{"version":3,"sources":["jsdelivr-header.js","/npm/@xeokit/xeokit-sdk@2.6.98/dist/xeokit-sdk.cjs.js"],"names":[],"mappings":"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EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAE,GAAK,GAAK,EACZ,EAAE,GAAK,GAAK,EAAE,GAAK,GACnB,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAE,GAAK,GAAK,EACZ,EAAE,GAAK,GAAK,EAAE,GAAK,GACnB,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAE,GAAK,GAAK,EACZ,EAAE,GAAK,GAAK,EAAE,GAAK,GACnB,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EAAG,EAAI,GAAM,GAC/B,EAAG,EAAI,GAAM,GAAK,EA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AO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,CACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,CACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,CACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,CACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,KAAO,CAClB,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,KACL,OAAO,IACX,CACA,SAAS,GAAG,GACR,EAAI,EAAI,EACR,IAAI,EAAI,EAAG,EAAI,EAAG,EAAI,EAAG,EAAI,EA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,CACA,SAAS,GAAG,EAAG,EAAG,GACd,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAE,EACN,CACA,SAAS,GAAG,EAAG,EAAG,EAAG,GACjB,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAE,EACN,CACA,SAAS,GAAG,EAAG,EAAG,EAAG,EAAG,GACpB,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAE,GACN,CACA,SAAS,GAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACvB,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAI,EAAI,EACR,EAAE,GACN,CAEA,IAAI,GAAI,CAAC,GAAI,GAAI,GAAI,IACrB,IAAI,GAAI,CAAC,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,IACrE,IAAI,GAAI,CAAC,GAAI,IACb,IAAI,GAAI,CACJ,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,IAEJ,IAAI,GAAK,CAAC,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,IACtC,IAAI,GAAK,CAAC,GAAI,GAAI,GAAI,IACtB,IAAI,GAAK,CACL,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,IAEJ,IAAI,GAAK,CAAC,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GA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","file":"/npm/@xeokit/xeokit-sdk@2.6.98/dist/xeokit-sdk.cjs.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@xeokit/xeokit-sdk@2.6.98/dist/xeokit-sdk.cjs.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n * xeokit-sdk v2.6.98\n *  Commit: 30ac0fa9a4eaf6759fe306bb2e332cce49884787\n *  Built: 2025-12-08T14:33:34.719Z\n */\n\nif (typeof window !== 'undefined') {\n    window.__XEOKIT__ = { version: '2.6.98', commit: '30ac0fa9a4eaf6759fe306bb2e332cce49884787', built: '2025-12-08T14:33:34.719Z' };\n}\n\n'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\n/** @private */\nclass Map$1 {\n\n    constructor(items, baseId) {\n        this.items = items || [];\n        this._lastUniqueId = (baseId || 0) + 1;\n    }\n\n    /**\n     * Usage:\n     *\n     * id = myMap.addItem(\"foo\") // ID internally generated\n     * id = myMap.addItem(\"foo\", \"bar\") // ID is \"foo\"\n     */\n    addItem() {\n        let item;\n        if (arguments.length === 2) {\n            const id = arguments[0];\n            item = arguments[1];\n            if (this.items[id]) { // Won't happen if given ID is string\n                throw \"ID clash: '\" + id + \"'\";\n            }\n            this.items[id] = item;\n            return id;\n\n        } else {\n            item = arguments[0] || {};\n            while (true) {\n                const findId = this._lastUniqueId++;\n                if (!this.items[findId]) {\n                    this.items[findId] = item;\n                    return findId;\n                }\n            }\n        }\n    }\n\n    removeItem(id) {\n        const item = this.items[id];\n        delete this.items[id];\n        return item;\n    }\n}\n\nconst idMap = new Map$1();\n\n/**\n * Internal data class that represents the state of a menu or a submenu.\n * @private\n */\nclass Menu {\n    constructor(id) {\n        this.id = id;\n        this.parentItem = null; // Set to an Item when this Menu is a submenu\n        this.groups = [];\n        this.menuElement = null;\n        this.shown = false;\n        this.mouseOver = 0;\n    }\n}\n\n/**\n * Internal data class that represents a group of Items in a Menu.\n * @private\n */\nclass Group {\n    constructor() {\n        this.items = [];\n    }\n}\n\n/**\n * Internal data class that represents the state of a menu item.\n * @private\n */\nclass Item {\n    constructor(id, getTitle, doAction, getEnabled, getShown) {\n        this.id = id;\n        this.getTitle = getTitle;\n        this.doAction = doAction;\n        this.getEnabled = getEnabled;\n        this.getShown = getShown;\n        this.itemElement = null;\n        this.subMenu = null;\n        this.enabled = true;\n    }\n}\n\n/**\n * @desc A customizable HTML context menu.\n *\n * [<img src=\"http://xeokit.io/img/docs/ContextMenu/ContextMenu.gif\">](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_Canvas_TreeViewPlugin_Custom)\n *\n * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_Canvas_TreeViewPlugin_Custom)]\n *\n * ## Overview\n *\n * * A pure JavaScript, lightweight context menu\n * * Dynamically configure menu items\n * * Dynamically enable or disable items\n * * Dynamically show or hide items\n * * Supports cascading sub-menus\n * * Configure custom style with CSS (see examples above)\n *\n * ## Usage\n *\n * In the example below we'll create a ````ContextMenu```` that pops up whenever we right-click on an {@link Entity} within\n * our {@link Scene}.\n *\n * First, we'll create the ````ContextMenu````, configuring it with a list of menu items.\n *\n * Each item has:\n *\n * * a ````title```` for the item,\n * * a ````doAction()```` callback to fire when the item's title is clicked,\n * * an optional ````getShown()```` callback that indicates if the item should shown in the menu or not, and\n * * an optional ````getEnabled()```` callback that indicates if the item should be shown enabled in the menu or not.\n *\n * <br>\n *\n * The ````getShown()```` and ````getEnabled()```` callbacks are invoked whenever the menu is shown.\n *\n * When an item's ````getShown()```` callback\n * returns ````true````, then the item is shown. When it returns ````false````, then the item is hidden. An item without\n * a ````getShown()```` callback is always shown.\n *\n * When an item's ````getEnabled()```` callback returns ````true````, then the item is enabled and clickable (as long as it's also shown). When it\n * returns ````false````, then the item is disabled and cannot be clicked. An item without a ````getEnabled()````\n * callback is always enabled and clickable.\n *\n * Note how the ````doAction()````,  ````getShown()```` and ````getEnabled()```` callbacks accept a ````context````\n * object. That must be set on the ````ContextMenu```` before we're able to we show it. The context object can be anything. In this example,\n * we'll use the context object to provide the callbacks with the Entity that we right-clicked.\n *\n * We'll also initially enable the ````ContextMenu````.\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_Canvas_Custom)]\n *\n * ````javascript\n * const canvasContextMenu = new ContextMenu({\n *\n *    enabled: true,\n *\n *    items: [\n *       [\n *          {\n *             title: \"Hide Object\",\n *             getEnabled: (context) => {\n *                 return context.entity.visible; // Can't hide entity if already hidden\n *             },\n *             doAction: function (context) {\n *                 context.entity.visible = false;\n *             }\n *          }\n *       ],\n *       [\n *          {\n *             title: \"Select Object\",\n *             getEnabled: (context) => {\n *                 return (!context.entity.selected); // Can't select an entity that's already selected\n *             },\n *             doAction: function (context) {\n *                 context.entity.selected = true;\n *             }\n *          }\n *       ],\n *       [\n *          {\n *             title: \"X-Ray Object\",\n *             getEnabled: (context) => {\n *                 return (!context.entity.xrayed); // Can't X-ray an entity that's already X-rayed\n *             },\n *             doAction: (context) => {\n *                 context.entity.xrayed = true;\n *             }\n *          }\n *       ]\n *    ]\n * });\n * ````\n *\n * Next, we'll make the ````ContextMenu```` appear whenever we right-click on an Entity. Whenever we right-click\n * on the canvas, we'll attempt to pick the Entity at those mouse coordinates. If we succeed, we'll feed the\n * Entity into ````ContextMenu```` via the context object, then show the ````ContextMenu````.\n *\n * From there, each ````ContextMenu```` item's ````getEnabled()```` callback will be invoked (if provided), to determine if the item should\n * be enabled. If we click an item, its ````doAction()```` callback will be invoked with our context object.\n *\n * Remember that we must set the context on our ````ContextMenu```` before we show it, otherwise it will log an error to the console,\n * and ignore our attempt to show it.\n *\n * ````javascript*\n * viewer.scene.canvas.canvas.oncontextmenu = (e) => { // Right-clicked on the canvas\n *\n *     if (!objectContextMenu.enabled) {\n *         return;\n *     }\n *\n *     var hit = viewer.scene.pick({ // Try to pick an Entity at the coordinates\n *         canvasPos: [e.pageX, e.pageY]\n *     });\n *\n *     if (hit) { // Picked an Entity\n *\n *         objectContextMenu.context = { // Feed entity to ContextMenu\n *             entity: hit.entity\n *         };\n *\n *         objectContextMenu.show(e.pageX, e.pageY); // Show the ContextMenu\n *     }\n *\n *     e.preventDefault();\n * });\n * ````\n *\n * Note how we only show the ````ContextMenu```` if it's enabled. We can use that mechanism to switch between multiple\n * ````ContextMenu```` instances depending on what we clicked.\n *\n * ## Dynamic Item Titles\n *\n * To make an item dynamically regenerate its title text whenever we show the ````ContextMenu````, provide its title with a\n * ````getTitle()```` callback. The callback will fire each time you show ````ContextMenu````, which will dynamically\n * set the item title text.\n *\n * In the example below, we'll create a simple ````ContextMenu```` that allows us to toggle the selection of an object\n * via its first item, which changes text depending on whether we are selecting or deselecting the object.\n *\n * [[Run an example](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_dynamicItemTitles)]\n *\n * ````javascript\n * const canvasContextMenu = new ContextMenu({\n *\n *    enabled: true,\n *\n *    items: [\n *       [\n *          {\n *              getTitle: (context) => {\n *                  return (!context.entity.selected) ? \"Select\" : \"Undo Select\";\n *              },\n *              doAction: function (context) {\n *                  context.entity.selected = !context.entity.selected;\n *              }\n *          },\n *          {\n *              title: \"Clear Selection\",\n *              getEnabled: function (context) {\n *                  return (context.viewer.scene.numSelectedObjects > 0);\n *              },\n *              doAction: function (context) {\n *                  context.viewer.scene.setObjectsSelected(context.viewer.scene.selectedObjectIds, false);\n *              }\n *          }\n *       ]\n *    ]\n * });\n * ````\n *\n * ## Sub-menus\n *\n * Each menu item can optionally have a sub-menu, which will appear when we hover over the item.\n *\n * In the example below, we'll create a much simpler ````ContextMenu```` that has only one item, called \"Effects\", which\n * will open a cascading sub-menu whenever we hover over that item.\n *\n * Note that our \"Effects\" item has no ````doAction```` callback, because an item with a sub-menu performs no\n * action of its own.\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_subMenus)]\n *\n * ````javascript\n * const canvasContextMenu = new ContextMenu({\n *     items: [ // Top level items\n *         [\n *             {\n *                 getTitle: (context) => {\n *                     return \"Effects\";\n *                 },\n *\n *                 items: [ // Sub-menu\n *                     [\n *                         {\n *                             getTitle: (context) => {\n *                                 return (!context.entity.visible) ? \"Show\" : \"Hide\";\n *                             },\n *                             doAction: function (context) {\n *                                 context.entity.visible = !context.entity.visible;\n *                             }\n *                         },\n *                         {\n *                             getTitle: (context) => {\n *                                 return (!context.entity.selected) ? \"Select\" : \"Undo Select\";\n *                             },\n *                             doAction: function (context) {\n *                                 context.entity.selected = !context.entity.selected;\n *                             }\n *                         },\n *                         {\n *                             getTitle: (context) => {\n *                                 return (!context.entity.highlighted) ? \"Highlight\" : \"Undo Highlight\";\n *                             },\n *                             doAction: function (context) {\n *                                 context.entity.highlighted = !context.entity.highlighted;\n *                             }\n *                         }\n *                     ]\n *                 ]\n *             }\n *          ]\n *      ]\n * });\n * ````\n */\nclass ContextMenu {\n\n    /**\n     * Creates a ````ContextMenu````.\n     *\n     * The ````ContextMenu```` will be initially hidden.\n     *\n     * @param {Object} [cfg] ````ContextMenu```` configuration.\n     * @param {Object} [cfg.items] The context menu items. These can also be dynamically set on {@link ContextMenu#items}. See the class documentation for an example.\n     * @param {Object} [cfg.context] The context, which is passed into the item callbacks. This can also be dynamically set on {@link ContextMenu#context}. This must be set before calling {@link ContextMenu#show}.\n     * @param {Boolean} [cfg.enabled=true] Whether this ````ContextMenu```` is initially enabled. {@link ContextMenu#show} does nothing while this is ````false````.\n     * @param {Boolean} [cfg.hideOnMouseDown=true] Whether this ````ContextMenu```` automatically hides whenever we mouse-down or tap anywhere in the page.\n     * @param {Boolean} [cfg.hideOnAction=true] Whether this ````ContextMenu```` automatically hides after we select a menu item. Se false if we want the menu to remain shown and show any updates to its item titles, after we've selected an item.\n     * @param {Node | undefined} [cfg.parentNode] Optional reference to an existing DOM Node (e.g. ShadowRoot), to which the menu's HTML element will be appended, defaults to ````document.body````.\n     */\n    constructor(cfg = {}) {\n\n        this._id = idMap.addItem();\n        this._context = null;\n        this._enabled = false;  // True when the ContextMenu is enabled\n        this._itemsCfg = [];    // Items as given as configs\n        this._rootMenu = null;  // The root Menu in the tree\n        this._menuList = [];    // List of Menus\n        this._menuMap = {};     // Menus mapped to their IDs\n        this._itemList = [];    // List of Items\n        this._itemMap = {};     // Items mapped to their IDs\n        this._shown = false;    // True when the ContextMenu is visible\n        this._nextId = 0;\n        this._parentNode = cfg.parentNode || document.body;\n        this._offsetParent = (this._parentNode instanceof ShadowRoot) ? this._parentNode.host : this._parentNode;\n        \n        /**\n         * Subscriptions to events fired at this ContextMenu.\n         * @private\n         */\n        this._eventSubs = {};\n\n        if (cfg.hideOnMouseDown !== false) {\n            this._parentNode.addEventListener(\"mousedown\", (event) => {\n                if (!event.target.classList.contains(\"xeokit-context-menu-item\")) {\n                    this.hide();\n                }\n            });\n            this._parentNode.addEventListener(\"touchstart\", this._canvasTouchStartHandler = (event) => {\n                if (!event.target.classList.contains(\"xeokit-context-menu-item\")) {\n                    this.hide();\n                }\n            });\n        }\n\n        if (cfg.items) {\n            this.items = cfg.items;\n        }\n\n        this._hideOnAction = (cfg.hideOnAction !== false);\n\n        this.context = cfg.context;\n        this.enabled = cfg.enabled !== false;\n        this.hide();\n    }\n\n\n    /**\n     Subscribes to an event fired at this ````ContextMenu````.\n\n     @param {String} event The event\n     @param {Function} callback Callback fired on the event\n     */\n    on(event, callback) {\n        let subs = this._eventSubs[event];\n        if (!subs) {\n            subs = [];\n            this._eventSubs[event] = subs;\n        }\n        subs.push(callback);\n    }\n\n    /**\n     Fires an event at this ````ContextMenu````.\n\n     @param {String} event The event type name\n     @param {Object} value The event parameters\n     */\n    fire(event, value) {\n        const subs = this._eventSubs[event];\n        if (subs) {\n            for (let i = 0, len = subs.length; i < len; i++) {\n                subs[i](value);\n            }\n        }\n    }\n\n    /**\n     * Sets the ````ContextMenu```` items.\n     *\n     * These can be updated dynamically at any time.\n     *\n     * See class documentation for an example.\n     *\n     * @type {Object[]}\n     */\n    set items(itemsCfg) {\n        this._clear();\n        this._itemsCfg = itemsCfg || [];\n        this._parseItems(itemsCfg);\n        this._createUI();\n    }\n\n    /**\n     * Gets the ````ContextMenu```` items.\n     *\n     * @type {Object[]}\n     */\n    get items() {\n        return this._itemsCfg;\n    }\n\n    /**\n     * Sets whether this ````ContextMenu```` is enabled.\n     *\n     * Hides the menu when disabling.\n     *\n     * @type {Boolean}\n     */\n    set enabled(enabled) {\n        enabled = (!!enabled);\n        if (enabled === this._enabled) {\n            return;\n        }\n        this._enabled = enabled;\n        if (!this._enabled) {\n            this.hide();\n        }\n    }\n\n    /**\n     * Gets whether this ````ContextMenu```` is enabled.\n     *\n     * {@link ContextMenu#show} does nothing while this is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get enabled() {\n        return this._enabled;\n    }\n\n    /**\n     * Sets the ````ContextMenu```` context.\n     *\n     * The context can be any object that you need to be provides to the callbacks configured on {@link ContextMenu#items}.\n     *\n     * This must be set before calling {@link ContextMenu#show}.\n     *\n     * @type {Object}\n     */\n    set context(context) {\n        this._context = context;\n    }\n\n    /**\n     * Gets the ````ContextMenu```` context.\n     *\n     * @type {Object}\n     */\n    get context() {\n        return this._context;\n    }\n\n    /**\n     * Shows this ````ContextMenu```` at the given page coordinates.\n     *\n     * Does nothing when {@link ContextMenu#enabled} is ````false````.\n     *\n     * Logs error to console and does nothing if {@link ContextMenu#context} has not been set.\n     *\n     * Fires a \"shown\" event when shown.\n     *\n     * @param {Number} pageX Page X-coordinate.\n     * @param {Number} pageY Page Y-coordinate.\n     */\n    show(pageX, pageY) {\n        if (!this._context) {\n            console.error(\"ContextMenu cannot be shown without a context - set context first\");\n            return;\n        }\n        if (!this._enabled) {\n            return;\n        }\n        if (this._shown) {\n            return;\n        }\n        this._hideAllMenus();\n        this._updateItemsTitles();\n        this._updateItemsEnabledStatus();\n        this._showMenu(this._rootMenu.id, pageX, pageY);\n        this._updateSubMenuInfo();\n        this._shown = true;\n        this.fire(\"shown\", {});\n    }\n\n    /**\n     * Gets whether this ````ContextMenu```` is currently shown or not.\n     *\n     * @returns {Boolean} Whether this ````ContextMenu```` is shown.\n     */\n    get shown() {\n        return this._shown;\n    }\n\n    /**\n     * Hides this ````ContextMenu````.\n     *\n     * Fires a \"hidden\" event when hidden.\n     */\n    hide() {\n        if (!this._enabled) {\n            return;\n        }\n        if (!this._shown) {\n            return;\n        }\n        this._hideAllMenus();\n        this._shown = false;\n        this.fire(\"hidden\", {});\n    }\n\n    /**\n     * Destroys this ````ContextMenu````.\n     */\n    destroy() {\n        this._context = null;\n        this._clear();\n        if (this._id !== null) {\n            idMap.removeItem(this._id);\n            this._id = null;\n        }\n    }\n\n    _clear() { // Destroys DOM elements, clears menu data\n        for (let i = 0, len = this._menuList.length; i < len; i++) {\n            const menu = this._menuList[i];\n            const menuElement = menu.menuElement;\n            menuElement.remove();\n        }\n        this._itemsCfg = [];\n        this._rootMenu = null;\n        this._menuList = [];\n        this._menuMap = {};\n        this._itemList = [];\n        this._itemMap = {};\n    }\n\n    _parseItems(itemsCfg) { // Parses \"items\" config into menu data\n\n        const visitItems = (itemsCfg) => {\n\n            const menuId = this._getNextId();\n            const menu = new Menu(menuId);\n\n            for (let i = 0, len = itemsCfg.length; i < len; i++) {\n\n                const itemsGroupCfg = itemsCfg[i];\n\n                const group = new Group();\n\n                menu.groups.push(group);\n\n                for (let j = 0, lenj = itemsGroupCfg.length; j < lenj; j++) {\n\n                    const itemCfg = itemsGroupCfg[j];\n                    const subItemsCfg = itemCfg.items;\n                    const hasSubItems = (subItemsCfg && (subItemsCfg.length > 0));\n                    const itemId = this._getNextId();\n\n                    const getTitle = itemCfg.getTitle || (() => {\n                        return (itemCfg.title || \"\");\n                    });\n\n                    const doAction = itemCfg.doAction || itemCfg.callback || (() => {\n                    });\n\n                    const getEnabled = itemCfg.getEnabled || (() => {\n                        return true;\n                    });\n\n                    const getShown = itemCfg.getShown || (() => {\n                        return true;\n                    });\n\n                    const item = new Item(itemId, getTitle, doAction, getEnabled, getShown);\n\n                    item.parentMenu = menu;\n\n                    group.items.push(item);\n\n                    if (hasSubItems) {\n                        const subMenu = visitItems(subItemsCfg);\n                        item.subMenu = subMenu;\n                        subMenu.parentItem = item;\n                    }\n\n                    this._itemList.push(item);\n                    this._itemMap[item.id] = item;\n                }\n            }\n\n            this._menuList.push(menu);\n            this._menuMap[menu.id] = menu;\n\n            return menu;\n        };\n\n        this._rootMenu = visitItems(itemsCfg);\n    }\n\n    _getNextId() { // Returns a unique ID\n        return \"ContextMenu_\" + this._id + \"_\" + this._nextId++; // Start ID with alpha chars to make a valid DOM element selector\n    }\n\n    _createUI() { // Builds DOM elements for the entire menu tree\n\n        const visitMenu = (menu) => {\n\n            this._createMenuUI(menu);\n\n            const groups = menu.groups;\n            for (let i = 0, len = groups.length; i < len; i++) {\n                const group = groups[i];\n                const groupItems = group.items;\n                for (let j = 0, lenj = groupItems.length; j < lenj; j++) {\n                    const item = groupItems[j];\n                    const subMenu = item.subMenu;\n                    if (subMenu) {\n                        visitMenu(subMenu);\n                    }\n                }\n            }\n        };\n\n        visitMenu(this._rootMenu);\n    }\n\n    _createMenuUI(menu) { // Builds DOM elements for a menu\n\n        const groups = menu.groups;\n        const html = [];\n\n        const menuElement= document.createElement(\"div\");\n        menuElement.classList.add(\"xeokit-context-menu\", menu.id);\n        menuElement.style.zIndex = 300000;\n        menuElement.style.position = \"absolute\";\n\n        html.push('<ul>');\n\n        if (groups) {\n\n            for (let i = 0, len = groups.length; i < len; i++) {\n\n                const group = groups[i];\n                const groupIdx = i;\n                const groupLen = len;\n                const groupItems = group.items;\n\n                if (groupItems) {\n\n                    for (let j = 0, lenj = groupItems.length; j < lenj; j++) {\n\n                        const item = groupItems[j];\n                        const itemSubMenu = item.subMenu;\n                        const actionTitle = item.title || \"\";\n\n                        if (itemSubMenu) {\n\n                            html.push(\n                                '<li id=\"' + item.id + '\" class=\"xeokit-context-menu-item xeokit-context-menu-submenu\">' +\n                                actionTitle +\n                                '</li>');\n                            if (!((groupIdx === groupLen - 1) || (j < lenj - 1))) {\n                                html.push(\n                                    '<li id=\"' + item.id + '\" class=\"xeokit-context-menu-item-separator\"></li>'\n                                );\n                            }\n\n                        } else {\n\n                            html.push(\n                                '<li id=\"' + item.id + '\" class=\"xeokit-context-menu-item\">' +\n                                actionTitle +\n                                '</li>');\n                            if (!((groupIdx === groupLen - 1) || (j < lenj - 1))) {\n                                html.push(\n                                    '<li id=\"' + item.id + '\" class=\"xeokit-context-menu-item-separator\"></li>'\n                                );\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        html.push('</ul>');\n\n        const htmlString = html.join(\"\");\n        menuElement.innerHTML = htmlString;\n        this._parentNode.appendChild(menuElement);\n\n        menu.menuElement = menuElement;\n\n        menuElement.style[\"border-radius\"] = 4 + \"px\";\n        menuElement.style.display = 'none';\n        menuElement.style[\"z-index\"] = 300000;\n        menuElement.style.background = \"white\";\n        menuElement.style.border = \"1px solid black\";\n        menuElement.style[\"box-shadow\"] = \"0 4px 5px 0 gray\";\n        menuElement.oncontextmenu = (e) => {\n            e.preventDefault();\n        };\n\n        // Bind event handlers\n\n        const self = this;\n\n        let lastSubMenu = null;\n\n        if (groups) {\n\n            for (let i = 0, len = groups.length; i < len; i++) {\n\n                const group = groups[i];\n                const groupItems = group.items;\n\n                if (groupItems) {\n\n                    for (let j = 0, lenj = groupItems.length; j < lenj; j++) {\n\n                        const item = groupItems[j];\n                        const itemSubMenu = item.subMenu;\n\n                        item.itemElement = this._parentNode.querySelector(`#${item.id}`);\n\n                        if (!item.itemElement) {\n                            console.error(\"ContextMenu item element not found: \" + item.id);\n                            continue;\n                        }\n\n                        item.itemElement.addEventListener(\"mouseenter\", (event) => {\n                            event.preventDefault();\n\n                            const subMenu = item.subMenu;\n                            if (!subMenu) {\n                                if (lastSubMenu) {\n                                    self._hideMenu(lastSubMenu.id);\n                                    lastSubMenu = null;\n                                }\n                                return;\n                            }\n                            if (lastSubMenu && (lastSubMenu.id !== subMenu.id)) {\n                                self._hideMenu(lastSubMenu.id);\n                                lastSubMenu = null;\n                            }\n\n                            if (item.enabled === false) {\n                                return;\n                            }\n\n                            const itemElement = item.itemElement;\n                            const subMenuElement = subMenu.menuElement;\n\n                            const itemRect = itemElement.getBoundingClientRect();\n                            subMenuElement.getBoundingClientRect();\n                            const offsetRect = self._offsetParent.getBoundingClientRect();\n\n                            const subMenuWidth = 200; // TODO\n                            const showOnRight = (itemRect.right + subMenuWidth) < offsetRect.right;\n                            const showOnLeft = (itemRect.left - subMenuWidth) > offsetRect.left;\n                        \n                            if(showOnRight)\n                                self._showMenu(subMenu.id, itemRect.right + window.scrollX - 5, itemRect.top + window.scrollY - 1);\n                            else if (showOnLeft)\n                                self._showMenu(subMenu.id, itemRect.left - subMenuWidth + window.scrollX, itemRect.top + window.scrollY - 1);\n                            else {\n                                const spaceOnLeft = itemRect.left - offsetRect.left, spaceOnRight = offsetRect.right - itemRect.right;\n                                if(spaceOnRight > spaceOnLeft) \n                                    self._showMenu(subMenu.id, itemRect.right - 5 - (subMenuWidth - spaceOnRight), itemRect.top + window.scrollY - 1);\n                                else \n                                    self._showMenu(subMenu.id, itemRect.left - spaceOnLeft, itemRect.top + window.scrollY - 1);\n                            }\n\n                            lastSubMenu = subMenu;\n                        });\n\n                        if (!itemSubMenu) {\n\n                            // Item without sub-menu\n                            // clicking item fires the item's action callback\n\n                            item.itemElement.addEventListener(\"click\", (event) => {\n                                event.preventDefault();\n                                if (!self._context) {\n                                    return;\n                                }\n                                if (item.enabled === false) {\n                                    return;\n                                }\n                                if (item.doAction) {\n                                    item.doAction(self._context);\n                                }\n                                if (this._hideOnAction) {\n                                    self.hide();\n                                } else {\n                                    self._updateItemsTitles();\n                                    self._updateItemsEnabledStatus();\n                                }\n                            });\n                            item.itemElement.addEventListener(\"mouseup\", (event) => {\n                                if (event.which !== 3) {\n                                    return;\n                                }\n                                event.preventDefault();\n                                if (!self._context) {\n                                    return;\n                                }\n                                if (item.enabled === false) {\n                                    return;\n                                }\n                                if (item.doAction) {\n                                    item.doAction(self._context);\n                                }\n                                if (this._hideOnAction) {\n                                    self.hide();\n                                } else {\n                                    self._updateItemsTitles();\n                                    self._updateItemsEnabledStatus();\n                                }\n                            });\n                            item.itemElement.addEventListener(\"mouseenter\", (event) => {\n                                event.preventDefault();\n                                if (item.enabled === false) {\n                                    return;\n                                }\n                                if (item.doHover) {\n                                    item.doHover(self._context);\n                                }\n                            });\n\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    _updateItemsTitles() { // Dynamically updates the title of each Item to the result of Item#getTitle()\n        if (!this._context) {\n            return;\n        }\n        for (let i = 0, len = this._itemList.length; i < len; i++) {\n            const item = this._itemList[i];\n            const itemElement = item.itemElement;\n            if (!itemElement) {\n                continue;\n            }\n            const getShown = item.getShown;\n            if (!getShown || !getShown(this._context)) {\n                continue;\n            }\n            const title = item.getTitle(this._context);\n            if (item.subMenu) {\n                itemElement.innerText = title;\n            } else {\n                itemElement.innerText = title;\n            }\n        }\n    }\n\n    _updateItemsEnabledStatus() { // Enables or disables each Item, depending on the result of Item#getEnabled()\n        if (!this._context) {\n            return;\n        }\n        for (let i = 0, len = this._itemList.length; i < len; i++) {\n            const item = this._itemList[i];\n            const itemElement = item.itemElement;\n            if (!itemElement) {\n                continue;\n            }\n            const getEnabled = item.getEnabled;\n            if (!getEnabled) {\n                continue;\n            }\n            const getShown = item.getShown;\n            if (!getShown) {\n                continue;\n            }\n            const shown = getShown(this._context);\n            item.shown = shown;\n            if (!shown) {\n                itemElement.style.display = \"none\";\n                continue;\n            } else {\n                itemElement.style.display = \"\";\n\n            }\n            const enabled = getEnabled(this._context);\n            item.enabled = enabled;\n            if (!enabled) {\n                itemElement.classList.add(\"disabled\");\n            } else {\n                itemElement.classList.remove(\"disabled\");\n            }\n        }\n    }\n\n    _updateSubMenuInfo() {\n        if (!this._context) return;\n        let itemElement, itemRect, subMenuElement, initialStyles, showOnLeft, subMenuWidth;\n        this._itemList.forEach((item) => {\n            if (item.subMenu) {\n                itemElement = item.itemElement;\n                itemRect = itemElement.getBoundingClientRect();\n                subMenuElement = item.subMenu.menuElement;\n                initialStyles = {\n                    visibility: subMenuElement.style.visibility,\n                    display: subMenuElement.style.display,\n                };\n                subMenuElement.style.display = \"block\";\n                subMenuElement.style.visibility = \"hidden\";\n                subMenuWidth = item.subMenu.menuElement.getBoundingClientRect().width;\n                subMenuElement.style.visibility = initialStyles.visibility;\n                subMenuElement.style.display = initialStyles.display;\n                showOnLeft = ((itemRect.right + subMenuWidth) > window.innerWidth);\n                itemElement.setAttribute(\"data-submenuposition\", showOnLeft ? \"left\" : \"right\");\n            }\n        });\n    }\n\n    _showMenu(menuId, pageX, pageY) { // Shows the given menu, at the specified page coordinates\n        const menu = this._menuMap[menuId];\n        if (!menu) {\n            console.error(\"Menu not found: \" + menuId);\n            return;\n        }\n        if (menu.shown) {\n            return;\n        }\n        const menuElement = menu.menuElement;\n        if (menuElement) {\n            this._showMenuElement(menuElement, pageX, pageY);\n            menu.shown = true;\n        }\n    }\n\n    _hideMenu(menuId) { // Hides the given menu\n        const menu = this._menuMap[menuId];\n        if (!menu) {\n            console.error(\"Menu not found: \" + menuId);\n            return;\n        }\n        if (!menu.shown) {\n            return;\n        }\n        const menuElement = menu.menuElement;\n        if (menuElement) {\n            this._hideMenuElement(menuElement);\n            menu.shown = false;\n        }\n    }\n\n    _hideAllMenus() {\n        for (let i = 0, len = this._menuList.length; i < len; i++) {\n            const menu = this._menuList[i];\n            this._hideMenu(menu.id);\n        }\n    }\n\n    _showMenuElement(menuElement, pageX, pageY) { // Shows the given menu element, at the specified page coordinates\n        menuElement.style.display = 'block';\n        const menuHeight = menuElement.offsetHeight;\n        const menuWidth = menuElement.offsetWidth;\n\n        const offsetRect = this._offsetParent.getBoundingClientRect();\n\n        // A regression occurred, that positions the menu horizontally above the client viewport\n        // at 6188de17ddca5c069b75a7673c1cda1aa1e74d07 when window.innerHeight has been replaced by offsetRect.bottom\n        // Reported originally at XCD-332\n        // Reproducible with examples/measurement/distance_createWithMouse_snapping.html\n        // Dirty hack introduced as XEOK-306, to be improved in the future to a more general solution\n        const bottomContainerBorder = ((this._offsetParent === window.document.body) && (offsetRect.bottom === 0)) ? window.innerHeight : (offsetRect.bottom + window.scrollY);\n        const rightContainerBorder = offsetRect.right + window.scrollX;\n        if ((pageY + menuHeight) > bottomContainerBorder) {\n            pageY = bottomContainerBorder- menuHeight;\n        }\n        if ((pageX + menuWidth) > rightContainerBorder) {\n            pageX = rightContainerBorder - menuWidth;\n        }\n\n\n        menuElement.style.left = pageX - offsetRect.left - window.scrollX + 'px';\n        menuElement.style.top = pageY - offsetRect.top - window.scrollY + 'px';\n    }\n\n    _hideMenuElement(menuElement) {\n        menuElement.style.display = 'none';\n    }\n}\n\n/**\n * A PointerLens shows a magnified view of a {@link Viewer}'s canvas, centered at the position of the\n * mouse or touch pointer.\n *\n * This component is used by {@link DistanceMeasurementsControl} and {@link AngleMeasurementsControl}\n * to help position the pointer when snap-to-vertex or snap-toedge is enabled.\n *\n * [[Run an example](https://xeokit.github.io/xeokit-sdk/examples/measurement/#distance_createWithMouse_snapping)]\n *\n * ````JavaScript\n *\n *  import {Viewer, XKTLoaderPlugin, AngleMeasurementsPlugin, AngleMeasurementsMouseControl, PointerLens} from \"../../dist/xeokit-sdk.es.js\";\n *\n *  const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      dtxEnabled: true\n *  });\n *\n *  viewer.camera.eye = [-3.93, 2.85, 27.01];\n *  viewer.camera.look = [4.40, 3.72, 8.89];\n *  viewer.camera.up = [-0.01, 0.99, 0.039];\n *\n *  const xktLoader = new XKTLoaderPlugin(viewer);\n *\n *  const sceneModel = xktLoader.load({\n *      id: \"myModel\",\n *      src: \"../../assets/models/xkt/v10/glTF-Embedded/Duplex_A_20110505.glTFEmbedded.xkt\",\n *      edges: true\n *  });\n *\n *  const angleMeasurements = new AngleMeasurementsPlugin(viewer);\n *\n *  const angleMeasurementsMouseControl  = new AngleMeasurementsMouseControl(angleMeasurements, {\n *      pointerLens : new PointerLens(viewer, {\n *          zoomFactor: 2\n *      })\n *  })\n *\n *  angleMeasurementsMouseControl.activate();\n * ````\n */\nclass PointerLens {\n\n    /**\n     * Constructs a new PointerLens.\n     * @param viewer The Viewer\n     * @param [cfg] PointerLens configuration.\n     * @param [cfg.active=true] Whether PointerLens is active. The PointerLens can only be shown when this is `true` (default).\n     */\n    constructor(viewer, cfg={}) {\n\n        this.viewer = viewer;\n        this.scene = this.viewer.scene;\n\n        this._lensCursorDiv = document.createElement('div');\n        this._lensParams = { canvasSize: 300, cursorBorder: 2, cursorSize: 10 };\n        this._lensCursorDiv.style.borderRadius = \"50%\";\n        this._lensCursorDiv.style.width  = this._lensParams.cursorSize + \"px\";\n        this._lensCursorDiv.style.height = this._lensParams.cursorSize + \"px\";\n        this._lensCursorDiv.style.zIndex = \"100000\";\n        this._lensCursorDiv.style.position = \"absolute\";\n        this._lensCursorDiv.style.pointerEvents = \"none\";\n\n        this._lensContainer = document.createElement('div');\n        this._lensContainerId = cfg.containerId || 'xeokit-lens';\n        this._lensContainer.setAttribute(\"id\", this._lensContainerId);\n\n        this._lensContainer.style.border = \"1px solid black\";\n        this._lensContainer.style.background = \"white\";\n    //    this._lensContainer.style.opacity = \"0\";\n        this._lensContainer.style.borderRadius = \"50%\";\n        this._lensContainer.style.width  = this._lensParams.canvasSize + \"px\";\n        this._lensContainer.style.height = this._lensParams.canvasSize + \"px\";\n        \n        this._lensContainer.style.zIndex = \"15000\";\n        this._lensContainer.style.position = \"absolute\";\n        this._lensContainer.style.pointerEvents = \"none\";\n        this._lensContainer.style.visibility = \"hidden\";\n\n        this._lensCanvas = document.createElement('canvas');\n        this._lensCanvas.id = `${this._lensContainerId}-canvas`;\n        // this._lensCanvas.style.background = \"darkblue\";\n        this._lensCanvas.style.borderRadius = \"50%\";\n\n        this._lensCanvas.style.width  = this._lensParams.canvasSize + \"px\";\n        this._lensCanvas.style.height = this._lensParams.canvasSize + \"px\";\n        this._lensCanvas.style.zIndex = \"15000\";\n        this._lensCanvas.style.pointerEvents = \"none\";\n\n        document.body.appendChild(this._lensContainer);\n        this._lensContainer.appendChild(this._lensCanvas);\n        this._lensContainer.appendChild(this._lensCursorDiv);\n\n        this._lensCanvasContext = this._lensCanvas.getContext('2d');\n        this._canvasElement = this.viewer.scene.canvas.canvas;\n\n        this._canvasPos = null;\n        this._snappedCanvasPos = null;\n        this._lensPosToggle = cfg.lensPosToggle || true;\n        this._lensPosToggleAmount = cfg.lensPosToggleAmount || 85;\n        this._lensPosMarginLeft = cfg.lensPosMarginLeft || 85;\n        this._lensPosMarginTop = cfg.lensPosMarginTop || 25;\n        this._lensContainer.style.marginTop = `${this._lensPosMarginTop}px`;\n        this._lensContainer.style.marginLeft = `${this._lensPosMarginLeft}px`;\n\n        this._zoomLevel = cfg.zoomLevel || 2;\n\n        this._active = (cfg.active !== false);\n        this._visible = false;\n        this.snapped = false;\n\n        this._onViewerRendering = this.viewer.scene.on(\"rendering\", () => {\n            if (this._active && this._visible) {\n                this.update();\n            }\n        });\n    }\n\n    /**\n     * Updates this PointerLens.\n     */\n    update() {\n        if (!this._active || !this._visible) {\n            return;\n        }\n        if (!this._canvasPos) {\n            return;\n        }\n        const lensRect = this._lensContainer.getBoundingClientRect();\n        const canvasRect = this._canvasElement.getBoundingClientRect();\n        const pointerOnLens =\n            this._canvasPos[0] < lensRect.right && this._canvasPos[0] > lensRect.left &&\n            this._canvasPos[1] < lensRect.bottom && this._canvasPos[1] > lensRect.top;\n            this._lensContainer.style.marginLeft = `${this._lensPosMarginLeft}px`;\n        if (pointerOnLens) {\n            if (this._lensPosToggle) {\n                this._lensContainer.style.marginTop = `${canvasRect.bottom - canvasRect.top - this._lensCanvas.height - this._lensPosToggleAmount}px`;\n            } else {\n                this._lensContainer.style.marginTop = `${this._lensPosMarginTop}px`;\n            }\n            this._lensPosToggle = !this._lensPosToggle;\n        }\n        this._lensCanvasContext.clearRect(0, 0, this._lensCanvas.width, this._lensCanvas.height);\n        const size = Math.max(this._lensCanvas.width, this._lensCanvas.height) / this._zoomLevel;\n        this._lensCanvasContext.drawImage(\n            this._canvasElement, // source canvas\n            this._canvasPos[0] - size / 2, // source x (zoom center)\n            this._canvasPos[1] - size / 2, // source y (zoom center)\n            size, // source width\n            size, // source height\n            0, // destination x\n            0, // destination y\n            this._lensCanvas.width, // destination width\n            this._lensCanvas.height // destination height\n        );\n\n        const middle = this._lensParams.canvasSize / 2 - this._lensParams.cursorSize / 2 - this._lensParams.cursorBorder;\n\n        const deltaX = this._snappedCanvasPos ? (this._snappedCanvasPos[0] - this._canvasPos[0]) : 0;\n        const deltaY = this._snappedCanvasPos ? (this._snappedCanvasPos[1] - this._canvasPos[1]) : 0;\n\n        this._lensCursorDiv.style.left = `${middle + deltaX * this._zoomLevel}px`;\n        this._lensCursorDiv.style.top  = `${middle + deltaY * this._zoomLevel}px`;\n    }\n\n\n    /**\n     * Sets the zoom factor for the lens.\n     *\n     * This is `2` by default.\n     *\n     * @param zoomFactor\n     */\n    set zoomFactor(zoomFactor) {\n        this._zoomFactor = zoomFactor;\n        this.update();\n    }\n\n    /**\n     * Gets the zoom factor for the lens.\n     *\n     * This is `2` by default.\n     *\n     * @returns Number\n     */\n    get zoomFactor() {\n        return this._zoomFactor;\n    }\n\n    /**\n     * Sets the canvas central position of the lens.\n     * @param canvasPos\n     */\n    set canvasPos(canvasPos) {\n        this._canvasPos = canvasPos;\n        this.update();\n    }\n\n    /**\n     * Gets the canvas central position of the lens.\n     * @returns {Number[]}\n     */\n    get canvasPos() {\n        return this._canvasPos;\n    }\n\n    /**\n     * Sets the canvas coordinates of the pointer.\n     * @param snappedCanvasPos\n     */\n    set snappedCanvasPos(snappedCanvasPos) {\n        this._snappedCanvasPos = snappedCanvasPos;\n        this.update();\n    }\n\n    /**\n     * Gets the canvas coordinates of the snapped pointer.\n     * @returns {Number[]}\n     */\n    get snappedCanvasPos() {\n        return this._snappedCanvasPos;\n    }\n\n    /**\n     * Sets if the cursor has snapped to anything.\n     * This is set by plugins.\n     * @param snapped\n     * @private\n     */\n    set snapped(snapped) {\n        this._snapped = snapped;\n        const [ bg, border ] = snapped ? [ \"greenyellow\", \"green\" ] : [ \"pink\", \"red\" ];\n        this._lensCursorDiv.style.background = bg;\n        this._lensCursorDiv.style.border = this._lensParams.cursorBorder + \"px solid \" + border;\n    }\n\n    /**\n     * Gets  if the cursor has snapped to anything.\n     * This is called by plugins.\n     * @returns {Boolean}\n     * @private\n     */\n    get snapped() {\n        return this._snapped;\n    }\n\n    _updateActiveVisible() {\n        this._lensContainer.style.visibility = (this._active && this._visible) ? \"visible\" : \"hidden\";\n        this.update();\n    }\n\n    /**\n     * Sets if this PointerLens is active.\n     * @param active\n     */\n    set active(active) {\n        this._active = active;\n        this._updateActiveVisible();\n    }\n\n    /**\n     * Gets if this PointerLens is active.\n     * @returns {Boolean}\n     */\n    get active() {\n        return this._active;\n    }\n\n    /**\n     * Sets if this PointerLens is visible.\n     * This is set by plugins.\n     * @param visible\n     * @private\n     */\n    set visible(visible) {\n        this._visible = visible;\n        this._updateActiveVisible();\n    }\n\n    /**\n     * Gets if this PointerLens is visible.\n     * This is called by plugins.\n     * @returns {Boolean}\n     * @private\n     */\n    get visible() {\n        return this._visible;\n    }\n\n    /**\n     * Destroys this PointerLens.\n     */\n    destroy() {\n        if (!this._destroyed) {\n            this.viewer.scene.off(this._onViewerRendering);\n            this._lensContainer.removeChild(this._lensCanvas);\n            document.body.removeChild(this._lensContainer);\n            this._destroyed = true;\n        }\n    }\n}\n\nfunction earcut(data, holeIndices, dim = 2) {\n\n    const hasHoles = holeIndices && holeIndices.length;\n    const outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n    let outerNode = linkedList(data, 0, outerLen, dim, true);\n    const triangles = [];\n\n    if (!outerNode || outerNode.next === outerNode.prev) return triangles;\n\n    let minX, minY, invSize;\n\n    if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n    // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n    if (data.length > 80 * dim) {\n        minX = Infinity;\n        minY = Infinity;\n        let maxX = -Infinity;\n        let maxY = -Infinity;\n\n        for (let i = dim; i < outerLen; i += dim) {\n            const x = data[i];\n            const y = data[i + 1];\n            if (x < minX) minX = x;\n            if (y < minY) minY = y;\n            if (x > maxX) maxX = x;\n            if (y > maxY) maxY = y;\n        }\n\n        // minX, minY and invSize are later used to transform coords into integers for z-order calculation\n        invSize = Math.max(maxX - minX, maxY - minY);\n        invSize = invSize !== 0 ? 32767 / invSize : 0;\n    }\n\n    earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);\n\n    return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList(data, start, end, dim, clockwise) {\n    let last;\n\n    if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n        for (let i = start; i < end; i += dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);\n    } else {\n        for (let i = end - dim; i >= start; i -= dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);\n    }\n\n    if (last && equals$1(last, last.next)) {\n        removeNode(last);\n        last = last.next;\n    }\n\n    return last;\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints(start, end) {\n    if (!start) return start;\n    if (!end) end = start;\n\n    let p = start,\n        again;\n    do {\n        again = false;\n\n        if (!p.steiner && (equals$1(p, p.next) || area(p.prev, p, p.next) === 0)) {\n            removeNode(p);\n            p = end = p.prev;\n            if (p === p.next) break;\n            again = true;\n\n        } else {\n            p = p.next;\n        }\n    } while (again || p !== end);\n\n    return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {\n    if (!ear) return;\n\n    // interlink polygon nodes in z-order\n    if (!pass && invSize) indexCurve(ear, minX, minY, invSize);\n\n    let stop = ear;\n\n    // iterate through ears, slicing them one by one\n    while (ear.prev !== ear.next) {\n        const prev = ear.prev;\n        const next = ear.next;\n\n        if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {\n            triangles.push(prev.i, ear.i, next.i); // cut off the triangle\n\n            removeNode(ear);\n\n            // skipping the next vertex leads to less sliver triangles\n            ear = next.next;\n            stop = next.next;\n\n            continue;\n        }\n\n        ear = next;\n\n        // if we looped through the whole remaining polygon and can't find any more ears\n        if (ear === stop) {\n            // try filtering points and slicing again\n            if (!pass) {\n                earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);\n\n            // if this didn't work, try curing all small self-intersections locally\n            } else if (pass === 1) {\n                ear = cureLocalIntersections(filterPoints(ear), triangles);\n                earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);\n\n            // as a last resort, try splitting the remaining polygon into two\n            } else if (pass === 2) {\n                splitEarcut(ear, triangles, dim, minX, minY, invSize);\n            }\n\n            break;\n        }\n    }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar(ear) {\n    const a = ear.prev,\n        b = ear,\n        c = ear.next;\n\n    if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n    // now make sure we don't have other points inside the potential ear\n    const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;\n\n    // triangle bbox\n    const x0 = Math.min(ax, bx, cx),\n        y0 = Math.min(ay, by, cy),\n        x1 = Math.max(ax, bx, cx),\n        y1 = Math.max(ay, by, cy);\n\n    let p = c.next;\n    while (p !== a) {\n        if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 &&\n            pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) &&\n            area(p.prev, p, p.next) >= 0) return false;\n        p = p.next;\n    }\n\n    return true;\n}\n\nfunction isEarHashed(ear, minX, minY, invSize) {\n    const a = ear.prev,\n        b = ear,\n        c = ear.next;\n\n    if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n    const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;\n\n    // triangle bbox\n    const x0 = Math.min(ax, bx, cx),\n        y0 = Math.min(ay, by, cy),\n        x1 = Math.max(ax, bx, cx),\n        y1 = Math.max(ay, by, cy);\n\n    // z-order range for the current triangle bbox;\n    const minZ = zOrder(x0, y0, minX, minY, invSize),\n        maxZ = zOrder(x1, y1, minX, minY, invSize);\n\n    let p = ear.prevZ,\n        n = ear.nextZ;\n\n    // look for points inside the triangle in both directions\n    while (p && p.z >= minZ && n && n.z <= maxZ) {\n        if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&\n            pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;\n        p = p.prevZ;\n\n        if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&\n            pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;\n        n = n.nextZ;\n    }\n\n    // look for remaining points in decreasing z-order\n    while (p && p.z >= minZ) {\n        if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&\n            pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;\n        p = p.prevZ;\n    }\n\n    // look for remaining points in increasing z-order\n    while (n && n.z <= maxZ) {\n        if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&\n            pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;\n        n = n.nextZ;\n    }\n\n    return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections(start, triangles) {\n    let p = start;\n    do {\n        const a = p.prev,\n            b = p.next.next;\n\n        if (!equals$1(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\n            triangles.push(a.i, p.i, b.i);\n\n            // remove two nodes involved\n            removeNode(p);\n            removeNode(p.next);\n\n            p = start = b;\n        }\n        p = p.next;\n    } while (p !== start);\n\n    return filterPoints(p);\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut(start, triangles, dim, minX, minY, invSize) {\n    // look for a valid diagonal that divides the polygon into two\n    let a = start;\n    do {\n        let b = a.next.next;\n        while (b !== a.prev) {\n            if (a.i !== b.i && isValidDiagonal(a, b)) {\n                // split the polygon in two by the diagonal\n                let c = splitPolygon(a, b);\n\n                // filter colinear points around the cuts\n                a = filterPoints(a, a.next);\n                c = filterPoints(c, c.next);\n\n                // run earcut on each half\n                earcutLinked(a, triangles, dim, minX, minY, invSize, 0);\n                earcutLinked(c, triangles, dim, minX, minY, invSize, 0);\n                return;\n            }\n            b = b.next;\n        }\n        a = a.next;\n    } while (a !== start);\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n    const queue = [];\n\n    for (let i = 0, len = holeIndices.length; i < len; i++) {\n        const start = holeIndices[i] * dim;\n        const end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n        const list = linkedList(data, start, end, dim, false);\n        if (list === list.next) list.steiner = true;\n        queue.push(getLeftmost(list));\n    }\n\n    queue.sort(compareXYSlope);\n\n    // process holes from left to right\n    for (let i = 0; i < queue.length; i++) {\n        outerNode = eliminateHole(queue[i], outerNode);\n    }\n\n    return outerNode;\n}\n\nfunction compareXYSlope(a, b) {\n    let result = a.x - b.x;\n    // when the left-most point of 2 holes meet at a vertex, sort the holes counterclockwise so that when we find\n    // the bridge to the outer shell is always the point that they meet at.\n    if (result === 0) {\n        result = a.y - b.y;\n        if (result === 0) {\n            const aSlope = (a.next.y - a.y) / (a.next.x - a.x);\n            const bSlope = (b.next.y - b.y) / (b.next.x - b.x);\n            result = aSlope - bSlope;\n        }\n    }\n    return result;\n}\n\n// find a bridge between vertices that connects hole with an outer ring and and link it\nfunction eliminateHole(hole, outerNode) {\n    const bridge = findHoleBridge(hole, outerNode);\n    if (!bridge) {\n        return outerNode;\n    }\n\n    const bridgeReverse = splitPolygon(bridge, hole);\n\n    // filter collinear points around the cuts\n    filterPoints(bridgeReverse, bridgeReverse.next);\n    return filterPoints(bridge, bridge.next);\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge(hole, outerNode) {\n    let p = outerNode;\n    const hx = hole.x;\n    const hy = hole.y;\n    let qx = -Infinity;\n    let m;\n\n    // find a segment intersected by a ray from the hole's leftmost point to the left;\n    // segment's endpoint with lesser x will be potential connection point\n    // unless they intersect at a vertex, then choose the vertex\n    if (equals$1(hole, p)) return p;\n    do {\n        if (equals$1(hole, p.next)) return p.next;\n        else if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {\n            const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n            if (x <= hx && x > qx) {\n                qx = x;\n                m = p.x < p.next.x ? p : p.next;\n                if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint\n            }\n        }\n        p = p.next;\n    } while (p !== outerNode);\n\n    if (!m) return null;\n\n    // look for points inside the triangle of hole point, segment intersection and endpoint;\n    // if there are no points found, we have a valid connection;\n    // otherwise choose the point of the minimum angle with the ray as connection point\n\n    const stop = m;\n    const mx = m.x;\n    const my = m.y;\n    let tanMin = Infinity;\n\n    p = m;\n\n    do {\n        if (hx >= p.x && p.x >= mx && hx !== p.x &&\n                pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\n            const tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n            if (locallyInside(p, hole) &&\n                (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {\n                m = p;\n                tanMin = tan;\n            }\n        }\n\n        p = p.next;\n    } while (p !== stop);\n\n    return m;\n}\n\n// whether sector in vertex m contains sector in vertex p in the same coordinates\nfunction sectorContainsSector(m, p) {\n    return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve(start, minX, minY, invSize) {\n    let p = start;\n    do {\n        if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize);\n        p.prevZ = p.prev;\n        p.nextZ = p.next;\n        p = p.next;\n    } while (p !== start);\n\n    p.prevZ.nextZ = null;\n    p.prevZ = null;\n\n    sortLinked(p);\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked(list) {\n    let numMerges;\n    let inSize = 1;\n\n    do {\n        let p = list;\n        let e;\n        list = null;\n        let tail = null;\n        numMerges = 0;\n\n        while (p) {\n            numMerges++;\n            let q = p;\n            let pSize = 0;\n            for (let i = 0; i < inSize; i++) {\n                pSize++;\n                q = q.nextZ;\n                if (!q) break;\n            }\n            let qSize = inSize;\n\n            while (pSize > 0 || (qSize > 0 && q)) {\n\n                if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {\n                    e = p;\n                    p = p.nextZ;\n                    pSize--;\n                } else {\n                    e = q;\n                    q = q.nextZ;\n                    qSize--;\n                }\n\n                if (tail) tail.nextZ = e;\n                else list = e;\n\n                e.prevZ = tail;\n                tail = e;\n            }\n\n            p = q;\n        }\n\n        tail.nextZ = null;\n        inSize *= 2;\n\n    } while (numMerges > 1);\n\n    return list;\n}\n\n// z-order of a point given coords and inverse of the longer side of data bbox\nfunction zOrder(x, y, minX, minY, invSize) {\n    // coords are transformed into non-negative 15-bit integer range\n    x = (x - minX) * invSize | 0;\n    y = (y - minY) * invSize | 0;\n\n    x = (x | (x << 8)) & 0x00FF00FF;\n    x = (x | (x << 4)) & 0x0F0F0F0F;\n    x = (x | (x << 2)) & 0x33333333;\n    x = (x | (x << 1)) & 0x55555555;\n\n    y = (y | (y << 8)) & 0x00FF00FF;\n    y = (y | (y << 4)) & 0x0F0F0F0F;\n    y = (y | (y << 2)) & 0x33333333;\n    y = (y | (y << 1)) & 0x55555555;\n\n    return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost(start) {\n    let p = start,\n        leftmost = start;\n    do {\n        if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;\n        p = p.next;\n    } while (p !== start);\n\n    return leftmost;\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n    return (cx - px) * (ay - py) >= (ax - px) * (cy - py) &&\n           (ax - px) * (by - py) >= (bx - px) * (ay - py) &&\n           (bx - px) * (cy - py) >= (cx - px) * (by - py);\n}\n\n// check if a point lies within a convex triangle but false if its equal to the first point of the triangle\nfunction pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, px, py) {\n    return !(ax === px && ay === py) && pointInTriangle(ax, ay, bx, by, cx, cy, px, py);\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal(a, b) {\n    return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges\n           (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible\n            (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors\n            equals$1(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case\n}\n\n// signed area of a triangle\nfunction area(p, q, r) {\n    return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\nfunction equals$1(p1, p2) {\n    return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect\nfunction intersects(p1, q1, p2, q2) {\n    const o1 = sign(area(p1, q1, p2));\n    const o2 = sign(area(p1, q1, q2));\n    const o3 = sign(area(p2, q2, p1));\n    const o4 = sign(area(p2, q2, q1));\n\n    if (o1 !== o2 && o3 !== o4) return true; // general case\n\n    if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1\n    if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1\n    if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2\n    if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2\n\n    return false;\n}\n\n// for collinear points p, q, r, check if point q lies on segment pr\nfunction onSegment(p, q, r) {\n    return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);\n}\n\nfunction sign(num) {\n    return num > 0 ? 1 : num < 0 ? -1 : 0;\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon(a, b) {\n    let p = a;\n    do {\n        if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n                intersects(p, p.next, a, b)) return true;\n        p = p.next;\n    } while (p !== a);\n\n    return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside(a, b) {\n    return area(a.prev, a, a.next) < 0 ?\n        area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n        area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside(a, b) {\n    let p = a;\n    let inside = false;\n    const px = (a.x + b.x) / 2;\n    const py = (a.y + b.y) / 2;\n    do {\n        if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&\n                (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n            inside = !inside;\n        p = p.next;\n    } while (p !== a);\n\n    return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon(a, b) {\n    const a2 = createNode(a.i, a.x, a.y),\n        b2 = createNode(b.i, b.x, b.y),\n        an = a.next,\n        bp = b.prev;\n\n    a.next = b;\n    b.prev = a;\n\n    a2.next = an;\n    an.prev = a2;\n\n    b2.next = a2;\n    a2.prev = b2;\n\n    bp.next = b2;\n    b2.prev = bp;\n\n    return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode(i, x, y, last) {\n    const p = createNode(i, x, y);\n\n    if (!last) {\n        p.prev = p;\n        p.next = p;\n\n    } else {\n        p.next = last.next;\n        p.prev = last;\n        last.next.prev = p;\n        last.next = p;\n    }\n    return p;\n}\n\nfunction removeNode(p) {\n    p.next.prev = p.prev;\n    p.prev.next = p.next;\n\n    if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n    if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n}\n\nfunction createNode(i, x, y) {\n    return {\n        i, // vertex index in coordinates array\n        x, y, // vertex coordinates\n        prev: null, // previous and next vertex nodes in a polygon ring\n        next: null,\n        z: 0, // z-order curve value\n        prevZ: null, // previous and next nodes in z-order\n        nextZ: null,\n        steiner: false // indicates whether this is a steiner point\n    };\n}\n\nfunction signedArea(data, start, end, dim) {\n    let sum = 0;\n    for (let i = start, j = end - dim; i < end; i += dim) {\n        sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n        j = i;\n    }\n    return sum;\n}\n\n// Some temporary vars to help avoid garbage collection\n\nlet doublePrecision = true;\nlet FloatArrayType = doublePrecision ? Float64Array : Float32Array;\n\nconst tempVec3a$j = new FloatArrayType(3);\n\nconst tempMat1 = new FloatArrayType(16);\nconst tempMat2 = new FloatArrayType(16);\nconst tempVec4$4 = new FloatArrayType(4);\n\n\n/**\n * @private\n */\nconst math = {\n\n    setDoublePrecisionEnabled(enable) {\n        doublePrecision = enable;\n        FloatArrayType = doublePrecision ? Float64Array : Float32Array;\n    },\n\n    getDoublePrecisionEnabled() {\n        return doublePrecision;\n    },\n\n    MIN_DOUBLE: -Number.MAX_SAFE_INTEGER,\n    MAX_DOUBLE: Number.MAX_SAFE_INTEGER,\n\n    MAX_INT: 10000000,\n\n    /**\n     * The number of radiians in a degree (0.0174532925).\n     * @property DEGTORAD\n     * @type {Number}\n     */\n    DEGTORAD: 0.0174532925,\n\n    /**\n     * The number of degrees in a radian.\n     * @property RADTODEG\n     * @type {Number}\n     */\n    RADTODEG: 57.295779513,\n\n    unglobalizeObjectId(modelId, globalId) {\n        const idx = globalId.indexOf(\"#\");\n        return (idx === modelId.length && globalId.startsWith(modelId)) ? globalId.substring(idx + 1) : globalId;\n    },\n\n    globalizeObjectId(modelId, objectId) {\n        return (modelId + \"#\" + objectId)\n    },\n\n    /**\n     * Returns:\n     * - x != 0 => 1/x,\n     * - x == 1 => 1\n     *\n     * @param {number} x\n     */\n    safeInv(x) {\n        const retVal = 1 / x;\n        if (isNaN(retVal) || !isFinite(retVal)) {\n            return 1;\n        }\n        return retVal;\n    },\n\n    /**\n     * Returns a new, uninitialized two-element vector.\n     * @method vec2\n     * @param [values] Initial values.\n     * @static\n     * @returns {Number[]}\n     */\n    vec2(values) {\n        return new FloatArrayType(values || 2);\n    },\n\n    /**\n     * Returns a new, uninitialized three-element vector.\n     * @method vec3\n     * @param [values] Initial values.\n     * @static\n     * @returns {Number[]}\n     */\n    vec3(values) {\n        return new FloatArrayType(values || 3);\n    },\n\n    /**\n     * Returns a new, uninitialized four-element vector.\n     * @method vec4\n     * @param [values] Initial values.\n     * @static\n     * @returns {Number[]}\n     */\n    vec4(values) {\n        return new FloatArrayType(values || 4);\n    },\n\n    /**\n     * Returns a new, uninitialized 3x3 matrix.\n     * @method mat3\n     * @param [values] Initial values.\n     * @static\n     * @returns {Number[]}\n     */\n    mat3(values) {\n        return new FloatArrayType(values || 9);\n    },\n\n    /**\n     * Converts a 3x3 matrix to 4x4\n     * @method mat3ToMat4\n     * @param mat3 3x3 matrix.\n     * @param mat4 4x4 matrix\n     * @static\n     * @returns {Number[]}\n     */\n    mat3ToMat4(mat3, mat4 = new FloatArrayType(16)) {\n        mat4[0] = mat3[0];\n        mat4[1] = mat3[1];\n        mat4[2] = mat3[2];\n        mat4[3] = 0;\n        mat4[4] = mat3[3];\n        mat4[5] = mat3[4];\n        mat4[6] = mat3[5];\n        mat4[7] = 0;\n        mat4[8] = mat3[6];\n        mat4[9] = mat3[7];\n        mat4[10] = mat3[8];\n        mat4[11] = 0;\n        mat4[12] = 0;\n        mat4[13] = 0;\n        mat4[14] = 0;\n        mat4[15] = 1;\n        return mat4;\n    },\n\n    /**\n     * Returns a new, uninitialized 4x4 matrix.\n     * @method mat4\n     * @param [values] Initial values.\n     * @static\n     * @returns {Number[]}\n     */\n    mat4(values) {\n        return new FloatArrayType(values || 16);\n    },\n\n    /**\n     * Converts a 4x4 matrix to 3x3\n     * @method mat4ToMat3\n     * @param mat4 4x4 matrix.\n     * @param mat3 3x3 matrix\n     * @static\n     * @returns {Number[]}\n     */\n    mat4ToMat3(mat4, mat3 = new FloatArrayType(9)) {\n        mat3[0] = mat4[0];\n        mat3[1] = mat4[1];\n        mat3[2] = mat4[2];\n        \n        mat3[3] = mat4[4];\n        mat3[4] = mat4[5];\n        mat3[5] = mat4[6];\n        \n        mat3[6] = mat4[8];\n        mat3[7] = mat4[9];\n        mat3[8] = mat4[10];\n        \n        return mat3;\n    },\n\n    /**\n     * Converts a list of double-precision values to a list of high-part floats and a list of low-part floats.\n     * @param doubleVals\n     * @param floatValsHigh\n     * @param floatValsLow\n     */\n    doublesToFloats(doubleVals, floatValsHigh, floatValsLow) {\n        const floatPair = new FloatArrayType(2);\n        for (let i = 0, len = doubleVals.length; i < len; i++) {\n            math.splitDouble(doubleVals[i], floatPair);\n            floatValsHigh[i] = floatPair[0];\n            floatValsLow[i] = floatPair[1];\n        }\n    },\n\n    /**\n     * Splits a double value into two floats.\n     * @param value\n     * @param floatPair\n     */\n    splitDouble(value, floatPair) {\n        const hi = FloatArrayType.from([value])[0];\n        const low = value - hi;\n        floatPair[0] = hi;\n        floatPair[1] = low;\n    },\n\n    /**\n     * Returns a new UUID.\n     * @method createUUID\n     * @static\n     * @return string The new UUID\n     */\n    createUUID: ((() => {\n        const lut = [];\n        for (let i = 0; i < 256; i++) {\n            lut[i] = (i < 16 ? '0' : '') + (i).toString(16);\n        }\n        return () => {\n            const d0 = Math.random() * 0xffffffff | 0;\n            const d1 = Math.random() * 0xffffffff | 0;\n            const d2 = Math.random() * 0xffffffff | 0;\n            const d3 = Math.random() * 0xffffffff | 0;\n            return `${lut[d0 & 0xff] + lut[d0 >> 8 & 0xff] + lut[d0 >> 16 & 0xff] + lut[d0 >> 24 & 0xff]}-${lut[d1 & 0xff]}${lut[d1 >> 8 & 0xff]}-${lut[d1 >> 16 & 0x0f | 0x40]}${lut[d1 >> 24 & 0xff]}-${lut[d2 & 0x3f | 0x80]}${lut[d2 >> 8 & 0xff]}-${lut[d2 >> 16 & 0xff]}${lut[d2 >> 24 & 0xff]}${lut[d3 & 0xff]}${lut[d3 >> 8 & 0xff]}${lut[d3 >> 16 & 0xff]}${lut[d3 >> 24 & 0xff]}`;\n        };\n    }))(),\n\n    /**\n     * Clamps a value to the given range.\n     * @param {Number} value Value to clamp.\n     * @param {Number} min Lower bound.\n     * @param {Number} max Upper bound.\n     * @returns {Number} Clamped result.\n     */\n    clamp(value, min, max) {\n        return Math.max(min, Math.min(max, value));\n    },\n\n    /**\n     * Floating-point modulus\n     * @method fmod\n     * @static\n     * @param {Number} a\n     * @param {Number} b\n     * @returns {*}\n     */\n    fmod(a, b) {\n        if (a < b) {\n            console.error(\"math.fmod : Attempting to find modulus within negative range - would be infinite loop - ignoring\");\n            return a;\n        }\n        while (b <= a) {\n            a -= b;\n        }\n        return a;\n    },\n\n    /**\n     * Returns true if the two 3-element vectors are the same.\n     * @param v1\n     * @param v2\n     * @returns {Boolean}\n     */\n    compareVec3(v1, v2) {\n        return (v1[0] === v2[0] && v1[1] === v2[1] && v1[2] === v2[2]);\n    },\n\n    /**\n     * Returns true if the two 4-element vectors are the same.\n     * @param v1\n     * @param v2\n     * @returns {Boolean}\n     */\n    compareVec4(v1, v2) {\n        return (v1[0] === v2[0] && v1[1] === v2[1] && v1[2] === v2[2] && v1[3] === v2[3]);\n    },\n\n    /**\n     * Negates a three-element vector.\n     * @method negateVec3\n     * @static\n     * @param {Array(Number)} v Vector to negate\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, v otherwise\n     */\n    negateVec3(v, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = -v[0];\n        dest[1] = -v[1];\n        dest[2] = -v[2];\n        return dest;\n    },\n\n    /**\n     * Negates a four-element vector.\n     * @method negateVec4\n     * @static\n     * @param {Array(Number)} v Vector to negate\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, v otherwise\n     */\n    negateVec4(v, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = -v[0];\n        dest[1] = -v[1];\n        dest[2] = -v[2];\n        dest[3] = -v[3];\n        return dest;\n    },\n\n    /**\n     * Adds one four-element vector to another.\n     * @method addVec4\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Second vector\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, u otherwise\n     */\n    addVec4(u, v, dest) {\n        if (!dest) {\n            dest = u;\n        }\n        dest[0] = u[0] + v[0];\n        dest[1] = u[1] + v[1];\n        dest[2] = u[2] + v[2];\n        dest[3] = u[3] + v[3];\n        return dest;\n    },\n\n    /**\n     * Adds a scalar value to each element of a four-element vector.\n     * @method addVec4Scalar\n     * @static\n     * @param {Array(Number)} v The vector\n     * @param {Number} s The scalar\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, v otherwise\n     */\n    addVec4Scalar(v, s, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = v[0] + s;\n        dest[1] = v[1] + s;\n        dest[2] = v[2] + s;\n        dest[3] = v[3] + s;\n        return dest;\n    },\n\n    /**\n     * Adds one three-element vector to another.\n     * @method addVec3\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Second vector\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, u otherwise\n     */\n    addVec3(u, v, dest) {\n        if (!dest) {\n            dest = u;\n        }\n        dest[0] = u[0] + v[0];\n        dest[1] = u[1] + v[1];\n        dest[2] = u[2] + v[2];\n        return dest;\n    },\n\n    /**\n     * Adds a scalar value to each element of a three-element vector.\n     * @method addVec4Scalar\n     * @static\n     * @param {Array(Number)} v The vector\n     * @param {Number} s The scalar\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, v otherwise\n     */\n    addVec3Scalar(v, s, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = v[0] + s;\n        dest[1] = v[1] + s;\n        dest[2] = v[2] + s;\n        return dest;\n    },\n\n    /**\n     * Subtracts one four-element vector from another.\n     * @method subVec4\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Vector to subtract\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, u otherwise\n     */\n    subVec4(u, v, dest) {\n        if (!dest) {\n            dest = u;\n        }\n        dest[0] = u[0] - v[0];\n        dest[1] = u[1] - v[1];\n        dest[2] = u[2] - v[2];\n        dest[3] = u[3] - v[3];\n        return dest;\n    },\n\n    /**\n     * Subtracts one three-element vector from another.\n     * @method subVec3\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Vector to subtract\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, u otherwise\n     */\n    subVec3(u, v, dest) {\n        if (!dest) {\n            dest = u;\n        }\n        dest[0] = u[0] - v[0];\n        dest[1] = u[1] - v[1];\n        dest[2] = u[2] - v[2];\n        return dest;\n    },\n\n    /**\n     * Subtracts one two-element vector from another.\n     * @method subVec2\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Vector to subtract\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, u otherwise\n     */\n    subVec2(u, v, dest) {\n        if (!dest) {\n            dest = u;\n        }\n        dest[0] = u[0] - v[0];\n        dest[1] = u[1] - v[1];\n        return dest;\n    },\n\n    /**\n     * Get the geometric mean of the vectors.\n     * @method geometricMeanVec2\n     * @static\n     * @param {...Array(Number)} vectors Vec2 to mean\n     * @return {Array(Number)} The geometric mean vec2\n     */\n    geometricMeanVec2(...vectors) {\n        const geometricMean = new FloatArrayType(vectors[0]);\n        for (let i = 1; i < vectors.length; i++) {\n            geometricMean[0] += vectors[i][0];\n            geometricMean[1] += vectors[i][1];\n        }\n        geometricMean[0] /= vectors.length;\n        geometricMean[1] /= vectors.length;\n        return geometricMean;\n    },\n\n    /**\n     * Subtracts a scalar value from each element of a four-element vector.\n     * @method subVec4Scalar\n     * @static\n     * @param {Array(Number)} v The vector\n     * @param {Number} s The scalar\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, v otherwise\n     */\n    subVec4Scalar(v, s, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = v[0] - s;\n        dest[1] = v[1] - s;\n        dest[2] = v[2] - s;\n        dest[3] = v[3] - s;\n        return dest;\n    },\n\n    /**\n     * Sets each element of a 4-element vector to a scalar value minus the value of that element.\n     * @method subScalarVec4\n     * @static\n     * @param {Array(Number)} v The vector\n     * @param {Number} s The scalar\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, v otherwise\n     */\n    subScalarVec4(v, s, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = s - v[0];\n        dest[1] = s - v[1];\n        dest[2] = s - v[2];\n        dest[3] = s - v[3];\n        return dest;\n    },\n\n    /**\n     * Multiplies one three-element vector by another.\n     * @method mulVec3\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Second vector\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, u otherwise\n     */\n    mulVec4(u, v, dest) {\n        if (!dest) {\n            dest = u;\n        }\n        dest[0] = u[0] * v[0];\n        dest[1] = u[1] * v[1];\n        dest[2] = u[2] * v[2];\n        dest[3] = u[3] * v[3];\n        return dest;\n    },\n\n    /**\n     * Multiplies each element of a four-element vector by a scalar.\n     * @method mulVec34calar\n     * @static\n     * @param {Array(Number)} v The vector\n     * @param {Number} s The scalar\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, v otherwise\n     */\n    mulVec4Scalar(v, s, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = v[0] * s;\n        dest[1] = v[1] * s;\n        dest[2] = v[2] * s;\n        dest[3] = v[3] * s;\n        return dest;\n    },\n\n    /**\n     * Multiplies each element of a three-element vector by a scalar.\n     * @method mulVec3Scalar\n     * @static\n     * @param {Array(Number)} v The vector\n     * @param {Number} s The scalar\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, v otherwise\n     */\n    mulVec3Scalar(v, s, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = v[0] * s;\n        dest[1] = v[1] * s;\n        dest[2] = v[2] * s;\n        return dest;\n    },\n\n    /**\n     * Multiplies each element of a two-element vector by a scalar.\n     * @method mulVec2Scalar\n     * @static\n     * @param {Array(Number)} v The vector\n     * @param {Number} s The scalar\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, v otherwise\n     */\n    mulVec2Scalar(v, s, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = v[0] * s;\n        dest[1] = v[1] * s;\n        return dest;\n    },\n\n    /**\n     * Divides one three-element vector by another.\n     * @method divVec3\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Second vector\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, u otherwise\n     */\n    divVec3(u, v, dest) {\n        if (!dest) {\n            dest = u;\n        }\n        dest[0] = u[0] / v[0];\n        dest[1] = u[1] / v[1];\n        dest[2] = u[2] / v[2];\n        return dest;\n    },\n\n    /**\n     * Divides one four-element vector by another.\n     * @method divVec4\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Second vector\n     * @param  {Array(Number)} [dest] Destination vector\n     * @return {Array(Number)} dest if specified, u otherwise\n     */\n    divVec4(u, v, dest) {\n        if (!dest) {\n            dest = u;\n        }\n        dest[0] = u[0] / v[0];\n        dest[1] = u[1] / v[1];\n        dest[2] = u[2] / v[2];\n        dest[3] = u[3] / v[3];\n        return dest;\n    },\n\n    /**\n     * Divides a scalar by a three-element vector, returning a new vector.\n     * @method divScalarVec3\n     * @static\n     * @param v vec3\n     * @param s scalar\n     * @param dest vec3 - optional destination\n     * @return [] dest if specified, v otherwise\n     */\n    divScalarVec3(s, v, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = s / v[0];\n        dest[1] = s / v[1];\n        dest[2] = s / v[2];\n        return dest;\n    },\n\n    /**\n     * Divides a three-element vector by a scalar.\n     * @method divVec3Scalar\n     * @static\n     * @param v vec3\n     * @param s scalar\n     * @param dest vec3 - optional destination\n     * @return [] dest if specified, v otherwise\n     */\n    divVec3Scalar(v, s, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = v[0] / s;\n        dest[1] = v[1] / s;\n        dest[2] = v[2] / s;\n        return dest;\n    },\n\n    /**\n     * Divides a four-element vector by a scalar.\n     * @method divVec4Scalar\n     * @static\n     * @param v vec4\n     * @param s scalar\n     * @param dest vec4 - optional destination\n     * @return [] dest if specified, v otherwise\n     */\n    divVec4Scalar(v, s, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = v[0] / s;\n        dest[1] = v[1] / s;\n        dest[2] = v[2] / s;\n        dest[3] = v[3] / s;\n        return dest;\n    },\n\n\n    /**\n     * Divides a scalar by a four-element vector, returning a new vector.\n     * @method divScalarVec4\n     * @static\n     * @param s scalar\n     * @param v vec4\n     * @param dest vec4 - optional destination\n     * @return [] dest if specified, v otherwise\n     */\n    divScalarVec4(s, v, dest) {\n        if (!dest) {\n            dest = v;\n        }\n        dest[0] = s / v[0];\n        dest[1] = s / v[1];\n        dest[2] = s / v[2];\n        dest[3] = s / v[3];\n        return dest;\n    },\n\n    /**\n     * Returns the dot product of two four-element vectors.\n     * @method dotVec4\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Second vector\n     * @return The dot product\n     */\n    dotVec4(u, v) {\n        return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2] + u[3] * v[3]);\n    },\n\n    /**\n     * Returns the cross product of two four-element vectors.\n     * @method cross3Vec4\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Second vector\n     * @return The cross product\n     */\n    cross3Vec4(u, v) {\n        const u0 = u[0];\n        const u1 = u[1];\n        const u2 = u[2];\n        const v0 = v[0];\n        const v1 = v[1];\n        const v2 = v[2];\n        return [\n            u1 * v2 - u2 * v1,\n            u2 * v0 - u0 * v2,\n            u0 * v1 - u1 * v0,\n            0.0];\n    },\n\n    /**\n     * Returns the cross product of two three-element vectors.\n     * @method cross3Vec3\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Second vector\n     * @return The cross product\n     */\n    cross3Vec3(u, v, dest) {\n        if (!dest) {\n            dest = u;\n        }\n        const x = u[0];\n        const y = u[1];\n        const z = u[2];\n        const x2 = v[0];\n        const y2 = v[1];\n        const z2 = v[2];\n        dest[0] = y * z2 - z * y2;\n        dest[1] = z * x2 - x * z2;\n        dest[2] = x * y2 - y * x2;\n        return dest;\n    },\n\n\n    sqLenVec4(v) { // TODO\n        return math.dotVec4(v, v);\n    },\n\n    /**\n     * Returns the length of a four-element vector.\n     * @method lenVec4\n     * @static\n     * @param {Array(Number)} v The vector\n     * @return The length\n     */\n    lenVec4(v) {\n        return Math.sqrt(math.sqLenVec4(v));\n    },\n\n    /**\n     * Returns the dot product of two three-element vectors.\n     * @method dotVec3\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Second vector\n     * @return The dot product\n     */\n    dotVec3(u, v) {\n        return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]);\n    },\n\n    /**\n     * Returns the dot product of two two-element vectors.\n     * @method dotVec4\n     * @static\n     * @param {Array(Number)} u First vector\n     * @param {Array(Number)} v Second vector\n     * @return The dot product\n     */\n    dotVec2(u, v) {\n        return (u[0] * v[0] + u[1] * v[1]);\n    },\n\n\n    sqLenVec3(v) {\n        return math.dotVec3(v, v);\n    },\n\n\n    sqLenVec2(v) {\n        return math.dotVec2(v, v);\n    },\n\n    /**\n     * Returns the length of a three-element vector.\n     * @method lenVec3\n     * @static\n     * @param {Array(Number)} v The vector\n     * @return The length\n     */\n    lenVec3(v) {\n        return Math.sqrt(math.sqLenVec3(v));\n    },\n\n    distVec3: ((() => {\n        const vec = new FloatArrayType(3);\n        return (v, w) => math.lenVec3(math.subVec3(v, w, vec));\n    }))(),\n\n    /**\n     * Returns the length of a two-element vector.\n     * @method lenVec2\n     * @static\n     * @param {Array(Number)} v The vector\n     * @return The length\n     */\n    lenVec2(v) {\n        return Math.sqrt(math.sqLenVec2(v));\n    },\n\n    distVec2: ((() => {\n        const vec = new FloatArrayType(2);\n        return (v, w) => math.lenVec2(math.subVec2(v, w, vec));\n    }))(),\n\n    /**\n     * @method rcpVec3\n     * @static\n     * @param v vec3\n     * @param dest vec3 - optional destination\n     * @return [] dest if specified, v otherwise\n     *\n     */\n    rcpVec3(v, dest) {\n        return math.divScalarVec3(1.0, v, dest);\n    },\n\n    /**\n     * Normalizes a four-element vector\n     * @method normalizeVec4\n     * @static\n     * @param v vec4\n     * @param dest vec4 - optional destination\n     * @return [] dest if specified, v otherwise\n     *\n     */\n    normalizeVec4(v, dest) {\n        const f = 1.0 / math.lenVec4(v);\n        return math.mulVec4Scalar(v, f, dest);\n    },\n\n    /**\n     * Normalizes a three-element vector\n     * @method normalizeVec4\n     * @static\n     */\n    normalizeVec3(v, dest) {\n        const f = 1.0 / math.lenVec3(v);\n        return math.mulVec3Scalar(v, f, dest);\n    },\n\n    /**\n     * Normalizes a two-element vector\n     * @method normalizeVec2\n     * @static\n     */\n    normalizeVec2(v, dest) {\n        const f = 1.0 / math.lenVec2(v);\n        return math.mulVec2Scalar(v, f, dest);\n    },\n\n    /**\n     * Gets the angle between two vectors\n     * @method angleVec3\n     * @param v\n     * @param w\n     * @returns {number}\n     */\n    angleVec3(v, w) {\n        let theta = math.dotVec3(v, w) / (Math.sqrt(math.sqLenVec3(v) * math.sqLenVec3(w)));\n        theta = theta < -1 ? -1 : (theta > 1 ? 1 : theta);  // Clamp to handle numerical problems\n        return Math.acos(theta);\n    },\n\n    /**\n     * Creates a three-element vector from the rotation part of a sixteen-element matrix.\n     * @param m\n     * @param dest\n     */\n    vec3FromMat4Scale: ((() => {\n\n        const tempVec3 = new FloatArrayType(3);\n\n        return (m, dest) => {\n\n            tempVec3[0] = m[0];\n            tempVec3[1] = m[1];\n            tempVec3[2] = m[2];\n\n            dest[0] = math.lenVec3(tempVec3);\n\n            tempVec3[0] = m[4];\n            tempVec3[1] = m[5];\n            tempVec3[2] = m[6];\n\n            dest[1] = math.lenVec3(tempVec3);\n\n            tempVec3[0] = m[8];\n            tempVec3[1] = m[9];\n            tempVec3[2] = m[10];\n\n            dest[2] = math.lenVec3(tempVec3);\n\n            return dest;\n        };\n    }))(),\n\n    /**\n     * Converts an n-element vector to a JSON-serializable\n     * array with values rounded to two decimal places.\n     */\n    vecToArray: ((() => {\n        function trunc(v) {\n            return Math.round(v * 100000) / 100000\n        }\n\n        return v => {\n            v = Array.prototype.slice.call(v);\n            for (let i = 0, len = v.length; i < len; i++) {\n                v[i] = trunc(v[i]);\n            }\n            return v;\n        };\n    }))(),\n\n    /**\n     * Converts a 3-element vector from an array to an object of the form ````{x:999, y:999, z:999}````.\n     * @param arr\n     * @returns {{x: *, y: *, z: *}}\n     */\n    xyzArrayToObject(arr) {\n        return {\"x\": arr[0], \"y\": arr[1], \"z\": arr[2]};\n    },\n\n    /**\n     * Converts a 3-element vector object of the form ````{x:999, y:999, z:999}```` to an array.\n     * @param xyz\n     * @param  [arry]\n     * @returns {*[]}\n     */\n    xyzObjectToArray(xyz, arry) {\n        arry = arry || math.vec3();\n        arry[0] = xyz.x;\n        arry[1] = xyz.y;\n        arry[2] = xyz.z;\n        return arry;\n    },\n\n    /**\n     * Duplicates a 4x4 identity matrix.\n     * @method dupMat4\n     * @static\n     */\n    dupMat4(m) {\n        return m.slice(0, 16);\n    },\n\n    /**\n     * Extracts a 3x3 matrix from a 4x4 matrix.\n     * @method mat4To3\n     * @static\n     */\n    mat4To3(m) {\n        return [\n            m[0], m[1], m[2],\n            m[4], m[5], m[6],\n            m[8], m[9], m[10]\n        ];\n    },\n\n    /**\n     * Returns a 4x4 matrix with each element set to the given scalar value.\n     * @method m4s\n     * @static\n     */\n    m4s(s) {\n        return [\n            s, s, s, s,\n            s, s, s, s,\n            s, s, s, s,\n            s, s, s, s\n        ];\n    },\n\n    /**\n     * Returns a 4x4 matrix with each element set to zero.\n     * @method setMat4ToZeroes\n     * @static\n     */\n    setMat4ToZeroes() {\n        return math.m4s(0.0);\n    },\n\n    /**\n     * Returns a 4x4 matrix with each element set to 1.0.\n     * @method setMat4ToOnes\n     * @static\n     */\n    setMat4ToOnes() {\n        return math.m4s(1.0);\n    },\n\n    /**\n     * Returns a 4x4 matrix with each element set to 1.0.\n     * @method setMat4ToOnes\n     * @static\n     */\n    diagonalMat4v(v) {\n        return new FloatArrayType([\n            v[0], 0.0, 0.0, 0.0,\n            0.0, v[1], 0.0, 0.0,\n            0.0, 0.0, v[2], 0.0,\n            0.0, 0.0, 0.0, v[3]\n        ]);\n    },\n\n    /**\n     * Returns a 4x4 matrix with diagonal elements set to the given vector.\n     * @method diagonalMat4c\n     * @static\n     */\n    diagonalMat4c(x, y, z, w) {\n        return math.diagonalMat4v([x, y, z, w]);\n    },\n\n    /**\n     * Returns a 4x4 matrix with diagonal elements set to the given scalar.\n     * @method diagonalMat4s\n     * @static\n     */\n    diagonalMat4s(s) {\n        return math.diagonalMat4c(s, s, s, s);\n    },\n\n    /**\n     * Returns a 4x4 identity matrix.\n     * @method identityMat4\n     * @static\n     */\n    identityMat4(mat = new FloatArrayType(16)) {\n        mat[0] = 1.0;\n        mat[1] = 0.0;\n        mat[2] = 0.0;\n        mat[3] = 0.0;\n\n        mat[4] = 0.0;\n        mat[5] = 1.0;\n        mat[6] = 0.0;\n        mat[7] = 0.0;\n\n        mat[8] = 0.0;\n        mat[9] = 0.0;\n        mat[10] = 1.0;\n        mat[11] = 0.0;\n\n        mat[12] = 0.0;\n        mat[13] = 0.0;\n        mat[14] = 0.0;\n        mat[15] = 1.0;\n\n        return mat;\n    },\n\n    /**\n     * Returns a 3x3 identity matrix.\n     * @method identityMat3\n     * @static\n     */\n    identityMat3(mat = new FloatArrayType(9)) {\n        mat[0] = 1.0;\n        mat[1] = 0.0;\n        mat[2] = 0.0;\n\n        mat[3] = 0.0;\n        mat[4] = 1.0;\n        mat[5] = 0.0;\n\n        mat[6] = 0.0;\n        mat[7] = 0.0;\n        mat[8] = 1.0;\n\n        return mat;\n    },\n\n    /**\n     * Tests if the given 4x4 matrix is the identity matrix.\n     * @method isIdentityMat4\n     * @static\n     */\n    isIdentityMat4(m) {\n        if (m[0] !== 1.0 || m[1] !== 0.0 || m[2] !== 0.0 || m[3] !== 0.0 ||\n            m[4] !== 0.0 || m[5] !== 1.0 || m[6] !== 0.0 || m[7] !== 0.0 ||\n            m[8] !== 0.0 || m[9] !== 0.0 || m[10] !== 1.0 || m[11] !== 0.0 ||\n            m[12] !== 0.0 || m[13] !== 0.0 || m[14] !== 0.0 || m[15] !== 1.0) {\n            return false;\n        }\n        return true;\n    },\n\n    /**\n     * Negates the given 4x4 matrix.\n     * @method negateMat4\n     * @static\n     */\n    negateMat4(m, dest) {\n        if (!dest) {\n            dest = m;\n        }\n        dest[0] = -m[0];\n        dest[1] = -m[1];\n        dest[2] = -m[2];\n        dest[3] = -m[3];\n        dest[4] = -m[4];\n        dest[5] = -m[5];\n        dest[6] = -m[6];\n        dest[7] = -m[7];\n        dest[8] = -m[8];\n        dest[9] = -m[9];\n        dest[10] = -m[10];\n        dest[11] = -m[11];\n        dest[12] = -m[12];\n        dest[13] = -m[13];\n        dest[14] = -m[14];\n        dest[15] = -m[15];\n        return dest;\n    },\n\n    /**\n     * Adds the given 4x4 matrices together.\n     * @method addMat4\n     * @static\n     */\n    addMat4(a, b, dest) {\n        if (!dest) {\n            dest = a;\n        }\n        dest[0] = a[0] + b[0];\n        dest[1] = a[1] + b[1];\n        dest[2] = a[2] + b[2];\n        dest[3] = a[3] + b[3];\n        dest[4] = a[4] + b[4];\n        dest[5] = a[5] + b[5];\n        dest[6] = a[6] + b[6];\n        dest[7] = a[7] + b[7];\n        dest[8] = a[8] + b[8];\n        dest[9] = a[9] + b[9];\n        dest[10] = a[10] + b[10];\n        dest[11] = a[11] + b[11];\n        dest[12] = a[12] + b[12];\n        dest[13] = a[13] + b[13];\n        dest[14] = a[14] + b[14];\n        dest[15] = a[15] + b[15];\n        return dest;\n    },\n\n    /**\n     * Adds the given scalar to each element of the given 4x4 matrix.\n     * @method addMat4Scalar\n     * @static\n     */\n    addMat4Scalar(m, s, dest) {\n        if (!dest) {\n            dest = m;\n        }\n        dest[0] = m[0] + s;\n        dest[1] = m[1] + s;\n        dest[2] = m[2] + s;\n        dest[3] = m[3] + s;\n        dest[4] = m[4] + s;\n        dest[5] = m[5] + s;\n        dest[6] = m[6] + s;\n        dest[7] = m[7] + s;\n        dest[8] = m[8] + s;\n        dest[9] = m[9] + s;\n        dest[10] = m[10] + s;\n        dest[11] = m[11] + s;\n        dest[12] = m[12] + s;\n        dest[13] = m[13] + s;\n        dest[14] = m[14] + s;\n        dest[15] = m[15] + s;\n        return dest;\n    },\n\n    /**\n     * Adds the given scalar to each element of the given 4x4 matrix.\n     * @method addScalarMat4\n     * @static\n     */\n    addScalarMat4(s, m, dest) {\n        return math.addMat4Scalar(m, s, dest);\n    },\n\n    /**\n     * Subtracts the second 4x4 matrix from the first.\n     * @method subMat4\n     * @static\n     */\n    subMat4(a, b, dest) {\n        if (!dest) {\n            dest = a;\n        }\n        dest[0] = a[0] - b[0];\n        dest[1] = a[1] - b[1];\n        dest[2] = a[2] - b[2];\n        dest[3] = a[3] - b[3];\n        dest[4] = a[4] - b[4];\n        dest[5] = a[5] - b[5];\n        dest[6] = a[6] - b[6];\n        dest[7] = a[7] - b[7];\n        dest[8] = a[8] - b[8];\n        dest[9] = a[9] - b[9];\n        dest[10] = a[10] - b[10];\n        dest[11] = a[11] - b[11];\n        dest[12] = a[12] - b[12];\n        dest[13] = a[13] - b[13];\n        dest[14] = a[14] - b[14];\n        dest[15] = a[15] - b[15];\n        return dest;\n    },\n\n    /**\n     * Subtracts the given scalar from each element of the given 4x4 matrix.\n     * @method subMat4Scalar\n     * @static\n     */\n    subMat4Scalar(m, s, dest) {\n        if (!dest) {\n            dest = m;\n        }\n        dest[0] = m[0] - s;\n        dest[1] = m[1] - s;\n        dest[2] = m[2] - s;\n        dest[3] = m[3] - s;\n        dest[4] = m[4] - s;\n        dest[5] = m[5] - s;\n        dest[6] = m[6] - s;\n        dest[7] = m[7] - s;\n        dest[8] = m[8] - s;\n        dest[9] = m[9] - s;\n        dest[10] = m[10] - s;\n        dest[11] = m[11] - s;\n        dest[12] = m[12] - s;\n        dest[13] = m[13] - s;\n        dest[14] = m[14] - s;\n        dest[15] = m[15] - s;\n        return dest;\n    },\n\n    /**\n     * Subtracts the given scalar from each element of the given 4x4 matrix.\n     * @method subScalarMat4\n     * @static\n     */\n    subScalarMat4(s, m, dest) {\n        if (!dest) {\n            dest = m;\n        }\n        dest[0] = s - m[0];\n        dest[1] = s - m[1];\n        dest[2] = s - m[2];\n        dest[3] = s - m[3];\n        dest[4] = s - m[4];\n        dest[5] = s - m[5];\n        dest[6] = s - m[6];\n        dest[7] = s - m[7];\n        dest[8] = s - m[8];\n        dest[9] = s - m[9];\n        dest[10] = s - m[10];\n        dest[11] = s - m[11];\n        dest[12] = s - m[12];\n        dest[13] = s - m[13];\n        dest[14] = s - m[14];\n        dest[15] = s - m[15];\n        return dest;\n    },\n\n    /**\n     * Multiplies the two given 4x4 matrix by each other.\n     * @method mulMat4\n     * @static\n     */\n    mulMat4(a, b, dest) {\n        if (!dest) {\n            dest = a;\n        }\n\n        // Cache the matrix values (makes for huge speed increases!)\n        const a00 = a[0];\n\n        const a01 = a[1];\n        const a02 = a[2];\n        const a03 = a[3];\n        const a10 = a[4];\n        const a11 = a[5];\n        const a12 = a[6];\n        const a13 = a[7];\n        const a20 = a[8];\n        const a21 = a[9];\n        const a22 = a[10];\n        const a23 = a[11];\n        const a30 = a[12];\n        const a31 = a[13];\n        const a32 = a[14];\n        const a33 = a[15];\n        const b00 = b[0];\n        const b01 = b[1];\n        const b02 = b[2];\n        const b03 = b[3];\n        const b10 = b[4];\n        const b11 = b[5];\n        const b12 = b[6];\n        const b13 = b[7];\n        const b20 = b[8];\n        const b21 = b[9];\n        const b22 = b[10];\n        const b23 = b[11];\n        const b30 = b[12];\n        const b31 = b[13];\n        const b32 = b[14];\n        const b33 = b[15];\n\n        dest[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;\n        dest[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;\n        dest[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;\n        dest[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;\n        dest[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;\n        dest[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;\n        dest[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;\n        dest[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;\n        dest[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;\n        dest[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;\n        dest[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;\n        dest[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;\n        dest[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;\n        dest[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;\n        dest[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;\n        dest[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;\n\n        return dest;\n    },\n\n    /**\n     * Multiplies the two given 3x3 matrices by each other.\n     * @method mulMat4\n     * @static\n     */\n    mulMat3(a, b, dest) {\n        if (!dest) {\n            dest = new FloatArrayType(9);\n        }\n\n        const a11 = a[0];\n        const a12 = a[3];\n        const a13 = a[6];\n        const a21 = a[1];\n        const a22 = a[4];\n        const a23 = a[7];\n        const a31 = a[2];\n        const a32 = a[5];\n        const a33 = a[8];\n        const b11 = b[0];\n        const b12 = b[3];\n        const b13 = b[6];\n        const b21 = b[1];\n        const b22 = b[4];\n        const b23 = b[7];\n        const b31 = b[2];\n        const b32 = b[5];\n        const b33 = b[8];\n\n        dest[0] = a11 * b11 + a12 * b21 + a13 * b31;\n        dest[3] = a11 * b12 + a12 * b22 + a13 * b32;\n        dest[6] = a11 * b13 + a12 * b23 + a13 * b33;\n\n        dest[1] = a21 * b11 + a22 * b21 + a23 * b31;\n        dest[4] = a21 * b12 + a22 * b22 + a23 * b32;\n        dest[7] = a21 * b13 + a22 * b23 + a23 * b33;\n\n        dest[2] = a31 * b11 + a32 * b21 + a33 * b31;\n        dest[5] = a31 * b12 + a32 * b22 + a33 * b32;\n        dest[8] = a31 * b13 + a32 * b23 + a33 * b33;\n\n        return dest;\n    },\n\n    /**\n     * Multiplies each element of the given 4x4 matrix by the given scalar.\n     * @method mulMat4Scalar\n     * @static\n     */\n    mulMat4Scalar(m, s, dest) {\n        if (!dest) {\n            dest = m;\n        }\n        dest[0] = m[0] * s;\n        dest[1] = m[1] * s;\n        dest[2] = m[2] * s;\n        dest[3] = m[3] * s;\n        dest[4] = m[4] * s;\n        dest[5] = m[5] * s;\n        dest[6] = m[6] * s;\n        dest[7] = m[7] * s;\n        dest[8] = m[8] * s;\n        dest[9] = m[9] * s;\n        dest[10] = m[10] * s;\n        dest[11] = m[11] * s;\n        dest[12] = m[12] * s;\n        dest[13] = m[13] * s;\n        dest[14] = m[14] * s;\n        dest[15] = m[15] * s;\n        return dest;\n    },\n\n    /**\n     * Multiplies the given 4x4 matrix by the given four-element vector.\n     * @method mulMat4v4\n     * @static\n     */\n    mulMat4v4(m, v, dest = math.vec4()) {\n        const v0 = v[0];\n        const v1 = v[1];\n        const v2 = v[2];\n        const v3 = v[3];\n        dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3;\n        dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3;\n        dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3;\n        dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3;\n        return dest;\n    },\n\n    /**\n     * Transposes the given 4x4 matrix.\n     * @method transposeMat4\n     * @static\n     */\n    transposeMat4(mat, dest) {\n        // If we are transposing ourselves we can skip a few steps but have to cache some values\n        const m4 = mat[4];\n\n        const m14 = mat[14];\n        const m8 = mat[8];\n        const m13 = mat[13];\n        const m12 = mat[12];\n        const m9 = mat[9];\n        if (!dest || mat === dest) {\n            const a01 = mat[1];\n            const a02 = mat[2];\n            const a03 = mat[3];\n            const a12 = mat[6];\n            const a13 = mat[7];\n            const a23 = mat[11];\n            mat[1] = m4;\n            mat[2] = m8;\n            mat[3] = m12;\n            mat[4] = a01;\n            mat[6] = m9;\n            mat[7] = m13;\n            mat[8] = a02;\n            mat[9] = a12;\n            mat[11] = m14;\n            mat[12] = a03;\n            mat[13] = a13;\n            mat[14] = a23;\n            return mat;\n        }\n        dest[0] = mat[0];\n        dest[1] = m4;\n        dest[2] = m8;\n        dest[3] = m12;\n        dest[4] = mat[1];\n        dest[5] = mat[5];\n        dest[6] = m9;\n        dest[7] = m13;\n        dest[8] = mat[2];\n        dest[9] = mat[6];\n        dest[10] = mat[10];\n        dest[11] = m14;\n        dest[12] = mat[3];\n        dest[13] = mat[7];\n        dest[14] = mat[11];\n        dest[15] = mat[15];\n        return dest;\n    },\n\n    /**\n     * Transposes the given 3x3 matrix.\n     *\n     * @method transposeMat3\n     * @static\n     */\n    transposeMat3(mat, dest) {\n        if (dest === mat) {\n            const a01 = mat[1];\n            const a02 = mat[2];\n            const a12 = mat[5];\n            dest[1] = mat[3];\n            dest[2] = mat[6];\n            dest[3] = a01;\n            dest[5] = mat[7];\n            dest[6] = a02;\n            dest[7] = a12;\n        } else {\n            dest[0] = mat[0];\n            dest[1] = mat[3];\n            dest[2] = mat[6];\n            dest[3] = mat[1];\n            dest[4] = mat[4];\n            dest[5] = mat[7];\n            dest[6] = mat[2];\n            dest[7] = mat[5];\n            dest[8] = mat[8];\n        }\n        return dest;\n    },\n\n    /**\n     * Returns the determinant of the given 4x4 matrix.\n     * @method determinantMat4\n     * @static\n     */\n    determinantMat4(mat) {\n        // Cache the matrix values (makes for huge speed increases!)\n        const a00 = mat[0];\n\n        const a01 = mat[1];\n        const a02 = mat[2];\n        const a03 = mat[3];\n        const a10 = mat[4];\n        const a11 = mat[5];\n        const a12 = mat[6];\n        const a13 = mat[7];\n        const a20 = mat[8];\n        const a21 = mat[9];\n        const a22 = mat[10];\n        const a23 = mat[11];\n        const a30 = mat[12];\n        const a31 = mat[13];\n        const a32 = mat[14];\n        const a33 = mat[15];\n        return a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 +\n            a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 +\n            a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 +\n            a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 +\n            a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 +\n            a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33;\n    },\n\n    /**\n     * Returns the inverse of the given 4x4 matrix.\n     * @method inverseMat4\n     * @static\n     */\n    inverseMat4(mat, dest) {\n        if (!dest) {\n            dest = mat;\n        }\n\n        // Cache the matrix values (makes for huge speed increases!)\n        const a00 = mat[0];\n\n        const a01 = mat[1];\n        const a02 = mat[2];\n        const a03 = mat[3];\n        const a10 = mat[4];\n        const a11 = mat[5];\n        const a12 = mat[6];\n        const a13 = mat[7];\n        const a20 = mat[8];\n        const a21 = mat[9];\n        const a22 = mat[10];\n        const a23 = mat[11];\n        const a30 = mat[12];\n        const a31 = mat[13];\n        const a32 = mat[14];\n        const a33 = mat[15];\n        const b00 = a00 * a11 - a01 * a10;\n        const b01 = a00 * a12 - a02 * a10;\n        const b02 = a00 * a13 - a03 * a10;\n        const b03 = a01 * a12 - a02 * a11;\n        const b04 = a01 * a13 - a03 * a11;\n        const b05 = a02 * a13 - a03 * a12;\n        const b06 = a20 * a31 - a21 * a30;\n        const b07 = a20 * a32 - a22 * a30;\n        const b08 = a20 * a33 - a23 * a30;\n        const b09 = a21 * a32 - a22 * a31;\n        const b10 = a21 * a33 - a23 * a31;\n        const b11 = a22 * a33 - a23 * a32;\n\n        // Calculate the determinant (inlined to avoid double-caching)\n        const invDet = 1 / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06);\n\n        dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;\n        dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;\n        dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;\n        dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;\n        dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;\n        dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;\n        dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;\n        dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;\n        dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;\n        dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;\n        dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;\n        dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;\n        dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;\n        dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;\n        dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;\n        dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;\n\n        return dest;\n    },\n\n    /**\n     * Returns the trace of the given 4x4 matrix.\n     * @method traceMat4\n     * @static\n     */\n    traceMat4(m) {\n        return (m[0] + m[5] + m[10] + m[15]);\n    },\n\n    /**\n     * Returns 4x4 translation matrix.\n     * @method translationMat4\n     * @static\n     */\n    translationMat4v(v, dest) {\n        const m = dest || math.identityMat4();\n        m[12] = v[0];\n        m[13] = v[1];\n        m[14] = v[2];\n        return m;\n    },\n\n    /**\n     * Returns 3x3 translation matrix.\n     * @method translationMat3\n     * @static\n     */\n    translationMat3v(v, dest) {\n        const m = dest || math.identityMat3();\n        m[6] = v[0];\n        m[7] = v[1];\n        return m;\n    },\n\n    /**\n     * Returns 4x4 translation matrix.\n     * @method translationMat4c\n     * @static\n     */\n    translationMat4c: ((() => {\n        const xyz = new FloatArrayType(3);\n        return (x, y, z, dest) => {\n            xyz[0] = x;\n            xyz[1] = y;\n            xyz[2] = z;\n            return math.translationMat4v(xyz, dest);\n        };\n    }))(),\n\n    /**\n     * Returns 4x4 translation matrix.\n     * @method translationMat4s\n     * @static\n     */\n    translationMat4s(s, dest) {\n        return math.translationMat4c(s, s, s, dest);\n    },\n\n    /**\n     * Efficiently post-concatenates a translation to the given matrix.\n     * @param v\n     * @param m\n     */\n    translateMat4v(xyz, m) {\n        return math.translateMat4c(xyz[0], xyz[1], xyz[2], m);\n    },\n\n    /**\n     * Efficiently post-concatenates a translation to the given matrix.\n     * @param x\n     * @param y\n     * @param z\n     * @param m\n     */\n\n    translateMat4c(x, y, z, m) {\n\n        const m3 = m[3];\n        m[0] += m3 * x;\n        m[1] += m3 * y;\n        m[2] += m3 * z;\n\n        const m7 = m[7];\n        m[4] += m7 * x;\n        m[5] += m7 * y;\n        m[6] += m7 * z;\n\n        const m11 = m[11];\n        m[8] += m11 * x;\n        m[9] += m11 * y;\n        m[10] += m11 * z;\n\n        const m15 = m[15];\n        m[12] += m15 * x;\n        m[13] += m15 * y;\n        m[14] += m15 * z;\n\n        return m;\n    },\n\n    /**\n     * Creates a new matrix that replaces the translation in the rightmost column of the given\n     * affine matrix with the given translation.\n     * @param m\n     * @param translation\n     * @param dest\n     * @returns {*}\n     */\n    setMat4Translation(m, translation, dest) {\n\n        dest[0] = m[0];\n        dest[1] = m[1];\n        dest[2] = m[2];\n        dest[3] = m[3];\n\n        dest[4] = m[4];\n        dest[5] = m[5];\n        dest[6] = m[6];\n        dest[7] = m[7];\n\n        dest[8] = m[8];\n        dest[9] = m[9];\n        dest[10] = m[10];\n        dest[11] = m[11];\n\n        dest[12] = translation[0];\n        dest[13] = translation[1];\n        dest[14] = translation[2];\n        dest[15] = m[15];\n\n        return dest;\n    },\n\n    /**\n     * Returns 4x4 rotation matrix.\n     * @method rotationMat4v\n     * @static\n     */\n    rotationMat4v(anglerad, axis, m) {\n        const ax = math.normalizeVec4([axis[0], axis[1], axis[2], 0.0], []);\n        const s = Math.sin(anglerad);\n        const c = Math.cos(anglerad);\n        const q = 1.0 - c;\n\n        const x = ax[0];\n        const y = ax[1];\n        const z = ax[2];\n\n        let xy;\n        let yz;\n        let zx;\n        let xs;\n        let ys;\n        let zs;\n\n        //xx = x * x; used once\n        //yy = y * y; used once\n        //zz = z * z; used once\n        xy = x * y;\n        yz = y * z;\n        zx = z * x;\n        xs = x * s;\n        ys = y * s;\n        zs = z * s;\n\n        m = m || math.mat4();\n\n        m[0] = (q * x * x) + c;\n        m[1] = (q * xy) + zs;\n        m[2] = (q * zx) - ys;\n        m[3] = 0.0;\n\n        m[4] = (q * xy) - zs;\n        m[5] = (q * y * y) + c;\n        m[6] = (q * yz) + xs;\n        m[7] = 0.0;\n\n        m[8] = (q * zx) + ys;\n        m[9] = (q * yz) - xs;\n        m[10] = (q * z * z) + c;\n        m[11] = 0.0;\n\n        m[12] = 0.0;\n        m[13] = 0.0;\n        m[14] = 0.0;\n        m[15] = 1.0;\n\n        return m;\n    },\n\n    /**\n     * Returns 4x4 rotation matrix.\n     * @method rotationMat4c\n     * @static\n     */\n    rotationMat4c(anglerad, x, y, z, mat) {\n        return math.rotationMat4v(anglerad, [x, y, z], mat);\n    },\n\n    /**\n     * Returns 4x4 scale matrix.\n     * @method scalingMat4v\n     * @static\n     */\n    scalingMat4v(v, m = math.identityMat4()) {\n        m[0] = v[0];\n        m[5] = v[1];\n        m[10] = v[2];\n        return m;\n    },\n\n    /**\n     * Returns 3x3 scale matrix.\n     * @method scalingMat3v\n     * @static\n     */\n    scalingMat3v(v, m = math.identityMat3()) {\n        m[0] = v[0];\n        m[4] = v[1];\n        return m;\n    },\n\n    /**\n     * Returns 4x4 scale matrix.\n     * @method scalingMat4c\n     * @static\n     */\n    scalingMat4c: ((() => {\n        const xyz = new FloatArrayType(3);\n        return (x, y, z, dest) => {\n            xyz[0] = x;\n            xyz[1] = y;\n            xyz[2] = z;\n            return math.scalingMat4v(xyz, dest);\n        };\n    }))(),\n\n    /**\n     * Efficiently post-concatenates a scaling to the given matrix.\n     * @method scaleMat4c\n     * @param x\n     * @param y\n     * @param z\n     * @param m\n     */\n    scaleMat4c(x, y, z, m) {\n\n        m[0] *= x;\n        m[4] *= y;\n        m[8] *= z;\n\n        m[1] *= x;\n        m[5] *= y;\n        m[9] *= z;\n\n        m[2] *= x;\n        m[6] *= y;\n        m[10] *= z;\n\n        m[3] *= x;\n        m[7] *= y;\n        m[11] *= z;\n        return m;\n    },\n\n    /**\n     * Efficiently post-concatenates a scaling to the given matrix.\n     * @method scaleMat4c\n     * @param xyz\n     * @param m\n     */\n    scaleMat4v(xyz, m) {\n\n        const x = xyz[0];\n        const y = xyz[1];\n        const z = xyz[2];\n\n        m[0] *= x;\n        m[4] *= y;\n        m[8] *= z;\n        m[1] *= x;\n        m[5] *= y;\n        m[9] *= z;\n        m[2] *= x;\n        m[6] *= y;\n        m[10] *= z;\n        m[3] *= x;\n        m[7] *= y;\n        m[11] *= z;\n\n        return m;\n    },\n\n    /**\n     * Returns 4x4 scale matrix.\n     * @method scalingMat4s\n     * @static\n     */\n    scalingMat4s(s) {\n        return math.scalingMat4c(s, s, s);\n    },\n\n    /**\n     * Creates a matrix from a quaternion rotation and vector translation\n     *\n     * @param {Number[]} q Rotation quaternion\n     * @param {Number[]} v Translation vector\n     * @param {Number[]} dest Destination matrix\n     * @returns {Number[]} dest\n     */\n    rotationTranslationMat4(q, v, dest = math.mat4()) {\n        const x = q[0];\n        const y = q[1];\n        const z = q[2];\n        const w = q[3];\n\n        const x2 = x + x;\n        const y2 = y + y;\n        const z2 = z + z;\n        const xx = x * x2;\n        const xy = x * y2;\n        const xz = x * z2;\n        const yy = y * y2;\n        const yz = y * z2;\n        const zz = z * z2;\n        const wx = w * x2;\n        const wy = w * y2;\n        const wz = w * z2;\n\n        dest[0] = 1 - (yy + zz);\n        dest[1] = xy + wz;\n        dest[2] = xz - wy;\n        dest[3] = 0;\n        dest[4] = xy - wz;\n        dest[5] = 1 - (xx + zz);\n        dest[6] = yz + wx;\n        dest[7] = 0;\n        dest[8] = xz + wy;\n        dest[9] = yz - wx;\n        dest[10] = 1 - (xx + yy);\n        dest[11] = 0;\n        dest[12] = v[0];\n        dest[13] = v[1];\n        dest[14] = v[2];\n        dest[15] = 1;\n\n        return dest;\n    },\n\n    /**\n     * Gets Euler angles from a 4x4 matrix.\n     *\n     * @param {Number[]} mat The 4x4 matrix.\n     * @param {String} order Desired Euler angle order: \"XYZ\", \"YXZ\", \"ZXY\" etc.\n     * @param {Number[]} [dest] Destination Euler angles, created by default.\n     * @returns {Number[]} The Euler angles (in degrees).\n     */\n    mat4ToEuler(mat, order, dest = math.vec4()) {\n        const clamp = math.clamp;\n\n        // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n        const m11 = mat[0];\n\n        const m12 = mat[4];\n        const m13 = mat[8];\n        const m21 = mat[1];\n        const m22 = mat[5];\n        const m23 = mat[9];\n        const m31 = mat[2];\n        const m32 = mat[6];\n        const m33 = mat[10];\n\n        if (order === 'XYZ') {\n\n            dest[1] = Math.asin(clamp(m13, -1, 1));\n\n            if (Math.abs(m13) < 0.99999) {\n                dest[0] = Math.atan2(-m23, m33);\n                dest[2] = Math.atan2(-m12, m11);\n            } else {\n                dest[0] = Math.atan2(m32, m22);\n                dest[2] = 0;\n\n            }\n\n        } else if (order === 'YXZ') {\n\n            dest[0] = Math.asin(-clamp(m23, -1, 1));\n\n            if (Math.abs(m23) < 0.99999) {\n                dest[1] = Math.atan2(m13, m33);\n                dest[2] = Math.atan2(m21, m22);\n            } else {\n                dest[1] = Math.atan2(-m31, m11);\n                dest[2] = 0;\n            }\n\n        } else if (order === 'ZXY') {\n\n            dest[0] = Math.asin(clamp(m32, -1, 1));\n\n            if (Math.abs(m32) < 0.99999) {\n                dest[1] = Math.atan2(-m31, m33);\n                dest[2] = Math.atan2(-m12, m22);\n            } else {\n                dest[1] = 0;\n                dest[2] = Math.atan2(m21, m11);\n            }\n\n        } else if (order === 'ZYX') {\n\n            dest[1] = Math.asin(-clamp(m31, -1, 1));\n\n            if (Math.abs(m31) < 0.99999) {\n                dest[0] = Math.atan2(m32, m33);\n                dest[2] = Math.atan2(m21, m11);\n            } else {\n                dest[0] = 0;\n                dest[2] = Math.atan2(-m12, m22);\n            }\n\n        } else if (order === 'YZX') {\n\n            dest[2] = Math.asin(clamp(m21, -1, 1));\n\n            if (Math.abs(m21) < 0.99999) {\n                dest[0] = Math.atan2(-m23, m22);\n                dest[1] = Math.atan2(-m31, m11);\n            } else {\n                dest[0] = 0;\n                dest[1] = Math.atan2(m13, m33);\n            }\n\n        } else if (order === 'XZY') {\n\n            dest[2] = Math.asin(-clamp(m12, -1, 1));\n\n            if (Math.abs(m12) < 0.99999) {\n                dest[0] = Math.atan2(m32, m22);\n                dest[1] = Math.atan2(m13, m11);\n            } else {\n                dest[0] = Math.atan2(-m23, m33);\n                dest[1] = 0;\n            }\n        }\n\n        dest[0] *= math.RADTODEG;\n        dest[1] *= math.RADTODEG;\n        dest[2] *= math.RADTODEG;\n\n        return dest;\n    },\n\n    composeMat4(position, quaternion, scale, mat = math.mat4()) {\n        math.quaternionToRotationMat4(quaternion, mat);\n        math.scaleMat4v(scale, mat);\n        math.translateMat4v(position, mat);\n\n        return mat;\n    },\n\n    decomposeMat4: (() => {\n\n        const vec = new FloatArrayType(3);\n        const matrix = new FloatArrayType(16);\n\n        return function decompose(mat, position, quaternion, scale) {\n\n            vec[0] = mat[0];\n            vec[1] = mat[1];\n            vec[2] = mat[2];\n\n            let sx = math.lenVec3(vec);\n\n            vec[0] = mat[4];\n            vec[1] = mat[5];\n            vec[2] = mat[6];\n\n            const sy = math.lenVec3(vec);\n\n            vec[0] = mat[8];\n            vec[1] = mat[9];\n            vec[2] = mat[10];\n\n            const sz = math.lenVec3(vec);\n\n            // if determine is negative, we need to invert one scale\n            const det = math.determinantMat4(mat);\n\n            if (det < 0) {\n                sx = -sx;\n            }\n\n            position[0] = mat[12];\n            position[1] = mat[13];\n            position[2] = mat[14];\n\n            // scale the rotation part\n            matrix.set(mat);\n\n            const invSX = 1 / sx;\n            const invSY = 1 / sy;\n            const invSZ = 1 / sz;\n\n            matrix[0] *= invSX;\n            matrix[1] *= invSX;\n            matrix[2] *= invSX;\n\n            matrix[4] *= invSY;\n            matrix[5] *= invSY;\n            matrix[6] *= invSY;\n\n            matrix[8] *= invSZ;\n            matrix[9] *= invSZ;\n            matrix[10] *= invSZ;\n\n            math.mat4ToQuaternion(matrix, quaternion);\n\n            scale[0] = sx;\n            scale[1] = sy;\n            scale[2] = sz;\n\n            return this;\n\n        };\n\n    })(),\n\n    /** @private */\n    getColMat4(mat, c) {\n        const i = c * 4;\n        return [mat[i], mat[i + 1], mat[i + 2], mat[i + 3]];\n    },\n\n    /** @private */\n    setRowMat4(mat, r, v) {\n        mat[r] = v[0];\n        mat[r + 4] = v[1];\n        mat[r + 8] = v[2];\n        mat[r + 12] = v[3];\n    },\n\n    /**\n     * Returns a 4x4 'lookat' viewing transform matrix.\n     * @method lookAtMat4v\n     * @param pos vec3 position of the viewer\n     * @param target vec3 point the viewer is looking at\n     * @param up vec3 pointing \"up\"\n     * @param dest mat4 Optional, mat4 matrix will be written into\n     *\n     * @return {mat4} dest if specified, a new mat4 otherwise\n     */\n    lookAtMat4v(pos, target, up, dest) {\n        if (!dest) {\n            dest = math.mat4();\n        }\n\n        const posx = pos[0];\n        const posy = pos[1];\n        const posz = pos[2];\n        const upx = up[0];\n        const upy = up[1];\n        const upz = up[2];\n        const targetx = target[0];\n        const targety = target[1];\n        const targetz = target[2];\n\n        if (posx === targetx && posy === targety && posz === targetz) {\n            return math.identityMat4();\n        }\n\n        let z0;\n        let z1;\n        let z2;\n        let x0;\n        let x1;\n        let x2;\n        let y0;\n        let y1;\n        let y2;\n        let len;\n\n        //vec3.direction(eye, center, z);\n        z0 = posx - targetx;\n        z1 = posy - targety;\n        z2 = posz - targetz;\n\n        // normalize (no check needed for 0 because of early return)\n        len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);\n        z0 *= len;\n        z1 *= len;\n        z2 *= len;\n\n        //vec3.normalize(vec3.cross(up, z, x));\n        x0 = upy * z2 - upz * z1;\n        x1 = upz * z0 - upx * z2;\n        x2 = upx * z1 - upy * z0;\n        len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);\n        if (!len) {\n            x0 = 0;\n            x1 = 0;\n            x2 = 0;\n        } else {\n            len = 1 / len;\n            x0 *= len;\n            x1 *= len;\n            x2 *= len;\n        }\n\n        //vec3.normalize(vec3.cross(z, x, y));\n        y0 = z1 * x2 - z2 * x1;\n        y1 = z2 * x0 - z0 * x2;\n        y2 = z0 * x1 - z1 * x0;\n\n        len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);\n        if (!len) {\n            y0 = 0;\n            y1 = 0;\n            y2 = 0;\n        } else {\n            len = 1 / len;\n            y0 *= len;\n            y1 *= len;\n            y2 *= len;\n        }\n\n        dest[0] = x0;\n        dest[1] = y0;\n        dest[2] = z0;\n        dest[3] = 0;\n        dest[4] = x1;\n        dest[5] = y1;\n        dest[6] = z1;\n        dest[7] = 0;\n        dest[8] = x2;\n        dest[9] = y2;\n        dest[10] = z2;\n        dest[11] = 0;\n        dest[12] = -(x0 * posx + x1 * posy + x2 * posz);\n        dest[13] = -(y0 * posx + y1 * posy + y2 * posz);\n        dest[14] = -(z0 * posx + z1 * posy + z2 * posz);\n        dest[15] = 1;\n\n        return dest;\n    },\n\n    /**\n     * Returns a 4x4 'lookat' viewing transform matrix.\n     * @method lookAtMat4c\n     * @static\n     */\n    lookAtMat4c(posx, posy, posz, targetx, targety, targetz, upx, upy, upz) {\n        return math.lookAtMat4v([posx, posy, posz], [targetx, targety, targetz], [upx, upy, upz], []);\n    },\n\n    /**\n     * Returns a 4x4 orthographic projection matrix.\n     * @method orthoMat4c\n     * @static\n     */\n    orthoMat4c(left, right, bottom, top, near, far, dest) {\n        if (!dest) {\n            dest = math.mat4();\n        }\n        const rl = (right - left);\n        const tb = (top - bottom);\n        const fn = (far - near);\n\n        dest[0] = 2.0 / rl;\n        dest[1] = 0.0;\n        dest[2] = 0.0;\n        dest[3] = 0.0;\n\n        dest[4] = 0.0;\n        dest[5] = 2.0 / tb;\n        dest[6] = 0.0;\n        dest[7] = 0.0;\n\n        dest[8] = 0.0;\n        dest[9] = 0.0;\n        dest[10] = -2.0 / fn;\n        dest[11] = 0.0;\n\n        dest[12] = -(left + right) / rl;\n        dest[13] = -(top + bottom) / tb;\n        dest[14] = -(far + near) / fn;\n        dest[15] = 1.0;\n\n        return dest;\n    },\n\n    /**\n     * Returns a 4x4 perspective projection matrix.\n     * @method frustumMat4v\n     * @static\n     */\n    frustumMat4v(fmin, fmax, m) {\n        if (!m) {\n            m = math.mat4();\n        }\n\n        const fmin4 = [fmin[0], fmin[1], fmin[2], 0.0];\n        const fmax4 = [fmax[0], fmax[1], fmax[2], 0.0];\n\n        math.addVec4(fmax4, fmin4, tempMat1);\n        math.subVec4(fmax4, fmin4, tempMat2);\n\n        const t = 2.0 * fmin4[2];\n\n        const tempMat20 = tempMat2[0];\n        const tempMat21 = tempMat2[1];\n        const tempMat22 = tempMat2[2];\n\n        m[0] = t / tempMat20;\n        m[1] = 0.0;\n        m[2] = 0.0;\n        m[3] = 0.0;\n\n        m[4] = 0.0;\n        m[5] = t / tempMat21;\n        m[6] = 0.0;\n        m[7] = 0.0;\n\n        m[8] = tempMat1[0] / tempMat20;\n        m[9] = tempMat1[1] / tempMat21;\n        m[10] = -tempMat1[2] / tempMat22;\n        m[11] = -1.0;\n\n        m[12] = 0.0;\n        m[13] = 0.0;\n        m[14] = -t * fmax4[2] / tempMat22;\n        m[15] = 0.0;\n\n        return m;\n    },\n\n    /**\n     * Returns a 4x4 perspective projection matrix.\n     * @method frustumMat4v\n     * @static\n     */\n    frustumMat4(left, right, bottom, top, near, far, dest) {\n        if (!dest) {\n            dest = math.mat4();\n        }\n        const rl = (right - left);\n        const tb = (top - bottom);\n        const fn = (far - near);\n        dest[0] = (near * 2) / rl;\n        dest[1] = 0;\n        dest[2] = 0;\n        dest[3] = 0;\n        dest[4] = 0;\n        dest[5] = (near * 2) / tb;\n        dest[6] = 0;\n        dest[7] = 0;\n        dest[8] = (right + left) / rl;\n        dest[9] = (top + bottom) / tb;\n        dest[10] = -(far + near) / fn;\n        dest[11] = -1;\n        dest[12] = 0;\n        dest[13] = 0;\n        dest[14] = -(far * near * 2) / fn;\n        dest[15] = 0;\n        return dest;\n    },\n\n    /**\n     * Returns a 4x4 perspective projection matrix.\n     * @method perspectiveMat4v\n     * @static\n     */\n    perspectiveMat4(fovyrad, aspectratio, znear, zfar, m) {\n        const pmin = [];\n        const pmax = [];\n\n        pmin[2] = znear;\n        pmax[2] = zfar;\n\n        pmax[1] = pmin[2] * Math.tan(fovyrad / 2.0);\n        pmin[1] = -pmax[1];\n\n        pmax[0] = pmax[1] * aspectratio;\n        pmin[0] = -pmax[0];\n\n        return math.frustumMat4v(pmin, pmax, m);\n    },\n\n    /**\n     * Returns true if the two 4x4 matrices are the same.\n     * @param m1\n     * @param m2\n     * @returns {Boolean}\n     */\n    compareMat4(m1, m2) {\n        return m1[0] === m2[0] &&\n            m1[1] === m2[1] &&\n            m1[2] === m2[2] &&\n            m1[3] === m2[3] &&\n            m1[4] === m2[4] &&\n            m1[5] === m2[5] &&\n            m1[6] === m2[6] &&\n            m1[7] === m2[7] &&\n            m1[8] === m2[8] &&\n            m1[9] === m2[9] &&\n            m1[10] === m2[10] &&\n            m1[11] === m2[11] &&\n            m1[12] === m2[12] &&\n            m1[13] === m2[13] &&\n            m1[14] === m2[14] &&\n            m1[15] === m2[15];\n    },\n\n    /**\n     * Transforms a three-element position by a 4x4 matrix.\n     * @method transformPoint3\n     * @static\n     */\n    transformPoint3(m, p, dest = math.vec3()) {\n\n        const x = p[0];\n        const y = p[1];\n        const z = p[2];\n\n        dest[0] = (m[0] * x) + (m[4] * y) + (m[8] * z) + m[12];\n        dest[1] = (m[1] * x) + (m[5] * y) + (m[9] * z) + m[13];\n        dest[2] = (m[2] * x) + (m[6] * y) + (m[10] * z) + m[14];\n\n        return dest;\n    },\n\n    /**\n     * Transforms a homogeneous coordinate by a 4x4 matrix.\n     * @method transformPoint3\n     * @static\n     */\n    transformPoint4(m, v, dest = math.vec4()) {\n        dest[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];\n        dest[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];\n        dest[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];\n        dest[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];\n\n        return dest;\n    },\n\n\n    /**\n     * Transforms an array of three-element positions by a 4x4 matrix.\n     * @method transformPoints3\n     * @static\n     */\n    transformPoints3(m, points, points2) {\n        const result = points2 || [];\n        const len = points.length;\n        let p0;\n        let p1;\n        let p2;\n        let pi;\n\n        // cache values\n        const m0 = m[0];\n\n        const m1 = m[1];\n        const m2 = m[2];\n        const m3 = m[3];\n        const m4 = m[4];\n        const m5 = m[5];\n        const m6 = m[6];\n        const m7 = m[7];\n        const m8 = m[8];\n        const m9 = m[9];\n        const m10 = m[10];\n        const m11 = m[11];\n        const m12 = m[12];\n        const m13 = m[13];\n        const m14 = m[14];\n        const m15 = m[15];\n\n        let r;\n\n        for (let i = 0; i < len; ++i) {\n\n            // cache values\n            pi = points[i];\n\n            p0 = pi[0];\n            p1 = pi[1];\n            p2 = pi[2];\n\n            r = result[i] || (result[i] = [0, 0, 0]);\n\n            r[0] = (m0 * p0) + (m4 * p1) + (m8 * p2) + m12;\n            r[1] = (m1 * p0) + (m5 * p1) + (m9 * p2) + m13;\n            r[2] = (m2 * p0) + (m6 * p1) + (m10 * p2) + m14;\n            r[3] = (m3 * p0) + (m7 * p1) + (m11 * p2) + m15;\n        }\n\n        result.length = len;\n\n        return result;\n    },\n\n    /**\n     * Transforms an array of positions by a 4x4 matrix.\n     * @method transformPositions3\n     * @static\n     */\n    transformPositions3(m, p, p2 = p) {\n        let i;\n        const len = p.length;\n\n        let x;\n        let y;\n        let z;\n\n        const m0 = m[0];\n        const m1 = m[1];\n        const m2 = m[2];\n        m[3];\n        const m4 = m[4];\n        const m5 = m[5];\n        const m6 = m[6];\n        m[7];\n        const m8 = m[8];\n        const m9 = m[9];\n        const m10 = m[10];\n        m[11];\n        const m12 = m[12];\n        const m13 = m[13];\n        const m14 = m[14];\n        m[15];\n\n        for (i = 0; i < len; i += 3) {\n\n            x = p[i + 0];\n            y = p[i + 1];\n            z = p[i + 2];\n\n            p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n            p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n            p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n        }\n\n        return p2;\n    },\n\n    /**\n     * Transforms an array of positions by a 4x4 matrix.\n     * @method transformPositions4\n     * @static\n     */\n    transformPositions4(m, p, p2 = p) {\n        let i;\n        const len = p.length;\n\n        let x;\n        let y;\n        let z;\n\n        const m0 = m[0];\n        const m1 = m[1];\n        const m2 = m[2];\n        const m3 = m[3];\n        const m4 = m[4];\n        const m5 = m[5];\n        const m6 = m[6];\n        const m7 = m[7];\n        const m8 = m[8];\n        const m9 = m[9];\n        const m10 = m[10];\n        const m11 = m[11];\n        const m12 = m[12];\n        const m13 = m[13];\n        const m14 = m[14];\n        const m15 = m[15];\n\n        for (i = 0; i < len; i += 4) {\n\n            x = p[i + 0];\n            y = p[i + 1];\n            z = p[i + 2];\n\n            p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n            p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n            p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n            p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n        }\n\n        return p2;\n    },\n\n    /**\n     * Transforms a three-element vector by a 4x4 matrix.\n     * @method transformVec3\n     * @static\n     */\n    transformVec3(m, v, dest) {\n        const v0 = v[0];\n        const v1 = v[1];\n        const v2 = v[2];\n        dest = dest || this.vec3();\n        dest[0] = (m[0] * v0) + (m[4] * v1) + (m[8] * v2);\n        dest[1] = (m[1] * v0) + (m[5] * v1) + (m[9] * v2);\n        dest[2] = (m[2] * v0) + (m[6] * v1) + (m[10] * v2);\n        return dest;\n    },\n\n    /**\n     * Transforms a four-element vector by a 4x4 matrix.\n     * @method transformVec4\n     * @static\n     */\n    transformVec4(m, v, dest) {\n        const v0 = v[0];\n        const v1 = v[1];\n        const v2 = v[2];\n        const v3 = v[3];\n        dest = dest || math.vec4();\n        dest[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3;\n        dest[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3;\n        dest[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3;\n        dest[3] = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3;\n        return dest;\n    },\n\n    /**\n     * Rotate a 2D vector around a center point.\n     *\n     * @param a\n     * @param center\n     * @param angle\n     * @returns {math}\n     */\n    rotateVec2(a, center, angle, dest = a) {\n        const c = Math.cos(angle);\n        const s = Math.sin(angle);\n        const x = a[0] - center[0];\n        const y = a[1] - center[1];\n        dest[0] = x * c - y * s + center[0];\n        dest[1] = x * s + y * c + center[1];\n        return a;\n    },\n\n    /**\n     * Rotate a 3D vector around the x-axis\n     *\n     * @method rotateVec3X\n     * @param {Number[]} a The vec3 point to rotate\n     * @param {Number[]} b The origin of the rotation\n     * @param {Number} c The angle of rotation\n     * @param {Number[]} dest The receiving vec3\n     * @returns {Number[]} dest\n     * @static\n     */\n    rotateVec3X(a, b, c, dest) {\n        const p = [];\n        const r = [];\n\n        //Translate point to the origin\n        p[0] = a[0] - b[0];\n        p[1] = a[1] - b[1];\n        p[2] = a[2] - b[2];\n\n        //perform rotation\n        r[0] = p[0];\n        r[1] = p[1] * Math.cos(c) - p[2] * Math.sin(c);\n        r[2] = p[1] * Math.sin(c) + p[2] * Math.cos(c);\n\n        //translate to correct position\n        dest[0] = r[0] + b[0];\n        dest[1] = r[1] + b[1];\n        dest[2] = r[2] + b[2];\n\n        return dest;\n    },\n\n    /**\n     * Rotate a 3D vector around the y-axis\n     *\n     * @method rotateVec3Y\n     * @param {Number[]} a The vec3 point to rotate\n     * @param {Number[]} b The origin of the rotation\n     * @param {Number} c The angle of rotation\n     * @param {Number[]} dest The receiving vec3\n     * @returns {Number[]} dest\n     * @static\n     */\n    rotateVec3Y(a, b, c, dest) {\n        const p = [];\n        const r = [];\n\n        //Translate point to the origin\n        p[0] = a[0] - b[0];\n        p[1] = a[1] - b[1];\n        p[2] = a[2] - b[2];\n\n        //perform rotation\n        r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c);\n        r[1] = p[1];\n        r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c);\n\n        //translate to correct position\n        dest[0] = r[0] + b[0];\n        dest[1] = r[1] + b[1];\n        dest[2] = r[2] + b[2];\n\n        return dest;\n    },\n\n    /**\n     * Rotate a 3D vector around the z-axis\n     *\n     * @method rotateVec3Z\n     * @param {Number[]} a The vec3 point to rotate\n     * @param {Number[]} b The origin of the rotation\n     * @param {Number} c The angle of rotation\n     * @param {Number[]} dest The receiving vec3\n     * @returns {Number[]} dest\n     * @static\n     */\n    rotateVec3Z(a, b, c, dest) {\n        const p = [];\n        const r = [];\n\n        //Translate point to the origin\n        p[0] = a[0] - b[0];\n        p[1] = a[1] - b[1];\n        p[2] = a[2] - b[2];\n\n        //perform rotation\n        r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c);\n        r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c);\n        r[2] = p[2];\n\n        //translate to correct position\n        dest[0] = r[0] + b[0];\n        dest[1] = r[1] + b[1];\n        dest[2] = r[2] + b[2];\n\n        return dest;\n    },\n\n    /**\n     * Transforms a four-element vector by a 4x4 projection matrix.\n     *\n     * @method projectVec4\n     * @param {Number[]} p 3D View-space coordinate\n     * @param {Number[]} q 2D Projected coordinate\n     * @returns {Number[]} 2D Projected coordinate\n     * @static\n     */\n    projectVec4(p, q) {\n        const f = 1.0 / p[3];\n        q = q || math.vec2();\n        q[0] = p[0] * f;\n        q[1] = p[1] * f;\n        return q;\n    },\n\n    /**\n     * Unprojects a three-element vector.\n     *\n     * @method unprojectVec3\n     * @param {Number[]} p 3D Projected coordinate\n     * @param {Number[]} viewMat View matrix\n     * @returns {Number[]} projMat Projection matrix\n     * @static\n     */\n    unprojectVec3: ((() => {\n        const mat = new FloatArrayType(16);\n        const mat2 = new FloatArrayType(16);\n        const mat3 = new FloatArrayType(16);\n        return function (p, viewMat, projMat, q) {\n            return this.transformVec3(this.mulMat4(this.inverseMat4(viewMat, mat), this.inverseMat4(projMat, mat2), mat3), p, q)\n        };\n    }))(),\n\n    /**\n     * Linearly interpolates between two 3D vectors.\n     * @method lerpVec3\n     * @static\n     */\n    lerpVec3(t, t1, t2, p1, p2, dest) {\n        const result = dest || math.vec3();\n        const f = (t - t1) / (t2 - t1);\n        result[0] = p1[0] + (f * (p2[0] - p1[0]));\n        result[1] = p1[1] + (f * (p2[1] - p1[1]));\n        result[2] = p1[2] + (f * (p2[2] - p1[2]));\n        return result;\n    },\n\n    /**\n     * Linearly interpolates between two 4x4 matrices.\n     * @method lerpMat4\n     * @static\n     */\n    lerpMat4(t, t1, t2, m1, m2, dest) {\n        const result = dest || math.mat4();\n        const f = (t - t1) / (t2 - t1);\n        result[0] = m1[0] + (f * (m2[0] - m1[0]));\n        result[1] = m1[1] + (f * (m2[1] - m1[1]));\n        result[2] = m1[2] + (f * (m2[2] - m1[2]));\n        result[3] = m1[3] + (f * (m2[3] - m1[3]));\n        result[4] = m1[4] + (f * (m2[4] - m1[4]));\n        result[5] = m1[5] + (f * (m2[5] - m1[5]));\n        result[6] = m1[6] + (f * (m2[6] - m1[6]));\n        result[7] = m1[7] + (f * (m2[7] - m1[7]));\n        result[8] = m1[8] + (f * (m2[8] - m1[8]));\n        result[9] = m1[9] + (f * (m2[9] - m1[9]));\n        result[10] = m1[10] + (f * (m2[10] - m1[10]));\n        result[11] = m1[11] + (f * (m2[11] - m1[11]));\n        result[12] = m1[12] + (f * (m2[12] - m1[12]));\n        result[13] = m1[13] + (f * (m2[13] - m1[13]));\n        result[14] = m1[14] + (f * (m2[14] - m1[14]));\n        result[15] = m1[15] + (f * (m2[15] - m1[15]));\n        return result;\n    },\n\n\n    /**\n     * Flattens a two-dimensional array into a one-dimensional array.\n     *\n     * @method flatten\n     * @static\n     * @param {Array of Arrays} a A 2D array\n     * @returns Flattened 1D array\n     */\n    flatten(a) {\n\n        const result = [];\n\n        let i;\n        let leni;\n        let j;\n        let lenj;\n        let item;\n\n        for (i = 0, leni = a.length; i < leni; i++) {\n            item = a[i];\n            for (j = 0, lenj = item.length; j < lenj; j++) {\n                result.push(item[j]);\n            }\n        }\n\n        return result;\n    },\n\n\n    identityQuaternion(dest = math.vec4()) {\n        dest[0] = 0.0;\n        dest[1] = 0.0;\n        dest[2] = 0.0;\n        dest[3] = 1.0;\n        return dest;\n    },\n\n    /**\n     * Initializes a quaternion from Euler angles.\n     *\n     * @param {Number[]} euler The Euler angles (in degrees).\n     * @param {String} order Euler angle order: \"XYZ\", \"YXZ\", \"ZXY\" etc.\n     * @param {Number[]} [dest] Destination quaternion, created by default.\n     * @returns {Number[]} The quaternion.\n     */\n    eulerToQuaternion(euler, order, dest = math.vec4()) {\n        // http://www.mathworks.com/matlabcentral/fileexchange/\n        // \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n        //\tcontent/SpinCalc.m\n\n        const a = (euler[0] * math.DEGTORAD) / 2;\n        const b = (euler[1] * math.DEGTORAD) / 2;\n        const c = (euler[2] * math.DEGTORAD) / 2;\n\n        const c1 = Math.cos(a);\n        const c2 = Math.cos(b);\n        const c3 = Math.cos(c);\n        const s1 = Math.sin(a);\n        const s2 = Math.sin(b);\n        const s3 = Math.sin(c);\n\n        if (order === 'XYZ') {\n\n            dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n            dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n            dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n            dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n        } else if (order === 'YXZ') {\n\n            dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n            dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n            dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n            dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n\n        } else if (order === 'ZXY') {\n\n            dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n            dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n            dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n            dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n        } else if (order === 'ZYX') {\n\n            dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n            dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n            dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n            dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n\n        } else if (order === 'YZX') {\n\n            dest[0] = s1 * c2 * c3 + c1 * s2 * s3;\n            dest[1] = c1 * s2 * c3 + s1 * c2 * s3;\n            dest[2] = c1 * c2 * s3 - s1 * s2 * c3;\n            dest[3] = c1 * c2 * c3 - s1 * s2 * s3;\n\n        } else if (order === 'XZY') {\n\n            dest[0] = s1 * c2 * c3 - c1 * s2 * s3;\n            dest[1] = c1 * s2 * c3 - s1 * c2 * s3;\n            dest[2] = c1 * c2 * s3 + s1 * s2 * c3;\n            dest[3] = c1 * c2 * c3 + s1 * s2 * s3;\n        }\n\n        return dest;\n    },\n\n    mat4ToQuaternion(m, dest = math.vec4()) {\n        // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n        // Assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n        const m11 = m[0];\n        const m12 = m[4];\n        const m13 = m[8];\n        const m21 = m[1];\n        const m22 = m[5];\n        const m23 = m[9];\n        const m31 = m[2];\n        const m32 = m[6];\n        const m33 = m[10];\n        let s;\n\n        const trace = m11 + m22 + m33;\n\n        if (trace > 0) {\n\n            s = 0.5 / Math.sqrt(trace + 1.0);\n\n            dest[3] = 0.25 / s;\n            dest[0] = (m32 - m23) * s;\n            dest[1] = (m13 - m31) * s;\n            dest[2] = (m21 - m12) * s;\n\n        } else if (m11 > m22 && m11 > m33) {\n\n            s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);\n\n            dest[3] = (m32 - m23) / s;\n            dest[0] = 0.25 * s;\n            dest[1] = (m12 + m21) / s;\n            dest[2] = (m13 + m31) / s;\n\n        } else if (m22 > m33) {\n\n            s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);\n\n            dest[3] = (m13 - m31) / s;\n            dest[0] = (m12 + m21) / s;\n            dest[1] = 0.25 * s;\n            dest[2] = (m23 + m32) / s;\n\n        } else {\n\n            s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);\n\n            dest[3] = (m21 - m12) / s;\n            dest[0] = (m13 + m31) / s;\n            dest[1] = (m23 + m32) / s;\n            dest[2] = 0.25 * s;\n        }\n\n        return dest;\n    },\n\n    vec3PairToQuaternion(u, v, dest = math.vec4()) {\n        const norm_u_norm_v = Math.sqrt(math.dotVec3(u, u) * math.dotVec3(v, v));\n        let real_part = norm_u_norm_v + math.dotVec3(u, v);\n\n        if (real_part < 0.00000001 * norm_u_norm_v) {\n\n            // If u and v are exactly opposite, rotate 180 degrees\n            // around an arbitrary orthogonal axis. Axis normalisation\n            // can happen later, when we normalise the quaternion.\n\n            real_part = 0.0;\n\n            if (Math.abs(u[0]) > Math.abs(u[2])) {\n\n                dest[0] = -u[1];\n                dest[1] = u[0];\n                dest[2] = 0;\n\n            } else {\n                dest[0] = 0;\n                dest[1] = -u[2];\n                dest[2] = u[1];\n            }\n\n        } else {\n\n            // Otherwise, build quaternion the standard way.\n            math.cross3Vec3(u, v, dest);\n        }\n\n        dest[3] = real_part;\n\n        return math.normalizeQuaternion(dest);\n    },\n\n    angleAxisToQuaternion(angleAxis, dest = math.vec4()) {\n        const halfAngle = angleAxis[3] / 2.0;\n        const fsin = Math.sin(halfAngle);\n        dest[0] = fsin * angleAxis[0];\n        dest[1] = fsin * angleAxis[1];\n        dest[2] = fsin * angleAxis[2];\n        dest[3] = Math.cos(halfAngle);\n        return dest;\n    },\n\n    quaternionToEuler: ((() => {\n        const mat = new FloatArrayType(16);\n        return (q, order, dest) => {\n            dest = dest || math.vec3();\n            math.quaternionToRotationMat4(q, mat);\n            math.mat4ToEuler(mat, order, dest);\n            return dest;\n        };\n    }))(),\n\n    mulQuaternions(p, q, dest = math.vec4()) {\n        const p0 = p[0];\n        const p1 = p[1];\n        const p2 = p[2];\n        const p3 = p[3];\n        const q0 = q[0];\n        const q1 = q[1];\n        const q2 = q[2];\n        const q3 = q[3];\n        dest[0] = p3 * q0 + p0 * q3 + p1 * q2 - p2 * q1;\n        dest[1] = p3 * q1 + p1 * q3 + p2 * q0 - p0 * q2;\n        dest[2] = p3 * q2 + p2 * q3 + p0 * q1 - p1 * q0;\n        dest[3] = p3 * q3 - p0 * q0 - p1 * q1 - p2 * q2;\n        return dest;\n    },\n\n    vec3ApplyQuaternion(q, vec, dest = math.vec3()) {\n        const x = vec[0];\n        const y = vec[1];\n        const z = vec[2];\n\n        const qx = q[0];\n        const qy = q[1];\n        const qz = q[2];\n        const qw = q[3];\n\n        // calculate quat * vector\n\n        const ix = qw * x + qy * z - qz * y;\n        const iy = qw * y + qz * x - qx * z;\n        const iz = qw * z + qx * y - qy * x;\n        const iw = -qx * x - qy * y - qz * z;\n\n        // calculate result * inverse quat\n\n        dest[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;\n        dest[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;\n        dest[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;\n\n        return dest;\n    },\n\n    quaternionToMat4(q, dest) {\n\n        dest = math.identityMat4(dest);\n\n        const q0 = q[0];  //x\n        const q1 = q[1];  //y\n        const q2 = q[2];  //z\n        const q3 = q[3];  //w\n\n        const tx = 2.0 * q0;\n        const ty = 2.0 * q1;\n        const tz = 2.0 * q2;\n\n        const twx = tx * q3;\n        const twy = ty * q3;\n        const twz = tz * q3;\n\n        const txx = tx * q0;\n        const txy = ty * q0;\n        const txz = tz * q0;\n\n        const tyy = ty * q1;\n        const tyz = tz * q1;\n        const tzz = tz * q2;\n\n        dest[0] = 1.0 - (tyy + tzz);\n        dest[1] = txy + twz;\n        dest[2] = txz - twy;\n\n        dest[4] = txy - twz;\n        dest[5] = 1.0 - (txx + tzz);\n        dest[6] = tyz + twx;\n\n        dest[8] = txz + twy;\n        dest[9] = tyz - twx;\n\n        dest[10] = 1.0 - (txx + tyy);\n\n        return dest;\n    },\n\n    quaternionToRotationMat4(q, m) {\n        const x = q[0];\n        const y = q[1];\n        const z = q[2];\n        const w = q[3];\n\n        const x2 = x + x;\n        const y2 = y + y;\n        const z2 = z + z;\n        const xx = x * x2;\n        const xy = x * y2;\n        const xz = x * z2;\n        const yy = y * y2;\n        const yz = y * z2;\n        const zz = z * z2;\n        const wx = w * x2;\n        const wy = w * y2;\n        const wz = w * z2;\n\n        m[0] = 1 - (yy + zz);\n        m[4] = xy - wz;\n        m[8] = xz + wy;\n\n        m[1] = xy + wz;\n        m[5] = 1 - (xx + zz);\n        m[9] = yz - wx;\n\n        m[2] = xz - wy;\n        m[6] = yz + wx;\n        m[10] = 1 - (xx + yy);\n\n        // last column\n        m[3] = 0;\n        m[7] = 0;\n        m[11] = 0;\n\n        // bottom row\n        m[12] = 0;\n        m[13] = 0;\n        m[14] = 0;\n        m[15] = 1;\n\n        return m;\n    },\n\n    normalizeQuaternion(q, dest = q) {\n        const len = math.lenVec4([q[0], q[1], q[2], q[3]]);\n        dest[0] = q[0] / len;\n        dest[1] = q[1] / len;\n        dest[2] = q[2] / len;\n        dest[3] = q[3] / len;\n        return dest;\n    },\n\n    conjugateQuaternion(q, dest = q) {\n        dest[0] = -q[0];\n        dest[1] = -q[1];\n        dest[2] = -q[2];\n        dest[3] = q[3];\n        return dest;\n    },\n\n    inverseQuaternion(q, dest) {\n        return math.normalizeQuaternion(math.conjugateQuaternion(q, dest));\n    },\n\n    quaternionToAngleAxis(q, angleAxis = math.vec4()) {\n        q = math.normalizeQuaternion(q, tempVec4$4);\n        const q3 = q[3];\n        const angle = 2 * Math.acos(q3);\n        const s = Math.sqrt(1 - q3 * q3);\n        if (s < 0.001) { // test to avoid divide by zero, s is always positive due to sqrt\n            angleAxis[0] = q[0];\n            angleAxis[1] = q[1];\n            angleAxis[2] = q[2];\n        } else {\n            angleAxis[0] = q[0] / s;\n            angleAxis[1] = q[1] / s;\n            angleAxis[2] = q[2] / s;\n        }\n        angleAxis[3] = angle; // * 57.295779579;\n        return angleAxis;\n    },\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Boundaries\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns a new, uninitialized 3D axis-aligned bounding box.\n     *\n     * @private\n     */\n    AABB3(values) {\n        return new FloatArrayType(values || 6);\n    },\n\n    /**\n     * Returns a new, uninitialized 2D axis-aligned bounding box.\n     *\n     * @private\n     */\n    AABB2(values) {\n        return new FloatArrayType(values || 4);\n    },\n\n    /**\n     * Returns a new, uninitialized 3D oriented bounding box (OBB).\n     *\n     * @private\n     */\n    OBB3(values) {\n        return new FloatArrayType(values || 32);\n    },\n\n    /**\n     * Returns a new, uninitialized 2D oriented bounding box (OBB).\n     *\n     * @private\n     */\n    OBB2(values) {\n        return new FloatArrayType(values || 16);\n    },\n\n    /** Returns a new 3D bounding sphere */\n    Sphere3(x, y, z, r) {\n        return new FloatArrayType([x, y, z, r]);\n    },\n\n    /**\n     * Transforms an OBB3 by a 4x4 matrix.\n     *\n     * @private\n     */\n    transformOBB3(m, p, p2 = p) {\n        let i;\n        const len = p.length;\n\n        let x;\n        let y;\n        let z;\n\n        const m0 = m[0];\n        const m1 = m[1];\n        const m2 = m[2];\n        const m3 = m[3];\n        const m4 = m[4];\n        const m5 = m[5];\n        const m6 = m[6];\n        const m7 = m[7];\n        const m8 = m[8];\n        const m9 = m[9];\n        const m10 = m[10];\n        const m11 = m[11];\n        const m12 = m[12];\n        const m13 = m[13];\n        const m14 = m[14];\n        const m15 = m[15];\n\n        for (i = 0; i < len; i += 4) {\n\n            x = p[i + 0];\n            y = p[i + 1];\n            z = p[i + 2];\n\n            p2[i + 0] = (m0 * x) + (m4 * y) + (m8 * z) + m12;\n            p2[i + 1] = (m1 * x) + (m5 * y) + (m9 * z) + m13;\n            p2[i + 2] = (m2 * x) + (m6 * y) + (m10 * z) + m14;\n            p2[i + 3] = (m3 * x) + (m7 * y) + (m11 * z) + m15;\n        }\n\n        return p2;\n    },\n\n    /** Returns true if the first AABB contains the second AABB.\n     * @param aabb1\n     * @param aabb2\n     * @returns {Boolean}\n     */\n    containsAABB3: function (aabb1, aabb2) {\n        const result = (\n            aabb1[0] <= aabb2[0] && aabb2[3] <= aabb1[3] &&\n            aabb1[1] <= aabb2[1] && aabb2[4] <= aabb1[4] &&\n            aabb1[2] <= aabb2[2] && aabb2[5] <= aabb1[5]);\n        return result;\n    },\n\n\n    /**\n     * Gets the diagonal size of an AABB3 given as minima and maxima.\n     *\n     * @private\n     */\n    getAABB3Diag: ((() => {\n\n        const min = new FloatArrayType(3);\n        const max = new FloatArrayType(3);\n        const tempVec3 = new FloatArrayType(3);\n\n        return aabb => {\n\n            min[0] = aabb[0];\n            min[1] = aabb[1];\n            min[2] = aabb[2];\n\n            max[0] = aabb[3];\n            max[1] = aabb[4];\n            max[2] = aabb[5];\n\n            math.subVec3(max, min, tempVec3);\n\n            return Math.abs(math.lenVec3(tempVec3));\n        };\n    }))(),\n\n    /**\n     * Get a diagonal boundary size that is symmetrical about the given point.\n     *\n     * @private\n     */\n    getAABB3DiagPoint: ((() => {\n\n        const min = new FloatArrayType(3);\n        const max = new FloatArrayType(3);\n        const tempVec3 = new FloatArrayType(3);\n\n        return (aabb, p) => {\n\n            min[0] = aabb[0];\n            min[1] = aabb[1];\n            min[2] = aabb[2];\n\n            max[0] = aabb[3];\n            max[1] = aabb[4];\n            max[2] = aabb[5];\n\n            const diagVec = math.subVec3(max, min, tempVec3);\n\n            const xneg = p[0] - aabb[0];\n            const xpos = aabb[3] - p[0];\n            const yneg = p[1] - aabb[1];\n            const ypos = aabb[4] - p[1];\n            const zneg = p[2] - aabb[2];\n            const zpos = aabb[5] - p[2];\n\n            diagVec[0] += (xneg > xpos) ? xneg : xpos;\n            diagVec[1] += (yneg > ypos) ? yneg : ypos;\n            diagVec[2] += (zneg > zpos) ? zneg : zpos;\n\n            return Math.abs(math.lenVec3(diagVec));\n        };\n    }))(),\n\n    /**\n     * Gets the area of an AABB.\n     *\n     * @private\n     */\n    getAABB3Area(aabb) {\n        const width = (aabb[3] - aabb[0]);\n        const height = (aabb[4] - aabb[1]);\n        const depth = (aabb[5] - aabb[2]);\n        return (width * height * depth);\n    },\n\n    /**\n     * Gets the center of an AABB.\n     *\n     * @private\n     */\n    getAABB3Center(aabb, dest) {\n        const r = dest || math.vec3();\n\n        r[0] = (aabb[0] + aabb[3]) / 2;\n        r[1] = (aabb[1] + aabb[4]) / 2;\n        r[2] = (aabb[2] + aabb[5]) / 2;\n\n        return r;\n    },\n\n    /**\n     * Gets the center of a 2D AABB.\n     *\n     * @private\n     */\n    getAABB2Center(aabb, dest) {\n        const r = dest || math.vec2();\n\n        r[0] = (aabb[2] + aabb[0]) / 2;\n        r[1] = (aabb[3] + aabb[1]) / 2;\n\n        return r;\n    },\n\n    /**\n     * Collapses a 3D axis-aligned boundary, ready to expand to fit 3D points.\n     * Creates new AABB if none supplied.\n     *\n     * @private\n     */\n    collapseAABB3(aabb = math.AABB3()) {\n        aabb[0] = math.MAX_DOUBLE;\n        aabb[1] = math.MAX_DOUBLE;\n        aabb[2] = math.MAX_DOUBLE;\n        aabb[3] = math.MIN_DOUBLE;\n        aabb[4] = math.MIN_DOUBLE;\n        aabb[5] = math.MIN_DOUBLE;\n\n        return aabb;\n    },\n\n    /**\n     * Converts an axis-aligned 3D boundary into an oriented boundary consisting of\n     * an array of eight 3D positions, one for each corner of the boundary.\n     *\n     * @private\n     */\n    AABB3ToOBB3(aabb, obb = math.OBB3()) {\n        obb[0] = aabb[0];\n        obb[1] = aabb[1];\n        obb[2] = aabb[2];\n        obb[3] = 1;\n\n        obb[4] = aabb[3];\n        obb[5] = aabb[1];\n        obb[6] = aabb[2];\n        obb[7] = 1;\n\n        obb[8] = aabb[3];\n        obb[9] = aabb[4];\n        obb[10] = aabb[2];\n        obb[11] = 1;\n\n        obb[12] = aabb[0];\n        obb[13] = aabb[4];\n        obb[14] = aabb[2];\n        obb[15] = 1;\n\n        obb[16] = aabb[0];\n        obb[17] = aabb[1];\n        obb[18] = aabb[5];\n        obb[19] = 1;\n\n        obb[20] = aabb[3];\n        obb[21] = aabb[1];\n        obb[22] = aabb[5];\n        obb[23] = 1;\n\n        obb[24] = aabb[3];\n        obb[25] = aabb[4];\n        obb[26] = aabb[5];\n        obb[27] = 1;\n\n        obb[28] = aabb[0];\n        obb[29] = aabb[4];\n        obb[30] = aabb[5];\n        obb[31] = 1;\n\n        return obb;\n    },\n\n    /**\n     * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array.\n     *\n     * @private\n     */\n    positions3ToAABB3: ((() => {\n\n        const p = new FloatArrayType(3);\n\n        return (positions, aabb, positionsDecodeMatrix) => {\n            aabb = aabb || math.AABB3();\n\n            let xmin = math.MAX_DOUBLE;\n            let ymin = math.MAX_DOUBLE;\n            let zmin = math.MAX_DOUBLE;\n            let xmax = math.MIN_DOUBLE;\n            let ymax = math.MIN_DOUBLE;\n            let zmax = math.MIN_DOUBLE;\n\n            let x;\n            let y;\n            let z;\n\n            for (let i = 0, len = positions.length; i < len; i += 3) {\n\n                if (positionsDecodeMatrix) {\n\n                    p[0] = positions[i + 0];\n                    p[1] = positions[i + 1];\n                    p[2] = positions[i + 2];\n\n                    math.decompressPosition(p, positionsDecodeMatrix, p);\n\n                    x = p[0];\n                    y = p[1];\n                    z = p[2];\n\n                } else {\n                    x = positions[i + 0];\n                    y = positions[i + 1];\n                    z = positions[i + 2];\n                }\n\n                if (x < xmin) {\n                    xmin = x;\n                }\n\n                if (y < ymin) {\n                    ymin = y;\n                }\n\n                if (z < zmin) {\n                    zmin = z;\n                }\n\n                if (x > xmax) {\n                    xmax = x;\n                }\n\n                if (y > ymax) {\n                    ymax = y;\n                }\n\n                if (z > zmax) {\n                    zmax = z;\n                }\n            }\n\n            aabb[0] = xmin;\n            aabb[1] = ymin;\n            aabb[2] = zmin;\n            aabb[3] = xmax;\n            aabb[4] = ymax;\n            aabb[5] = zmax;\n\n            return aabb;\n        };\n    }))(),\n\n    /**\n     * Finds the minimum axis-aligned 3D boundary enclosing the homogeneous 3D points (x,y,z,w) given in a flattened array.\n     *\n     * @private\n     */\n    OBB3ToAABB3(obb, aabb = math.AABB3()) {\n        let xmin = math.MAX_DOUBLE;\n        let ymin = math.MAX_DOUBLE;\n        let zmin = math.MAX_DOUBLE;\n        let xmax = math.MIN_DOUBLE;\n        let ymax = math.MIN_DOUBLE;\n        let zmax = math.MIN_DOUBLE;\n\n        let x;\n        let y;\n        let z;\n\n        for (let i = 0, len = obb.length; i < len; i += 4) {\n\n            x = obb[i + 0];\n            y = obb[i + 1];\n            z = obb[i + 2];\n\n            if (x < xmin) {\n                xmin = x;\n            }\n\n            if (y < ymin) {\n                ymin = y;\n            }\n\n            if (z < zmin) {\n                zmin = z;\n            }\n\n            if (x > xmax) {\n                xmax = x;\n            }\n\n            if (y > ymax) {\n                ymax = y;\n            }\n\n            if (z > zmax) {\n                zmax = z;\n            }\n        }\n\n        aabb[0] = xmin;\n        aabb[1] = ymin;\n        aabb[2] = zmin;\n        aabb[3] = xmax;\n        aabb[4] = ymax;\n        aabb[5] = zmax;\n\n        return aabb;\n    },\n\n    /**\n     * Finds the minimum axis-aligned 3D boundary enclosing the given 3D points.\n     *\n     * @private\n     */\n    points3ToAABB3(points, aabb = math.AABB3()) {\n        let xmin = math.MAX_DOUBLE;\n        let ymin = math.MAX_DOUBLE;\n        let zmin = math.MAX_DOUBLE;\n        let xmax = math.MIN_DOUBLE;\n        let ymax = math.MIN_DOUBLE;\n        let zmax = math.MIN_DOUBLE;\n\n        let x;\n        let y;\n        let z;\n\n        for (let i = 0, len = points.length; i < len; i++) {\n\n            x = points[i][0];\n            y = points[i][1];\n            z = points[i][2];\n\n            if (x < xmin) {\n                xmin = x;\n            }\n\n            if (y < ymin) {\n                ymin = y;\n            }\n\n            if (z < zmin) {\n                zmin = z;\n            }\n\n            if (x > xmax) {\n                xmax = x;\n            }\n\n            if (y > ymax) {\n                ymax = y;\n            }\n\n            if (z > zmax) {\n                zmax = z;\n            }\n        }\n\n        aabb[0] = xmin;\n        aabb[1] = ymin;\n        aabb[2] = zmin;\n        aabb[3] = xmax;\n        aabb[4] = ymax;\n        aabb[5] = zmax;\n\n        return aabb;\n    },\n\n    /**\n     * Finds the minimum boundary sphere enclosing the given 3D points.\n     *\n     * @private\n     */\n    points3ToSphere3: ((() => {\n\n        const tempVec3 = new FloatArrayType(3);\n\n        return (points, sphere) => {\n\n            sphere = sphere || math.vec4();\n\n            let x = 0;\n            let y = 0;\n            let z = 0;\n\n            let i;\n            const numPoints = points.length;\n\n            for (i = 0; i < numPoints; i++) {\n                x += points[i][0];\n                y += points[i][1];\n                z += points[i][2];\n            }\n\n            sphere[0] = x / numPoints;\n            sphere[1] = y / numPoints;\n            sphere[2] = z / numPoints;\n\n            let radius = 0;\n            let dist;\n\n            for (i = 0; i < numPoints; i++) {\n\n                dist = Math.abs(math.lenVec3(math.subVec3(points[i], sphere, tempVec3)));\n\n                if (dist > radius) {\n                    radius = dist;\n                }\n            }\n\n            sphere[3] = radius;\n\n            return sphere;\n        };\n    }))(),\n\n    /**\n     * Finds the minimum boundary sphere enclosing the given 3D positions.\n     *\n     * @private\n     */\n    positions3ToSphere3: ((() => {\n\n        const tempVec3a = new FloatArrayType(3);\n        const tempVec3b = new FloatArrayType(3);\n\n        return (positions, sphere) => {\n\n            sphere = sphere || math.vec4();\n\n            let x = 0;\n            let y = 0;\n            let z = 0;\n\n            let i;\n            const lenPositions = positions.length;\n            let radius = 0;\n\n            for (i = 0; i < lenPositions; i += 3) {\n                x += positions[i];\n                y += positions[i + 1];\n                z += positions[i + 2];\n            }\n\n            const numPositions = lenPositions / 3;\n\n            sphere[0] = x / numPositions;\n            sphere[1] = y / numPositions;\n            sphere[2] = z / numPositions;\n\n            let dist;\n\n            for (i = 0; i < lenPositions; i += 3) {\n\n                tempVec3a[0] = positions[i];\n                tempVec3a[1] = positions[i + 1];\n                tempVec3a[2] = positions[i + 2];\n\n                dist = Math.abs(math.lenVec3(math.subVec3(tempVec3a, sphere, tempVec3b)));\n\n                if (dist > radius) {\n                    radius = dist;\n                }\n            }\n\n            sphere[3] = radius;\n\n            return sphere;\n        };\n    }))(),\n\n    /**\n     * Finds the minimum boundary sphere enclosing the given 3D points.\n     *\n     * @private\n     */\n    OBB3ToSphere3: ((() => {\n\n        const point = new FloatArrayType(3);\n        const tempVec3 = new FloatArrayType(3);\n\n        return (points, sphere) => {\n\n            sphere = sphere || math.vec4();\n\n            let x = 0;\n            let y = 0;\n            let z = 0;\n\n            let i;\n            const lenPoints = points.length;\n            const numPoints = lenPoints / 4;\n\n            for (i = 0; i < lenPoints; i += 4) {\n                x += points[i + 0];\n                y += points[i + 1];\n                z += points[i + 2];\n            }\n\n            sphere[0] = x / numPoints;\n            sphere[1] = y / numPoints;\n            sphere[2] = z / numPoints;\n\n            let radius = 0;\n            let dist;\n\n            for (i = 0; i < lenPoints; i += 4) {\n\n                point[0] = points[i + 0];\n                point[1] = points[i + 1];\n                point[2] = points[i + 2];\n\n                dist = Math.abs(math.lenVec3(math.subVec3(point, sphere, tempVec3)));\n\n                if (dist > radius) {\n                    radius = dist;\n                }\n            }\n\n            sphere[3] = radius;\n\n            return sphere;\n        };\n    }))(),\n\n    /**\n     * Gets the center of a bounding sphere.\n     *\n     * @private\n     */\n    getSphere3Center(sphere, dest = math.vec3()) {\n        dest[0] = sphere[0];\n        dest[1] = sphere[1];\n        dest[2] = sphere[2];\n\n        return dest;\n    },\n\n    /**\n     * Gets the 3D center of the given flat array of 3D positions.\n     *\n     * @private\n     */\n    getPositionsCenter(positions, center = math.vec3()) {\n        let xCenter = 0;\n        let yCenter = 0;\n        let zCenter = 0;\n        for (var i = 0, len = positions.length; i < len; i += 3) {\n            xCenter += positions[i + 0];\n            yCenter += positions[i + 1];\n            zCenter += positions[i + 2];\n        }\n        const numPositions = positions.length / 3;\n        center[0] = xCenter / numPositions;\n        center[1] = yCenter / numPositions;\n        center[2] = zCenter / numPositions;\n        return center;\n    },\n\n    /**\n     * Expands the first axis-aligned 3D boundary to enclose the second, if required.\n     *\n     * @private\n     */\n    expandAABB3(aabb1, aabb2) {\n\n        if (aabb1[0] > aabb2[0]) {\n            aabb1[0] = aabb2[0];\n        }\n\n        if (aabb1[1] > aabb2[1]) {\n            aabb1[1] = aabb2[1];\n        }\n\n        if (aabb1[2] > aabb2[2]) {\n            aabb1[2] = aabb2[2];\n        }\n\n        if (aabb1[3] < aabb2[3]) {\n            aabb1[3] = aabb2[3];\n        }\n\n        if (aabb1[4] < aabb2[4]) {\n            aabb1[4] = aabb2[4];\n        }\n\n        if (aabb1[5] < aabb2[5]) {\n            aabb1[5] = aabb2[5];\n        }\n\n        return aabb1;\n    },\n\n    /**\n     * Expands an axis-aligned 3D boundary to enclose the given point, if needed.\n     *\n     * @private\n     */\n    expandAABB3Point3(aabb, p) {\n\n        if (aabb[0] > p[0]) {\n            aabb[0] = p[0];\n        }\n\n        if (aabb[1] > p[1]) {\n            aabb[1] = p[1];\n        }\n\n        if (aabb[2] > p[2]) {\n            aabb[2] = p[2];\n        }\n\n        if (aabb[3] < p[0]) {\n            aabb[3] = p[0];\n        }\n\n        if (aabb[4] < p[1]) {\n            aabb[4] = p[1];\n        }\n\n        if (aabb[5] < p[2]) {\n            aabb[5] = p[2];\n        }\n\n        return aabb;\n    },\n\n    /**\n     * Expands an axis-aligned 3D boundary to enclose the given points, if needed.\n     *\n     * @private\n     */\n    expandAABB3Points3(aabb, positions) {\n        var x;\n        var y;\n        var z;\n        for (var i = 0, len = positions.length; i < len; i += 3) {\n            x = positions[i];\n            y = positions[i + 1];\n            z = positions[i + 2];\n            if (aabb[0] > x) {\n                aabb[0] = x;\n            }\n            if (aabb[1] > y) {\n                aabb[1] = y;\n            }\n            if (aabb[2] > z) {\n                aabb[2] = z;\n            }\n            if (aabb[3] < x) {\n                aabb[3] = x;\n            }\n            if (aabb[4] < y) {\n                aabb[4] = y;\n            }\n            if (aabb[5] < z) {\n                aabb[5] = z;\n            }\n        }\n        return aabb;\n    },\n\n    /**\n     * Collapses a 2D axis-aligned boundary, ready to expand to fit 2D points.\n     * Creates new AABB if none supplied.\n     *\n     * @private\n     */\n    collapseAABB2(aabb = math.AABB2()) {\n        aabb[0] = math.MAX_DOUBLE;\n        aabb[1] = math.MAX_DOUBLE;\n        aabb[2] = math.MIN_DOUBLE;\n        aabb[3] = math.MIN_DOUBLE;\n\n        return aabb;\n    },\n\n    point3AABB3Intersect(aabb, p) {\n        return aabb[0] > p[0] || aabb[3] < p[0] || aabb[1] > p[1] || aabb[4] < p[1] || aabb[2] > p[2] || aabb[5] < p[2];\n    },\n\n    point3AABB3AbsoluteIntersect(aabb, p) {\n        return (\n            aabb[0] <= p[0] && aabb[3] >= p[0] &&\n            aabb[1] <= p[1] && aabb[4] >= p[1] &&\n            aabb[2] <= p[2] && aabb[5] >= p[2]\n        );\n    },\n\n    /**\n     *\n     * @param dir\n     * @param constant\n     * @param aabb\n     * @returns {number}\n     */\n    planeAABB3Intersect(dir, constant, aabb) {\n        let min, max;\n        if (dir[0] > 0) {\n            min = dir[0] * aabb[0];\n            max = dir[0] * aabb[3];\n        } else {\n            min = dir[0] * aabb[3];\n            max = dir[0] * aabb[0];\n        }\n        if (dir[1] > 0) {\n            min += dir[1] * aabb[1];\n            max += dir[1] * aabb[4];\n        } else {\n            min += dir[1] * aabb[4];\n            max += dir[1] * aabb[1];\n        }\n        if (dir[2] > 0) {\n            min += dir[2] * aabb[2];\n            max += dir[2] * aabb[5];\n        } else {\n            min += dir[2] * aabb[5];\n            max += dir[2] * aabb[2];\n        }\n        const outside = (min <= -constant) && (max <= -constant);\n        if (outside) {\n            return -1;\n        }\n\n        const inside = (min >= -constant) && (max >= -constant);\n        if (inside) {\n            return 1;\n        }\n\n        return 0;\n    },\n\n    /**\n     * Finds the minimum 2D projected axis-aligned boundary enclosing the given 3D points.\n     *\n     * @private\n     */\n    OBB3ToAABB2(points, aabb = math.AABB2()) {\n        let xmin = math.MAX_DOUBLE;\n        let ymin = math.MAX_DOUBLE;\n        let xmax = math.MIN_DOUBLE;\n        let ymax = math.MIN_DOUBLE;\n\n        let x;\n        let y;\n        let w;\n        let f;\n\n        for (let i = 0, len = points.length; i < len; i += 4) {\n\n            x = points[i + 0];\n            y = points[i + 1];\n            w = points[i + 3] || 1.0;\n\n            f = 1.0 / w;\n\n            x *= f;\n            y *= f;\n\n            if (x < xmin) {\n                xmin = x;\n            }\n\n            if (y < ymin) {\n                ymin = y;\n            }\n\n            if (x > xmax) {\n                xmax = x;\n            }\n\n            if (y > ymax) {\n                ymax = y;\n            }\n        }\n\n        aabb[0] = xmin;\n        aabb[1] = ymin;\n        aabb[2] = xmax;\n        aabb[3] = ymax;\n\n        return aabb;\n    },\n\n    /**\n     * Expands the first axis-aligned 2D boundary to enclose the second, if required.\n     *\n     * @private\n     */\n    expandAABB2(aabb1, aabb2) {\n\n        if (aabb1[0] > aabb2[0]) {\n            aabb1[0] = aabb2[0];\n        }\n\n        if (aabb1[1] > aabb2[1]) {\n            aabb1[1] = aabb2[1];\n        }\n\n        if (aabb1[2] < aabb2[2]) {\n            aabb1[2] = aabb2[2];\n        }\n\n        if (aabb1[3] < aabb2[3]) {\n            aabb1[3] = aabb2[3];\n        }\n\n        return aabb1;\n    },\n\n    /**\n     * Expands an axis-aligned 2D boundary to enclose the given point, if required.\n     *\n     * @private\n     */\n    expandAABB2Point2(aabb, p) {\n\n        if (aabb[0] > p[0]) {\n            aabb[0] = p[0];\n        }\n\n        if (aabb[1] > p[1]) {\n            aabb[1] = p[1];\n        }\n\n        if (aabb[2] < p[0]) {\n            aabb[2] = p[0];\n        }\n\n        if (aabb[3] < p[1]) {\n            aabb[3] = p[1];\n        }\n\n        return aabb;\n    },\n\n    AABB2ToCanvas(aabb, canvasWidth, canvasHeight, aabb2 = aabb) {\n        const xmin = (aabb[0] + 1.0) * 0.5;\n        const ymin = (aabb[1] + 1.0) * 0.5;\n        const xmax = (aabb[2] + 1.0) * 0.5;\n        const ymax = (aabb[3] + 1.0) * 0.5;\n\n        aabb2[0] = Math.floor(xmin * canvasWidth);\n        aabb2[1] = canvasHeight - Math.floor(ymax * canvasHeight);\n        aabb2[2] = Math.floor(xmax * canvasWidth);\n        aabb2[3] = canvasHeight - Math.floor(ymin * canvasHeight);\n\n        return aabb2;\n    },\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Curves\n    //------------------------------------------------------------------------------------------------------------------\n\n    tangentQuadraticBezier(t, p0, p1, p2) {\n        return 2 * (1 - t) * (p1 - p0) + 2 * t * (p2 - p1);\n    },\n\n    tangentQuadraticBezier3(t, p0, p1, p2, p3) {\n        return -3 * p0 * (1 - t) * (1 - t) +\n            3 * p1 * (1 - t) * (1 - t) - 6 * t * p1 * (1 - t) +\n            6 * t * p2 * (1 - t) - 3 * t * t * p2 +\n            3 * t * t * p3;\n    },\n\n    tangentSpline(t) {\n        const h00 = 6 * t * t - 6 * t;\n        const h10 = 3 * t * t - 4 * t + 1;\n        const h01 = -6 * t * t + 6 * t;\n        const h11 = 3 * t * t - 2 * t;\n        return h00 + h10 + h01 + h11;\n    },\n\n    catmullRomInterpolate(p0, p1, p2, p3, t) {\n        const v0 = (p2 - p0) * 0.5;\n        const v1 = (p3 - p1) * 0.5;\n        const t2 = t * t;\n        const t3 = t * t2;\n        return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;\n    },\n\n// Bezier Curve formulii from http://en.wikipedia.org/wiki/B%C3%A9zier_curve\n\n// Quad Bezier Functions\n\n    b2p0(t, p) {\n        const k = 1 - t;\n        return k * k * p;\n\n    },\n\n    b2p1(t, p) {\n        return 2 * (1 - t) * t * p;\n    },\n\n    b2p2(t, p) {\n        return t * t * p;\n    },\n\n    b2(t, p0, p1, p2) {\n        return this.b2p0(t, p0) + this.b2p1(t, p1) + this.b2p2(t, p2);\n    },\n\n// Cubic Bezier Functions\n\n    b3p0(t, p) {\n        const k = 1 - t;\n        return k * k * k * p;\n    },\n\n    b3p1(t, p) {\n        const k = 1 - t;\n        return 3 * k * k * t * p;\n    },\n\n    b3p2(t, p) {\n        const k = 1 - t;\n        return 3 * k * t * t * p;\n    },\n\n    b3p3(t, p) {\n        return t * t * t * p;\n    },\n\n    b3(t, p0, p1, p2, p3) {\n        return this.b3p0(t, p0) + this.b3p1(t, p1) + this.b3p2(t, p2) + this.b3p3(t, p3);\n    },\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Geometry\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Calculates the normal vector of a triangle.\n     *\n     * @private\n     */\n    triangleNormal(a, b, c, normal = math.vec3()) {\n        const p1x = b[0] - a[0];\n        const p1y = b[1] - a[1];\n        const p1z = b[2] - a[2];\n\n        const p2x = c[0] - a[0];\n        const p2y = c[1] - a[1];\n        const p2z = c[2] - a[2];\n\n        const p3x = p1y * p2z - p1z * p2y;\n        const p3y = p1z * p2x - p1x * p2z;\n        const p3z = p1x * p2y - p1y * p2x;\n\n        const mag = Math.sqrt(p3x * p3x + p3y * p3y + p3z * p3z);\n        if (mag === 0) {\n            normal[0] = 0;\n            normal[1] = 0;\n            normal[2] = 0;\n        } else {\n            normal[0] = p3x / mag;\n            normal[1] = p3y / mag;\n            normal[2] = p3z / mag;\n        }\n\n        return normal\n    },\n\n    /**\n     * Finds the intersection of a 3D ray with a 3D triangle.\n     *\n     * @private\n     */\n    rayTriangleIntersect: ((() => {\n\n        const tempVec3 = new FloatArrayType(3);\n        const tempVec3b = new FloatArrayType(3);\n        const tempVec3c = new FloatArrayType(3);\n        const tempVec3d = new FloatArrayType(3);\n        const tempVec3e = new FloatArrayType(3);\n\n        return (origin, dir, a, b, c, isect) => {\n\n            isect = isect || math.vec3();\n\n            const EPSILON = 0.000001;\n\n            const edge1 = math.subVec3(b, a, tempVec3);\n            const edge2 = math.subVec3(c, a, tempVec3b);\n\n            const pvec = math.cross3Vec3(dir, edge2, tempVec3c);\n            const det = math.dotVec3(edge1, pvec);\n            if (det < EPSILON) {\n                return null;\n            }\n\n            const tvec = math.subVec3(origin, a, tempVec3d);\n            const u = math.dotVec3(tvec, pvec);\n            if (u < 0 || u > det) {\n                return null;\n            }\n\n            const qvec = math.cross3Vec3(tvec, edge1, tempVec3e);\n            const v = math.dotVec3(dir, qvec);\n            if (v < 0 || u + v > det) {\n                return null;\n            }\n\n            const t = math.dotVec3(edge2, qvec) / det;\n            isect[0] = origin[0] + t * dir[0];\n            isect[1] = origin[1] + t * dir[1];\n            isect[2] = origin[2] + t * dir[2];\n\n            return isect;\n        };\n    }))(),\n\n    /**\n     * Finds the intersection of a 3D ray with a plane defined by 3 points.\n     *\n     * @private\n     */\n    rayPlaneIntersect: ((() => {\n\n        const tempVec3 = new FloatArrayType(3);\n        const tempVec3b = new FloatArrayType(3);\n        const tempVec3c = new FloatArrayType(3);\n        const tempVec3d = new FloatArrayType(3);\n\n        return (origin, dir, a, b, c, isect) => {\n\n            isect = isect || math.vec3();\n\n            dir = math.normalizeVec3(dir, tempVec3);\n\n            const edge1 = math.subVec3(b, a, tempVec3b);\n            const edge2 = math.subVec3(c, a, tempVec3c);\n\n            const n = math.cross3Vec3(edge1, edge2, tempVec3d);\n            math.normalizeVec3(n, n);\n\n            const d = -math.dotVec3(a, n);\n\n            const t = -(math.dotVec3(origin, n) + d) / math.dotVec3(dir, n);\n\n            isect[0] = origin[0] + t * dir[0];\n            isect[1] = origin[1] + t * dir[1];\n            isect[2] = origin[2] + t * dir[2];\n\n            return isect;\n        };\n    }))(),\n\n    /**\n     * Gets barycentric coordinates from cartesian coordinates within a triangle.\n     * Gets barycentric coordinates from cartesian coordinates within a triangle.\n     *\n     * @private\n     */\n    cartesianToBarycentric: ((() => {\n\n        const tempVec3 = new FloatArrayType(3);\n        const tempVec3b = new FloatArrayType(3);\n        const tempVec3c = new FloatArrayType(3);\n\n        return (cartesian, a, b, c, dest) => {\n\n            const v0 = math.subVec3(c, a, tempVec3);\n            const v1 = math.subVec3(b, a, tempVec3b);\n            const v2 = math.subVec3(cartesian, a, tempVec3c);\n\n            const dot00 = math.dotVec3(v0, v0);\n            const dot01 = math.dotVec3(v0, v1);\n            const dot02 = math.dotVec3(v0, v2);\n            const dot11 = math.dotVec3(v1, v1);\n            const dot12 = math.dotVec3(v1, v2);\n\n            const denom = (dot00 * dot11 - dot01 * dot01);\n\n            // Colinear or singular triangle\n\n            if (denom === 0) {\n\n                // Arbitrary location outside of triangle\n\n                return null;\n            }\n\n            const invDenom = 1 / denom;\n\n            const u = (dot11 * dot02 - dot01 * dot12) * invDenom;\n            const v = (dot00 * dot12 - dot01 * dot02) * invDenom;\n\n            dest[0] = 1 - u - v;\n            dest[1] = v;\n            dest[2] = u;\n\n            return dest;\n        };\n    }))(),\n\n    /**\n     * Returns true if the given barycentric coordinates are within their triangle.\n     *\n     * @private\n     */\n    barycentricInsideTriangle(bary) {\n\n        const v = bary[1];\n        const u = bary[2];\n\n        return (u >= 0) && (v >= 0) && (u + v < 1);\n    },\n\n    /**\n     * Gets cartesian coordinates from barycentric coordinates within a triangle.\n     *\n     * @private\n     */\n    barycentricToCartesian(bary, a, b, c, cartesian = math.vec3()) {\n        const u = bary[0];\n        const v = bary[1];\n        const w = bary[2];\n\n        cartesian[0] = a[0] * u + b[0] * v + c[0] * w;\n        cartesian[1] = a[1] * u + b[1] * v + c[1] * w;\n        cartesian[2] = a[2] * u + b[2] * v + c[2] * w;\n\n        return cartesian;\n    },\n\n\n    /**\n     * Given geometry defined as an array of positions, optional normals, option uv and an array of indices, returns\n     * modified arrays that have duplicate vertices removed.\n     *\n     * Note: does not work well when co-incident vertices have same positions but different normals and UVs.\n     *\n     * @param positions\n     * @param normals\n     * @param uv\n     * @param indices\n     * @returns {{positions: Array, indices: Array}}\n     * @private\n     */\n    mergeVertices(positions, normals, uv, indices) {\n        const positionsMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n        const indicesLookup = [];\n        const uniquePositions = [];\n        const uniqueNormals = normals ? [] : null;\n        const uniqueUV = uv ? [] : null;\n        const indices2 = [];\n        let vx;\n        let vy;\n        let vz;\n        let key;\n        const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n        const precision = 10 ** precisionPoints;\n        let i;\n        let len;\n        let uvi = 0;\n        for (i = 0, len = positions.length; i < len; i += 3) {\n            vx = positions[i];\n            vy = positions[i + 1];\n            vz = positions[i + 2];\n            key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`;\n            if (positionsMap[key] === undefined) {\n                positionsMap[key] = uniquePositions.length / 3;\n                uniquePositions.push(vx);\n                uniquePositions.push(vy);\n                uniquePositions.push(vz);\n                if (normals) {\n                    uniqueNormals.push(normals[i]);\n                    uniqueNormals.push(normals[i + 1]);\n                    uniqueNormals.push(normals[i + 2]);\n                }\n                if (uv) {\n                    uniqueUV.push(uv[uvi]);\n                    uniqueUV.push(uv[uvi + 1]);\n                }\n            }\n            indicesLookup[i / 3] = positionsMap[key];\n            uvi += 2;\n        }\n        for (i = 0, len = indices.length; i < len; i++) {\n            indices2[i] = indicesLookup[indices[i]];\n        }\n        const result = {\n            positions: uniquePositions,\n            indices: indices2\n        };\n        if (uniqueNormals) {\n            result.normals = uniqueNormals;\n        }\n        if (uniqueUV) {\n            result.uv = uniqueUV;\n\n        }\n        return result;\n    },\n\n    /**\n     * Builds normal vectors from positions and indices.\n     *\n     * @private\n     */\n    buildNormals: ((() => {\n\n        const a = new FloatArrayType(3);\n        const b = new FloatArrayType(3);\n        const c = new FloatArrayType(3);\n        const ab = new FloatArrayType(3);\n        const ac = new FloatArrayType(3);\n        const crossVec = new FloatArrayType(3);\n\n        return (positions, indices, normals) => {\n\n            let i;\n            let len;\n            const nvecs = new Array(positions.length / 3);\n            let j0;\n            let j1;\n            let j2;\n\n            for (i = 0, len = indices.length; i < len; i += 3) {\n\n                j0 = indices[i];\n                j1 = indices[i + 1];\n                j2 = indices[i + 2];\n\n                a[0] = positions[j0 * 3];\n                a[1] = positions[j0 * 3 + 1];\n                a[2] = positions[j0 * 3 + 2];\n\n                b[0] = positions[j1 * 3];\n                b[1] = positions[j1 * 3 + 1];\n                b[2] = positions[j1 * 3 + 2];\n\n                c[0] = positions[j2 * 3];\n                c[1] = positions[j2 * 3 + 1];\n                c[2] = positions[j2 * 3 + 2];\n\n                math.subVec3(b, a, ab);\n                math.subVec3(c, a, ac);\n\n                const normVec = math.vec3();\n\n                math.normalizeVec3(math.cross3Vec3(ab, ac, crossVec), normVec);\n\n                if (!nvecs[j0]) {\n                    nvecs[j0] = [];\n                }\n                if (!nvecs[j1]) {\n                    nvecs[j1] = [];\n                }\n                if (!nvecs[j2]) {\n                    nvecs[j2] = [];\n                }\n\n                nvecs[j0].push(normVec);\n                nvecs[j1].push(normVec);\n                nvecs[j2].push(normVec);\n            }\n\n            normals = (normals && normals.length === positions.length) ? normals : new Float32Array(positions.length);\n\n            let count;\n            let x;\n            let y;\n            let z;\n\n            for (i = 0, len = nvecs.length; i < len; i++) {  // Now go through and average out everything\n\n                count = nvecs[i].length;\n\n                x = 0;\n                y = 0;\n                z = 0;\n\n                for (let j = 0; j < count; j++) {\n                    x += nvecs[i][j][0];\n                    y += nvecs[i][j][1];\n                    z += nvecs[i][j][2];\n                }\n\n                normals[i * 3] = (x / count);\n                normals[i * 3 + 1] = (y / count);\n                normals[i * 3 + 2] = (z / count);\n            }\n\n            return normals;\n        };\n    }))(),\n\n    /**\n     * Builds vertex tangent vectors from positions, UVs and indices.\n     *\n     * @private\n     */\n    buildTangents: ((() => {\n\n        const tempVec3 = new FloatArrayType(3);\n        const tempVec3b = new FloatArrayType(3);\n        const tempVec3c = new FloatArrayType(3);\n        const tempVec3d = new FloatArrayType(3);\n        const tempVec3e = new FloatArrayType(3);\n        const tempVec3f = new FloatArrayType(3);\n        const tempVec3g = new FloatArrayType(3);\n\n        return (positions, indices, uv) => {\n\n            const tangents = new Float32Array(positions.length);\n\n            // The vertex arrays needs to be calculated\n            // before the calculation of the tangents\n\n            for (let location = 0; location < indices.length; location += 3) {\n\n                // Recontructing each vertex and UV coordinate into the respective vectors\n\n                let index = indices[location];\n\n                const v0 = positions.subarray(index * 3, index * 3 + 3);\n                const uv0 = uv.subarray(index * 2, index * 2 + 2);\n\n                index = indices[location + 1];\n\n                const v1 = positions.subarray(index * 3, index * 3 + 3);\n                const uv1 = uv.subarray(index * 2, index * 2 + 2);\n\n                index = indices[location + 2];\n\n                const v2 = positions.subarray(index * 3, index * 3 + 3);\n                const uv2 = uv.subarray(index * 2, index * 2 + 2);\n\n                const deltaPos1 = math.subVec3(v1, v0, tempVec3);\n                const deltaPos2 = math.subVec3(v2, v0, tempVec3b);\n\n                const deltaUV1 = math.subVec2(uv1, uv0, tempVec3c);\n                const deltaUV2 = math.subVec2(uv2, uv0, tempVec3d);\n\n                const r = 1 / ((deltaUV1[0] * deltaUV2[1]) - (deltaUV1[1] * deltaUV2[0]));\n\n                const tangent = math.mulVec3Scalar(\n                    math.subVec3(\n                        math.mulVec3Scalar(deltaPos1, deltaUV2[1], tempVec3e),\n                        math.mulVec3Scalar(deltaPos2, deltaUV1[1], tempVec3f),\n                        tempVec3g\n                    ),\n                    r,\n                    tempVec3f\n                );\n\n                // Average the value of the vectors\n\n                let addTo;\n\n                for (let v = 0; v < 3; v++) {\n                    addTo = indices[location + v] * 3;\n                    tangents[addTo] += tangent[0];\n                    tangents[addTo + 1] += tangent[1];\n                    tangents[addTo + 2] += tangent[2];\n                }\n            }\n\n            return tangents;\n        };\n    }))(),\n\n    /**\n     * Builds vertex and index arrays needed by color-indexed triangle picking.\n     *\n     * @private\n     */\n    buildPickTriangles(positions, indices, compressGeometry) {\n\n        const numIndices = indices.length;\n        const pickPositions = compressGeometry ? new Uint16Array(numIndices * 9) : new Float32Array(numIndices * 9);\n        const pickColors = new Uint8Array(numIndices * 12);\n        let primIndex = 0;\n        let vi;// Positions array index\n        let pvi = 0;// Picking positions array index\n        let pci = 0; // Picking color array index\n\n        // Triangle indices\n        let i;\n        let r;\n        let g;\n        let b;\n        let a;\n\n        for (let location = 0; location < numIndices; location += 3) {\n\n            // Primitive-indexed triangle pick color\n\n            a = (primIndex >> 24 & 0xFF);\n            b = (primIndex >> 16 & 0xFF);\n            g = (primIndex >> 8 & 0xFF);\n            r = (primIndex & 0xFF);\n\n            // A\n\n            i = indices[location];\n            vi = i * 3;\n\n            pickPositions[pvi++] = positions[vi];\n            pickPositions[pvi++] = positions[vi + 1];\n            pickPositions[pvi++] = positions[vi + 2];\n\n            pickColors[pci++] = r;\n            pickColors[pci++] = g;\n            pickColors[pci++] = b;\n            pickColors[pci++] = a;\n\n            // B\n\n            i = indices[location + 1];\n            vi = i * 3;\n\n            pickPositions[pvi++] = positions[vi];\n            pickPositions[pvi++] = positions[vi + 1];\n            pickPositions[pvi++] = positions[vi + 2];\n\n            pickColors[pci++] = r;\n            pickColors[pci++] = g;\n            pickColors[pci++] = b;\n            pickColors[pci++] = a;\n\n            // C\n\n            i = indices[location + 2];\n            vi = i * 3;\n\n            pickPositions[pvi++] = positions[vi];\n            pickPositions[pvi++] = positions[vi + 1];\n            pickPositions[pvi++] = positions[vi + 2];\n\n            pickColors[pci++] = r;\n            pickColors[pci++] = g;\n            pickColors[pci++] = b;\n            pickColors[pci++] = a;\n\n            primIndex++;\n        }\n\n        return {\n            positions: pickPositions,\n            colors: pickColors\n        };\n    },\n\n    /**\n     * Converts surface-perpendicular face normals to vertex normals. Assumes that the mesh contains disjoint triangles\n     * that don't share vertex array elements. Works by finding groups of vertices that have the same location and\n     * averaging their normal vectors.\n     *\n     * @returns {{positions: Array, normals: *}}\n     */\n    faceToVertexNormals(positions, normals, options = {}) {\n        const smoothNormalsAngleThreshold = options.smoothNormalsAngleThreshold || 20;\n        const vertexMap = {};\n        const vertexNormals = [];\n        const vertexNormalAccum = {};\n        let acc;\n        let vx;\n        let vy;\n        let vz;\n        let key;\n        const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n        const precision = 10 ** precisionPoints;\n        let posi;\n        let i;\n        let j;\n        let len;\n        let a;\n        let b;\n\n        for (i = 0, len = positions.length; i < len; i += 3) {\n\n            posi = i / 3;\n\n            vx = positions[i];\n            vy = positions[i + 1];\n            vz = positions[i + 2];\n\n            key = `${Math.round(vx * precision)}_${Math.round(vy * precision)}_${Math.round(vz * precision)}`;\n\n            if (vertexMap[key] === undefined) {\n                vertexMap[key] = [posi];\n            } else {\n                vertexMap[key].push(posi);\n            }\n\n            const normal = math.normalizeVec3([normals[i], normals[i + 1], normals[i + 2]]);\n\n            vertexNormals[posi] = normal;\n\n            acc = math.vec4([normal[0], normal[1], normal[2], 1]);\n\n            vertexNormalAccum[posi] = acc;\n        }\n\n        for (key in vertexMap) {\n\n            if (vertexMap.hasOwnProperty(key)) {\n\n                const vertices = vertexMap[key];\n                const numVerts = vertices.length;\n\n                for (i = 0; i < numVerts; i++) {\n\n                    const ii = vertices[i];\n\n                    acc = vertexNormalAccum[ii];\n\n                    for (j = 0; j < numVerts; j++) {\n\n                        if (i === j) {\n                            continue;\n                        }\n\n                        const jj = vertices[j];\n\n                        a = vertexNormals[ii];\n                        b = vertexNormals[jj];\n\n                        const angle = Math.abs(math.angleVec3(a, b) / math.DEGTORAD);\n\n                        if (angle < smoothNormalsAngleThreshold) {\n\n                            acc[0] += b[0];\n                            acc[1] += b[1];\n                            acc[2] += b[2];\n                            acc[3] += 1.0;\n                        }\n                    }\n                }\n            }\n        }\n\n        for (i = 0, len = normals.length; i < len; i += 3) {\n\n            acc = vertexNormalAccum[i / 3];\n\n            normals[i + 0] = acc[0] / acc[3];\n            normals[i + 1] = acc[1] / acc[3];\n            normals[i + 2] = acc[2] / acc[3];\n\n        }\n    },\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Ray casting\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     Transforms a ray by a matrix.\n     @method transformRay\n     @static\n     @param {Number[]} matrix 4x4 matrix\n     @param {Number[]} rayOrigin The ray origin\n     @param {Number[]} rayDir The ray direction\n     @param {Number[]} rayOriginDest The transformed ray origin\n     @param {Number[]} rayDirDest The transformed ray direction\n     */\n    transformRay: ((() => {\n\n        const tempVec4a = new FloatArrayType(4);\n        const tempVec4b = new FloatArrayType(4);\n\n        return (matrix, rayOrigin, rayDir, rayOriginDest, rayDirDest) => {\n\n            tempVec4a[0] = rayOrigin[0];\n            tempVec4a[1] = rayOrigin[1];\n            tempVec4a[2] = rayOrigin[2];\n            tempVec4a[3] = 1;\n\n            math.transformVec4(matrix, tempVec4a, tempVec4b);\n\n            rayOriginDest[0] = tempVec4b[0];\n            rayOriginDest[1] = tempVec4b[1];\n            rayOriginDest[2] = tempVec4b[2];\n\n            tempVec4a[0] = rayDir[0];\n            tempVec4a[1] = rayDir[1];\n            tempVec4a[2] = rayDir[2];\n\n            math.transformVec3(matrix, tempVec4a, tempVec4b);\n\n            math.normalizeVec3(tempVec4b);\n\n            rayDirDest[0] = tempVec4b[0];\n            rayDirDest[1] = tempVec4b[1];\n            rayDirDest[2] = tempVec4b[2];\n        };\n    }))(),\n\n    /**\n     Transforms a Canvas-space position into a World-space ray, in the context of a Camera.\n     @method canvasPosToWorldRay\n     @static\n     @param {Number[]} viewMatrix View matrix\n     @param {Number[]} projMatrix Projection matrix\n     @param {String} projection Projection type (e.g. \"ortho\")\n     @param {Number[]} canvasPos The Canvas-space position.\n     @param {Number[]} worldRayOrigin The World-space ray origin.\n     @param {Number[]} worldRayDir The World-space ray direction.\n     */\n    canvasPosToWorldRay: ((() => {\n\n        const pvMatInv = new FloatArrayType(16);\n        const vec4Near = new FloatArrayType(4);\n        const vec4Far  = new FloatArrayType(4);\n\n        const clipToWorld = (clipX, clipY, clipZ, isOrtho, outVec4) => {\n            outVec4[0] = clipX;\n            outVec4[1] = clipY;\n            outVec4[2] = clipZ;\n            outVec4[3] = 1;\n\n            math.transformVec4(pvMatInv, outVec4, outVec4);\n            if (! isOrtho)\n                math.mulVec4Scalar(outVec4, 1 / outVec4[3]);\n        };\n\n        return (canvas, viewMatrix, projMatrix, projection, canvasPos, worldRayOrigin, worldRayDir) => {\n            const isOrtho = projection === \"ortho\";\n\n            math.mulMat4(projMatrix, viewMatrix, pvMatInv);\n            math.inverseMat4(pvMatInv, pvMatInv);\n\n            // Calculate clip space coordinates, which will be in range\n            // of x=[-1..1] and y=[-1..1], with y=(+1) at top\n            // clientWidth/Height needs to be used in case canvas.width/height is scaled down,\n            // but not reflecting client dimensions (e.g. when using FastNavPlugin)\n            const clipX =     2 * canvasPos[0] / canvas.clientWidth - 1;  // Calculate clip space coordinates\n            const clipY = 1 - 2 * canvasPos[1] / canvas.clientHeight;\n\n            clipToWorld(clipX, clipY, -1, isOrtho, vec4Near);\n\n            clipToWorld(clipX, clipY,  1, isOrtho, vec4Far);\n\n            worldRayOrigin[0] = vec4Near[0];\n            worldRayOrigin[1] = vec4Near[1];\n            worldRayOrigin[2] = vec4Near[2];\n\n            math.subVec3(vec4Far, vec4Near, worldRayDir);\n\n            math.normalizeVec3(worldRayDir);\n        };\n    }))(),\n\n    /**\n     Transforms a Canvas-space position to a Mesh's Local-space coordinate system, in the context of a Camera.\n     @method canvasPosToLocalRay\n     @static\n     @param {Camera} camera The Camera.\n     @param {Mesh} mesh The Mesh.\n     @param {Number[]} viewMatrix View matrix\n     @param {Number[]} projMatrix Projection matrix\n     @param {Number[]} worldMatrix Modeling matrix\n     @param {Number[]} canvasPos The Canvas-space position.\n     @param {Number[]} localRayOrigin The Local-space ray origin.\n     @param {Number[]} localRayDir The Local-space ray direction.\n     */\n    canvasPosToLocalRay: ((() => {\n\n        const worldRayOrigin = new FloatArrayType(3);\n        const worldRayDir = new FloatArrayType(3);\n\n        return (canvas, viewMatrix, projMatrix, projection, worldMatrix, canvasPos, localRayOrigin, localRayDir) => {\n            math.canvasPosToWorldRay(canvas, viewMatrix, projMatrix, projection, canvasPos, worldRayOrigin, worldRayDir);\n            math.worldRayToLocalRay(worldMatrix, worldRayOrigin, worldRayDir, localRayOrigin, localRayDir);\n        };\n    }))(),\n\n    /**\n     Transforms a ray from World-space to a Mesh's Local-space coordinate system.\n     @method worldRayToLocalRay\n     @static\n     @param {Number[]} worldMatrix The World transform matrix\n     @param {Number[]} worldRayOrigin The World-space ray origin.\n     @param {Number[]} worldRayDir The World-space ray direction.\n     @param {Number[]} localRayOrigin The Local-space ray origin.\n     @param {Number[]} localRayDir The Local-space ray direction.\n     */\n    worldRayToLocalRay: ((() => {\n\n        const tempMat4 = new FloatArrayType(16);\n        const tempVec4a = new FloatArrayType(4);\n        const tempVec4b = new FloatArrayType(4);\n\n        return (worldMatrix, worldRayOrigin, worldRayDir, localRayOrigin, localRayDir) => {\n\n            const modelMatInverse = math.inverseMat4(worldMatrix, tempMat4);\n\n            tempVec4a[0] = worldRayOrigin[0];\n            tempVec4a[1] = worldRayOrigin[1];\n            tempVec4a[2] = worldRayOrigin[2];\n            tempVec4a[3] = 1;\n\n            math.transformVec4(modelMatInverse, tempVec4a, tempVec4b);\n\n            localRayOrigin[0] = tempVec4b[0];\n            localRayOrigin[1] = tempVec4b[1];\n            localRayOrigin[2] = tempVec4b[2];\n\n            math.transformVec3(modelMatInverse, worldRayDir, localRayDir);\n        };\n    }))(),\n\n    buildKDTree: ((() => {\n\n        const KD_TREE_MAX_DEPTH = 10;\n        const KD_TREE_MIN_TRIANGLES = 20;\n\n        const dimLength = new Float32Array();\n\n        function buildNode(triangles, indices, positions, depth) {\n            const aabb = new FloatArrayType(6);\n\n            const node = {\n                triangles: null,\n                left: null,\n                right: null,\n                leaf: false,\n                splitDim: 0,\n                aabb\n            };\n\n            aabb[0] = aabb[1] = aabb[2] = Number.POSITIVE_INFINITY;\n            aabb[3] = aabb[4] = aabb[5] = Number.NEGATIVE_INFINITY;\n\n            let t;\n            let len;\n\n            for (t = 0, len = triangles.length; t < len; ++t) {\n                var ii = triangles[t] * 3;\n                for (let j = 0; j < 3; ++j) {\n                    const pi = indices[ii + j] * 3;\n                    if (positions[pi] < aabb[0]) {\n                        aabb[0] = positions[pi];\n                    }\n                    if (positions[pi] > aabb[3]) {\n                        aabb[3] = positions[pi];\n                    }\n                    if (positions[pi + 1] < aabb[1]) {\n                        aabb[1] = positions[pi + 1];\n                    }\n                    if (positions[pi + 1] > aabb[4]) {\n                        aabb[4] = positions[pi + 1];\n                    }\n                    if (positions[pi + 2] < aabb[2]) {\n                        aabb[2] = positions[pi + 2];\n                    }\n                    if (positions[pi + 2] > aabb[5]) {\n                        aabb[5] = positions[pi + 2];\n                    }\n                }\n            }\n\n            if (triangles.length < KD_TREE_MIN_TRIANGLES || depth > KD_TREE_MAX_DEPTH) {\n                node.triangles = triangles;\n                node.leaf = true;\n                return node;\n            }\n\n            dimLength[0] = aabb[3] - aabb[0];\n            dimLength[1] = aabb[4] - aabb[1];\n            dimLength[2] = aabb[5] - aabb[2];\n\n            let dim = 0;\n\n            if (dimLength[1] > dimLength[dim]) {\n                dim = 1;\n            }\n\n            if (dimLength[2] > dimLength[dim]) {\n                dim = 2;\n            }\n\n            node.splitDim = dim;\n\n            const mid = (aabb[dim] + aabb[dim + 3]) / 2;\n            const left = new Array(triangles.length);\n            let numLeft = 0;\n            const right = new Array(triangles.length);\n            let numRight = 0;\n\n            for (t = 0, len = triangles.length; t < len; ++t) {\n\n                var ii = triangles[t] * 3;\n                const i0 = indices[ii];\n                const i1 = indices[ii + 1];\n                const i2 = indices[ii + 2];\n\n                const pi0 = i0 * 3;\n                const pi1 = i1 * 3;\n                const pi2 = i2 * 3;\n\n                if (positions[pi0 + dim] <= mid || positions[pi1 + dim] <= mid || positions[pi2 + dim] <= mid) {\n                    left[numLeft++] = triangles[t];\n                } else {\n                    right[numRight++] = triangles[t];\n                }\n            }\n\n            left.length = numLeft;\n            right.length = numRight;\n\n            node.left = buildNode(left, indices, positions, depth + 1);\n            node.right = buildNode(right, indices, positions, depth + 1);\n\n            return node;\n        }\n\n        return (indices, positions) => {\n            const numTris = indices.length / 3;\n            const triangles = new Array(numTris);\n            for (let i = 0; i < numTris; ++i) {\n                triangles[i] = i;\n            }\n            return buildNode(triangles, indices, positions, 0);\n        };\n    }))(),\n\n\n    decompressPosition(position, decodeMatrix, dest) {\n        dest = dest || position;\n        dest[0] = position[0] * decodeMatrix[0] + decodeMatrix[12];\n        dest[1] = position[1] * decodeMatrix[5] + decodeMatrix[13];\n        dest[2] = position[2] * decodeMatrix[10] + decodeMatrix[14];\n    },\n\n    decompressPositions(positions, decodeMatrix, dest = new Float32Array(positions.length)) {\n        for (let i = 0, len = positions.length; i < len; i += 3) {\n            dest[i + 0] = positions[i + 0] * decodeMatrix[0] + decodeMatrix[12];\n            dest[i + 1] = positions[i + 1] * decodeMatrix[5] + decodeMatrix[13];\n            dest[i + 2] = positions[i + 2] * decodeMatrix[10] + decodeMatrix[14];\n        }\n        return dest;\n    },\n\n    decompressUV(uv, decodeMatrix, dest) {\n        dest[0] = uv[0] * decodeMatrix[0] + decodeMatrix[6];\n        dest[1] = uv[1] * decodeMatrix[4] + decodeMatrix[7];\n    },\n\n    decompressUVs(uvs, decodeMatrix, dest = new Float32Array(uvs.length)) {\n        for (let i = 0, len = uvs.length; i < len; i += 3) {\n            dest[i + 0] = uvs[i + 0] * decodeMatrix[0] + decodeMatrix[6];\n            dest[i + 1] = uvs[i + 1] * decodeMatrix[4] + decodeMatrix[7];\n        }\n        return dest;\n    },\n\n    octDecodeVec2(oct, result) {\n        let x = oct[0];\n        let y = oct[1];\n        x = (2 * x + 1) / 255;\n        y = (2 * y + 1) / 255;\n        const z = 1 - Math.abs(x) - Math.abs(y);\n        if (z < 0) {\n            x = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n            y = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n        }\n        const length = Math.sqrt(x * x + y * y + z * z);\n        result[0] = x / length;\n        result[1] = y / length;\n        result[2] = z / length;\n        return result;\n    },\n\n    octDecodeVec2s(octs, result) {\n        for (let i = 0, j = 0, len = octs.length; i < len; i += 2) {\n            let x = octs[i + 0];\n            let y = octs[i + 1];\n            x = (2 * x + 1) / 255;\n            y = (2 * y + 1) / 255;\n            const z = 1 - Math.abs(x) - Math.abs(y);\n            if (z < 0) {\n                x = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n                y = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n            }\n            const length = Math.sqrt(x * x + y * y + z * z);\n            result[j + 0] = x / length;\n            result[j + 1] = y / length;\n            result[j + 2] = z / length;\n            j += 3;\n        }\n        return result;\n    }\n};\n\nmath.buildEdgeIndices = (function () {\n\n    const uniquePositions = [];\n    const indicesLookup = [];\n    const indicesReverseLookup = [];\n    const weldedIndices = [];\n\n    // TODO: Optimize with caching, but need to cater to both compressed and uncompressed positions\n\n    const faces = [];\n    let numFaces = 0;\n    const compa = new Uint16Array(3);\n    const compb = new Uint16Array(3);\n    const compc = new Uint16Array(3);\n    const a = math.vec3();\n    const b = math.vec3();\n    const c = math.vec3();\n    const cb = math.vec3();\n    const ab = math.vec3();\n    const cross = math.vec3();\n    const normal = math.vec3();\n\n    function weldVertices(positions, indices) {\n        const positionsMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n        let vx;\n        let vy;\n        let vz;\n        let key;\n        const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n        const precision = Math.pow(10, precisionPoints);\n        let i;\n        let len;\n        let lenUniquePositions = 0;\n        for (i = 0, len = positions.length; i < len; i += 3) {\n            vx = positions[i];\n            vy = positions[i + 1];\n            vz = positions[i + 2];\n            key = Math.round(vx * precision) + '_' + Math.round(vy * precision) + '_' + Math.round(vz * precision);\n            if (positionsMap[key] === undefined) {\n                positionsMap[key] = lenUniquePositions / 3;\n                uniquePositions[lenUniquePositions++] = vx;\n                uniquePositions[lenUniquePositions++] = vy;\n                uniquePositions[lenUniquePositions++] = vz;\n            }\n            indicesLookup[i / 3] = positionsMap[key];\n        }\n        for (i = 0, len = indices.length; i < len; i++) {\n            weldedIndices[i] = indicesLookup[indices[i]];\n            indicesReverseLookup[weldedIndices[i]] = indices[i];\n        }\n    }\n\n    function buildFaces(numIndices, positionsDecodeMatrix) {\n        numFaces = 0;\n        for (let i = 0, len = numIndices; i < len; i += 3) {\n            const ia = ((weldedIndices[i]) * 3);\n            const ib = ((weldedIndices[i + 1]) * 3);\n            const ic = ((weldedIndices[i + 2]) * 3);\n            if (positionsDecodeMatrix) {\n                compa[0] = uniquePositions[ia];\n                compa[1] = uniquePositions[ia + 1];\n                compa[2] = uniquePositions[ia + 2];\n                compb[0] = uniquePositions[ib];\n                compb[1] = uniquePositions[ib + 1];\n                compb[2] = uniquePositions[ib + 2];\n                compc[0] = uniquePositions[ic];\n                compc[1] = uniquePositions[ic + 1];\n                compc[2] = uniquePositions[ic + 2];\n                // Decode\n                math.decompressPosition(compa, positionsDecodeMatrix, a);\n                math.decompressPosition(compb, positionsDecodeMatrix, b);\n                math.decompressPosition(compc, positionsDecodeMatrix, c);\n            } else {\n                a[0] = uniquePositions[ia];\n                a[1] = uniquePositions[ia + 1];\n                a[2] = uniquePositions[ia + 2];\n                b[0] = uniquePositions[ib];\n                b[1] = uniquePositions[ib + 1];\n                b[2] = uniquePositions[ib + 2];\n                c[0] = uniquePositions[ic];\n                c[1] = uniquePositions[ic + 1];\n                c[2] = uniquePositions[ic + 2];\n            }\n            math.subVec3(c, b, cb);\n            math.subVec3(a, b, ab);\n            math.cross3Vec3(cb, ab, cross);\n            math.normalizeVec3(cross, normal);\n            const face = faces[numFaces] || (faces[numFaces] = {normal: math.vec3()});\n            face.normal[0] = normal[0];\n            face.normal[1] = normal[1];\n            face.normal[2] = normal[2];\n            numFaces++;\n        }\n    }\n\n    return function (positions, indices, positionsDecodeMatrix, edgeThreshold) {\n        weldVertices(positions, indices);\n        buildFaces(indices.length, positionsDecodeMatrix);\n        const edgeIndices = [];\n        const thresholdDot = Math.cos(math.DEGTORAD * edgeThreshold);\n        const edges = {};\n        let edge1;\n        let edge2;\n        let index1;\n        let index2;\n        let key;\n        let largeIndex = false;\n        let edge;\n        let normal1;\n        let normal2;\n        let dot;\n        let ia;\n        let ib;\n        for (let i = 0, len = indices.length; i < len; i += 3) {\n            const faceIndex = i / 3;\n            for (let j = 0; j < 3; j++) {\n                edge1 = weldedIndices[i + j];\n                edge2 = weldedIndices[i + ((j + 1) % 3)];\n                index1 = Math.min(edge1, edge2);\n                index2 = Math.max(edge1, edge2);\n                key = index1 + \",\" + index2;\n                if (edges[key] === undefined) {\n                    edges[key] = {\n                        index1: index1,\n                        index2: index2,\n                        face1: faceIndex,\n                        face2: undefined\n                    };\n                } else {\n                    edges[key].face2 = faceIndex;\n                }\n            }\n        }\n        for (key in edges) {\n            edge = edges[key];\n            // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n            if (edge.face2 !== undefined) {\n                normal1 = faces[edge.face1].normal;\n                normal2 = faces[edge.face2].normal;\n                dot = math.dotVec3(normal1, normal2);\n                if (dot > thresholdDot) {\n                    continue;\n                }\n            }\n            ia = indicesReverseLookup[edge.index1];\n            ib = indicesReverseLookup[edge.index2];\n            if (!largeIndex && ia > 65535 || ib > 65535) {\n                largeIndex = true;\n            }\n            edgeIndices.push(ia);\n            edgeIndices.push(ib);\n        }\n        return (largeIndex) ? new Uint32Array(edgeIndices) : new Uint16Array(edgeIndices);\n    };\n})();\n\n\n/**\n * Returns `true` if a plane clips the given 3D positions.\n * @param {Number[]} pos Position in plane\n * @param {Number[]} dir Direction of plane\n * @param {number} positions Flat array of 3D positions.\n * @param {number} numElementsPerPosition Number of elements perposition - usually either 3 or 4.\n * @returns {boolean}\n */\nmath.planeClipsPositions3 = function (pos, dir, positions, numElementsPerPosition = 3) {\n    for (let i = 0, len = positions.length; i < len; i += numElementsPerPosition) {\n        tempVec3a$j[0] = positions[i + 0] - pos[0];\n        tempVec3a$j[1] = positions[i + 1] - pos[1];\n        tempVec3a$j[2] = positions[i + 2] - pos[2];\n        let dotProduct = tempVec3a$j[0] * dir[0] + tempVec3a$j[1] * dir[1] + tempVec3a$j[2] * dir[2];\n        if (dotProduct < 0) {\n            return true;\n        }\n    }\n    return false;\n};\n\n/**\n * Tests whether a plane intersects a bouding box.\n * @param plane SectionPlane\n * @param aabb Bounding box\n * @returns {boolean}\n */\nmath.planeIntersectsAABB3 = (plane, aabb) => {\n    const min = [aabb[0], aabb[1], aabb[2]];\n    const max = [aabb[3], aabb[4], aabb[5]];\n\n    const corners = [\n        [min[0], min[1], min[2]], // 000\n        [max[0], min[1], min[2]], // 100\n        [min[0], max[1], min[2]], // 010\n        [max[0], max[1], min[2]], // 110\n        [min[0], min[1], max[2]], // 001\n        [max[0], min[1], max[2]], // 101\n        [min[0], max[1], max[2]], // 011\n        [max[0], max[1], max[2]]  // 111\n    ];\n\n    // Calculate distance from each corner to the plane\n    let hasPositive = false;\n    let hasNegative = false;\n\n    for (const corner of corners) {\n        const distance = plane.dist + math.dotVec3(plane.dir, corner);\n\n        if (distance > 0) hasPositive = true;\n        if (distance < 0) hasNegative = true;\n\n        // If we found points on both sides, the plane intersects the box\n        if (hasPositive && hasNegative) return true;\n    }\n\n    // If all points are on the same side, no intersection\n    return false;\n};\n\n/**\n * makeSectionPlaneSlicer returns a function that slices a given geometry with a given SectionPlane\n * The implementation finds segments where the SectionPlane intersects with the geometry's surface.\n * These segments form loops that are triangulated using the Earcut algorithm, taking internal holes into account.\n * @param {Number[]} pos SectionPlane position 3D vector\n * @param {Number[]} dir SectionPlane rotation quaternion\n * @returns {function}\n */\nmath.makeSectionPlaneSlicer = (function() {\n\n    const tempVec2a = math.vec2();\n    const tempVec2b = math.vec2();\n    const tempVec2c = math.vec2();\n    const tempVec2d = math.vec2();\n\n    const tempVec3a = math.vec3();\n    const tempVec3b = math.vec3();\n    const tempVec3c = math.vec3();\n    math.vec3();\n\n    const triangle = [ math.vec3(), math.vec3(), math.vec3() ];\n    const tmpIntersections = [ null, null, null ];\n    const tmpPositions     = [ null, null, null ];\n    const tmpReferences    = [ null, null, null ];\n\n    const worldRight   = [1, 0, 0];\n    const worldUp      = [0, 1, 0];\n    const worldForward = [0, 0, 1];\n\n    const sqDistVec3 = (function() {\n        const tmp = math.vec3();\n        return (a, b) => math.sqLenVec3(math.subVec3(a, b, tmp));\n    })();\n\n    const iota = n => {\n        const ret = [ ];\n        for (let i = 0; i < n; ++i)\n            ret.push(i);\n        return ret;\n    };\n\n    const ccw = (a, b, c) => ((c[1] - a[1]) * (b[0] - a[0])) > ((b[1] - a[1]) * (c[0] - a[0]));\n\n    return function(plane) {\n        const planeU = math.vec3ApplyQuaternion(plane.quaternion, worldRight,   math.vec3());\n        const planeV = math.vec3ApplyQuaternion(plane.quaternion, worldUp,      math.vec3());\n        const planeN = math.vec3ApplyQuaternion(plane.quaternion, worldForward, math.vec3());\n\n        return function(mesh, cfg = { }) {\n            const planeToMesh = math.subVec3(mesh.origin, plane.pos, math.vec3());\n            const planeDist = math.dotVec3(planeN, planeToMesh);\n\n            const unsortedSegment = [ ];\n            const indexedPositions = [ null ]; // to never return 0 from addPosition, so its result can be used as a predicate\n            const addPosition = (p, addUV) => {\n                const idx = indexedPositions.length;\n                const P = new Float64Array(5);\n                P.set(p);\n                if (addUV) {\n                    math.addVec3(planeToMesh, p, tempVec3a);\n                    P[3] = -math.dotVec3(planeU, tempVec3a);\n                    P[4] = math.dotVec3(planeV, tempVec3a);\n                }\n                indexedPositions.push(P);\n                return idx;\n            };\n\n            const getCoord2D = (idx, dst) => { const P = indexedPositions[idx]; dst[0] = P[3]; dst[1] = P[4]; return dst; };\n\n            const isLoopInside = (inner, outer) => {\n                const bbI = inner.boundingBox;\n                const bbO = outer.boundingBox;\n                if ((bbI[0] < bbO[0]) || (bbI[1] < bbO[1]) || (bbI[2] > bbO[2]) || (bbI[3] > bbO[3])) {\n                    return false;\n                }\n\n                const innerEndpoints = inner.endPoints;\n                const outerEndpoints = outer.endPoints;\n                for (let ii = 0, ij = innerEndpoints.length - 1; ii < innerEndpoints.length; ij = ii++) {\n                    const i0 = getCoord2D(innerEndpoints[ii], tempVec2a);\n                    const [i0x, i0y] = i0;\n                    const i1 = getCoord2D(innerEndpoints[ij], tempVec2b);\n\n                    let inside = false;\n                    for (let i = 0, j = outerEndpoints.length - 1; i < outerEndpoints.length; j = i++) {\n                        const o0 = getCoord2D(outerEndpoints[i], tempVec2c);\n                        const o1 = getCoord2D(outerEndpoints[j], tempVec2d);\n\n                        if ((ccw(i0, o0, o1) !== ccw(i1, o0, o1)) && (ccw(i0, i1, o0) !== ccw(i0, i1, o1))) {\n                            return false; // segments intersect\n                        }\n\n                        const [o0x, o0y] = o0;\n                        const [o1x, o1y] = o1;\n\n                        const dx = i0x - o0x;\n                        const dy = i0y - o0y;\n\n                        const oDx = o1x - o0x;\n                        const oDy = o1y - o0y;\n\n                        const dot = (((oDx !== 0) || (oDy !== 0)) && (Math.abs(oDx * dy - oDy * dx) < 1e-10)) ? (dx * oDx + dy * oDy) : -1;\n                        if ((dot >= 0) && (dot <= (Math.pow(oDx, 2) + Math.pow(oDy, 2)))) {\n                            return false; // on edge\n                        }\n\n                        if (((o0y > i0y) !== (o1y > i0y)) && (dx < (dy * oDx / oDy))) {\n                            inside = !inside;\n                        }\n                    }\n                    if (! inside) {\n                        return false;\n                    }\n                }\n\n                return true;\n            };\n\n            const pos = { indices: [ ], normals: [ ] };\n            const neg = (! cfg.onlyPosSliceWithUV) && { indices: [ ], normals: [ ] };\n\n            const appendOnSide = (dst, indices, normal) => {\n                if (dst) {\n                    const p0 = indexedPositions[indices[0]];\n                    normal ||= math.normalizeVec3(math.cross3Vec3(math.subVec3(indexedPositions[indices[1]], p0, tempVec3a),\n                                                                  math.subVec3(indexedPositions[indices[2]], p0, tempVec3b),\n                                                                  tempVec3a),\n                                                  tempVec3a);\n\n                    for (let i = 0; i < 3; ++i) {\n                        dst.indices.push(indices[i]);\n                        dst.normals.push(normal[0], normal[1], normal[2]);\n                    }\n                }\n            };\n\n            const setVertex = (i, dst) => {\n                const idx = mesh.indices[i] * 3;\n                dst[0] = mesh.positions[idx + 0];\n                dst[1] = mesh.positions[idx + 1];\n                dst[2] = mesh.positions[idx + 2];\n                return dst;\n            };\n\n            for (let faceIdx = 0; faceIdx < mesh.indices.length; faceIdx += 3) {\n                const p0 = setVertex(faceIdx + 0, triangle[0]);\n                const p1 = setVertex(faceIdx + 1, triangle[1]);\n                const p2 = setVertex(faceIdx + 2, triangle[2]);\n\n                if (math.compareVec3(p0, p1) || math.compareVec3(p1, p2) || math.compareVec3(p2, p0)) {\n                    continue; // skip degenerate triangle\n                }\n\n                const d0 = planeDist + math.dotVec3(planeN, p0);\n                const d1 = planeDist + math.dotVec3(planeN, p1);\n                const d2 = planeDist + math.dotVec3(planeN, p2);\n\n                if ((d0 !== 0) || (d1 !== 0) || (d2 !== 0)) {\n                    const i0 = (d0 * d1 <= 0) && addPosition(math.lerpVec3(d0 / (d0 - d1), 0, 1, p0, p1, tempVec3a), true);\n                    const i1 = (d1 * d2 <= 0) && addPosition(math.lerpVec3(d1 / (d1 - d2), 0, 1, p1, p2, tempVec3a), true);\n                    const i2 = (d2 * d0 <= 0) && addPosition(math.lerpVec3(d2 / (d2 - d0), 0, 1, p2, p0, tempVec3a), true);\n\n                    const p = (! cfg.onlyPosSliceWithUV) && tmpPositions;\n                    if (p) {\n                        p[0] = addPosition(p0);\n                        p[1] = addPosition(p1);\n                        p[2] = addPosition(p2);\n                    }\n\n                    if (i0 ? (i1 || i2) : (i1 && i2)) { // triangle intersected by the section plane\n                        unsortedSegment.push(i0 ? [ i0, i1 || i2 ] : [ i1, i2 ]);\n\n                        if (p) {\n                            if ((d0 === 0) && (d1 === 0)) {\n                                appendOnSide((d2 > 0) ? pos : neg, p);\n                            } else if ((d0 === 0) && (d2 === 0)) {\n                                appendOnSide((d1 > 0) ? pos : neg, p);\n                            } else if ((d1 === 0) && (d2 === 0)) {\n                                appendOnSide((d0 > 0) ? pos : neg, p);\n                            } else {\n                                const isPos = (i0 ? d0 : d1) > 0;\n                                const dst0 = isPos ? pos : neg;\n                                const dst1 = isPos ? neg : pos;\n                                const i = tmpIntersections;\n                                i[0] = i0;\n                                i[1] = i1;\n                                i[2] = i2;\n                                const ref = tmpReferences;\n                                if (i0) {\n                                    ref[0] = 0; ref[1] = 1; ref[2] = 2;\n                                } else {\n                                    ref[0] = 1; ref[1] = 2; ref[2] = 0;\n                                }\n                                if (i[ref[1]]) {\n                                    appendOnSide(dst0, [ p[ref[0]], i[ref[0]], p[ref[2]] ]);\n                                    appendOnSide(dst0, [ i[ref[0]], i[ref[1]], p[ref[2]] ]);\n                                    appendOnSide(dst1, [ i[ref[0]], p[ref[1]], i[ref[1]] ]);\n                                } else {\n                                    appendOnSide(dst0, [ p[ref[0]], i[ref[0]], i[ref[2]] ]);\n                                    appendOnSide(dst1, [ i[ref[0]], p[ref[1]], p[ref[2]] ]);\n                                    appendOnSide(dst1, [ i[ref[0]], p[ref[2]], i[ref[2]] ]);\n                                }\n                            }\n                        }\n                    } else if (p) {\n                        if ((d0 >= 0) && (d1 >= 0) && (d2 >= 0)) {\n                            appendOnSide(pos, p);\n                        } else if ((d0 <= 0) && (d1 <= 0) && (d2 <= 0)) {\n                            appendOnSide(neg, p);\n                        } else {\n                            debugger;\n                        }\n                    }\n                }\n            }\n\n            const endpointLoops = [ ];\n            while (unsortedSegment.length > 0) {\n                endpointLoops.push([ unsortedSegment[0][0], unsortedSegment[0][1] ]);\n                const curEndpoints = endpointLoops[endpointLoops.length - 1];\n                unsortedSegment.splice(0, 1);\n                while (unsortedSegment.length > 0) {\n                    const lastPoint = indexedPositions[curEndpoints[curEndpoints.length - 1]];\n                    const closest = { distSq: sqDistVec3(indexedPositions[curEndpoints[0]], lastPoint), idx: -1, side: -1 };\n                    unsortedSegment.forEach((seg, i) => {\n                        const distSq0 = sqDistVec3(indexedPositions[seg[0]], lastPoint);\n                        const distSq1 = sqDistVec3(indexedPositions[seg[1]], lastPoint);\n                        const distSq = Math.min(distSq0, distSq1);\n                        if (closest.distSq > distSq) {\n                            closest.distSq = distSq;\n                            closest.idx = i;\n                            closest.side = (distSq1 < distSq0) ? 1 : 0;\n                        }\n                    });\n\n                    if (closest.distSq < 1e-20) {\n                        const nextSegment = (closest.idx >= 0) && unsortedSegment[closest.idx];\n                        indexedPositions[nextSegment ? nextSegment[closest.side] : curEndpoints[0]] = lastPoint; // move the split face's (above) vertex to lastPoint, to not introduce gaps\n                        if (nextSegment) {\n                            unsortedSegment.splice(closest.idx, 1);\n                            const nextEnd = nextSegment[1 - closest.side];\n                            if (sqDistVec3(indexedPositions[nextEnd], indexedPositions[curEndpoints[0]]) > 1e-20) {\n                                curEndpoints.push(nextEnd);\n                            } else {\n                                break;\n                            }\n                        } else {\n                            break;\n                        }\n                    } else {\n                        endpointLoops.pop(); // Could not find a matching segment. Discard a loop that cannot be closed.\n                        break;\n                    }\n                }\n            }\n\n            const loops = endpointLoops.filter(endPoints => endPoints.length > 2).map((endPoints, idx) => {\n                let doubleArea = 0;\n                const aabb = math.collapseAABB2(math.AABB2());\n                for (let i = 0; i < endPoints.length; i++) {\n                    getCoord2D(endPoints[i], tempVec2a);\n                    math.expandAABB2Point2(aabb, tempVec2a);\n                    getCoord2D(endPoints[(i + 1) % endPoints.length], tempVec2b);\n                    doubleArea += (tempVec2a[0] * tempVec2b[1] - tempVec2b[0] * tempVec2a[1]);\n                }\n                return {\n                    boundingBox: aabb,\n                    doubleArea: Math.abs(doubleArea),\n                    endPoints: endPoints\n                };\n            }).sort((a, b) => b.doubleArea - a.doubleArea);\n\n            while (loops.length > 0) {\n                const vertices2D = [ ];\n                const vertices3D = [ ];\n\n                const appendLoopVertices = loop => loop.endPoints.forEach(endpoint2D => {\n                    getCoord2D(endpoint2D, tempVec2a);\n                    vertices2D.push(tempVec2a[0], tempVec2a[1]);\n                    vertices3D.push(endpoint2D);\n                });\n\n                const outerLoop = loops.shift();\n                appendLoopVertices(outerLoop);\n\n                const innerLoops = [ ];\n                let innerLoopIdx = 0;\n                while (innerLoopIdx < loops.length) {\n                    const loop = loops[innerLoopIdx];\n                    if (isLoopInside(loop, outerLoop) && innerLoops.every(inner => !isLoopInside(loop, inner))) {\n                        loop.index = vertices2D.length / 2;\n                        appendLoopVertices(loop);\n                        innerLoops.push(loop);\n                        loops.splice(innerLoopIdx, 1);\n                    } else {\n                        ++innerLoopIdx;\n                    }\n                }\n\n                // Triangulate\n                const triangles = earcut(vertices2D, innerLoops.map(loop => loop.index));\n\n                for (let i = 0; i < triangles.length; i += 3) {\n                    const ti = tmpIntersections;\n                    ti[0] = vertices3D[triangles[i + 0]];\n                    ti[1] = vertices3D[triangles[i + 1]];\n                    ti[2] = vertices3D[triangles[i + 2]];\n                    const v0 = indexedPositions[ti[0]];\n                    math.subVec3(indexedPositions[ti[1]], v0, tempVec3b);\n                    math.subVec3(indexedPositions[ti[2]], v0, tempVec3c);\n                    math.normalizeVec3(math.cross3Vec3(tempVec3b, tempVec3c, tempVec3c), tempVec3c);\n                    const facedPositively = math.dotVec3(tempVec3c, planeN) <= 0;\n                    appendOnSide(facedPositively ? pos : neg, ti, tempVec3c);\n                    const tmp = ti[0]; ti[0] = ti[2]; ti[2] = tmp;\n                    appendOnSide(facedPositively ? neg : pos, ti, math.negateVec3(tempVec3c, tempVec3c));\n                }\n            }\n\n            const side = src => src && (src.indices.length > 0) && (function() {\n                const positions = [ ];\n                const uv = cfg.onlyPosSliceWithUV && [ ];\n                src.indices.forEach(idx => {\n                    const P = indexedPositions[idx];\n                    positions.push(P[0], P[1], P[2]);\n                    uv && uv.push(P[3], P[4]);\n                });\n                return { indices: iota(src.indices.length), positions: positions, normals: src.normals, uv: uv };\n            })();\n            return { pos: side(pos), neg: side(neg) };\n        };\n    };\n})();\n\nconst MAX_KD_TREE_DEPTH$1 = 15; // Increase if greater precision needed\nconst kdTreeDimLength$1 = new Float32Array(3);\n\n/**\n * Automatically indexes a {@link Viewer}'s {@link Entity}s in a 3D k-d tree\n * to support fast collision detection with 3D World-space axis-aligned boundaries (AABBs) and frustums.\n *\n * See {@link MarqueePicker} for usage example.\n *\n * An ObjectsKdTree3 is configured with a Viewer, and will then automatically\n * keep itself populated with k-d nodes that contain the Viewer's Entitys.\n *\n * We can then traverse the k-d nodes, starting at {@link ObjectsKdTree3#root}, to find\n * the contained Entities.\n */\nclass ObjectsKdTree3 {\n\n    /**\n     * Creates an ObjectsKdTree3.\n     *\n     * @param {*} cfg Configuration\n     * @param {Viewer} cfg.viewer The Viewer that provides the {@link Entity}s in this ObjectsKdTree3.\n     * @param {number} [cfg.maxTreeDepth=15] Optional maximum depth for the k-d tree.\n     */\n    constructor(cfg) {\n\n        if (!cfg) {\n            throw \"Parameter expected: cfg\";\n        }\n\n        if (!cfg.viewer) {\n            throw \"Parameter expected: cfg.viewer\";\n        }\n\n        this.viewer = cfg.viewer;\n\n        this._maxTreeDepth = cfg.maxTreeDepth || MAX_KD_TREE_DEPTH$1;\n        this._root = null;\n        this._needsRebuild = true;\n\n        this._onModelLoaded = this.viewer.scene.on(\"modelLoaded\", (modelId) => {\n            this._needsRebuild = true;\n        });\n\n        this._onModelUnloaded = this.viewer.scene.on(\"modelUnloaded\", (modelId) => {\n            this._needsRebuild = true;\n        });\n    }\n\n    /**\n     * Gets the root ObjectsKdTree3 node.\n     *\n     * Each time this accessor is accessed, it will lazy-rebuild the ObjectsKdTree3\n     * if {@link Entity}s have been created or removed in the {@link Viewer} since the last time it was accessed.\n     */\n    get root() {\n        if (this._needsRebuild) {\n            this._rebuild();\n        }\n        return this._root;\n    }\n\n    _rebuild() {\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const depth = 0;\n        this._root = {\n            aabb: scene.getAABB()\n        };\n        for (let objectId in scene.objects) {\n            const entity = scene.objects[objectId];\n            this._insertEntity(this._root, entity, depth + 1);\n        }\n        this._needsRebuild = false;\n    }\n\n    _insertEntity(node, entity, depth) {\n\n        const entityAABB = entity.aabb;\n\n        if (depth >= this._maxTreeDepth) {\n            node.entities = node.entities || [];\n            node.entities.push(entity);\n            return;\n        }\n        if (node.left) {\n            if (math.containsAABB3(node.left.aabb, entityAABB)) {\n                this._insertEntity(node.left, entity, depth + 1);\n                return;\n            }\n        }\n        if (node.right) {\n            if (math.containsAABB3(node.right.aabb, entityAABB)) {\n                this._insertEntity(node.right, entity, depth + 1);\n                return;\n            }\n        }\n        const nodeAABB = node.aabb;\n        kdTreeDimLength$1[0] = nodeAABB[3] - nodeAABB[0];\n        kdTreeDimLength$1[1] = nodeAABB[4] - nodeAABB[1];\n        kdTreeDimLength$1[2] = nodeAABB[5] - nodeAABB[2];\n        let dim = 0;\n        if (kdTreeDimLength$1[1] > kdTreeDimLength$1[dim]) {\n            dim = 1;\n        }\n        if (kdTreeDimLength$1[2] > kdTreeDimLength$1[dim]) {\n            dim = 2;\n        }\n        if (!node.left) {\n            const aabbLeft = nodeAABB.slice();\n            aabbLeft[dim + 3] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0);\n            node.left = {\n                aabb: aabbLeft\n            };\n            if (math.containsAABB3(aabbLeft, entityAABB)) {\n                this._insertEntity(node.left, entity, depth + 1);\n                return;\n            }\n        }\n        if (!node.right) {\n            const aabbRight = nodeAABB.slice();\n            aabbRight[dim] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0);\n            node.right = {\n                aabb: aabbRight\n            };\n            if (math.containsAABB3(aabbRight, entityAABB)) {\n                this._insertEntity(node.right, entity, depth + 1);\n                return;\n            }\n        }\n        node.entities = node.entities || [];\n        node.entities.push(entity);\n    }\n\n    /**\n     * Destroys this ObjectsKdTree3.\n     *\n     * Does not destroy the {@link Viewer} given to the constructor of the ObjectsKdTree3.\n     */\n    destroy() {\n        const scene = this.viewer.scene;\n        scene.off(this._onModelLoaded);\n        scene.off(this._onModelUnloaded);\n        this._root = null;\n        this._needsRebuild = true;\n    }\n}\n\n// Fast queue that avoids using potentially inefficient array .shift() calls\n// Based on https://github.com/creationix/fastqueue\n\n/** @private */\nclass Queue {\n\n    constructor() {\n\n        this._head = [];\n        this._headLength = 0;\n        this._tail = [];\n        this._index = 0;\n        this._length = 0;\n    }\n\n    get length() {\n        return this._length;\n    }\n\n    shift() {\n        if (this._index >= this._headLength) {\n            const t = this._head;\n            t.length = 0;\n            this._head = this._tail;\n            this._tail = t;\n            this._index = 0;\n            this._headLength = this._head.length;\n            if (!this._headLength) {\n                return;\n            }\n        }\n        const value = this._head[this._index];\n        if (this._index < 0) {\n            delete this._head[this._index++];\n        }\n        else {\n            this._head[this._index++] = undefined;\n        }\n        this._length--;\n        return value;\n    }\n\n    push(item) {\n        this._length++;\n        this._tail.push(item);\n        return this;\n    };\n\n    unshift(item) {\n        this._head[--this._index] = item;\n        this._length++;\n        return this;\n    }\n}\n\n/**\n * xeokit runtime statistics.\n * @type {{components: {models: number, objects: number, scenes: number, meshes: number}, memory: {indices: number, uvs: number, textures: number, materials: number, transforms: number, positions: number, programs: number, normals: number, meshes: number, colors: number}, build: {version: string}, client: {browser: string}, frame: {frameCount: number, useProgram: number, bindTexture: number, drawElements: number, bindArray: number, tasksRun: number, fps: number, drawArrays: number, tasksScheduled: number}}}\n */\nconst stats = {\n    build: {\n        version: \"0.8\"\n    },\n    client: {\n        browser: (navigator && navigator.userAgent) ? navigator.userAgent : \"n/a\"\n    },\n\n    components: {\n        scenes: 0,\n        models: 0,\n        meshes: 0,\n        objects: 0\n    },\n    memory: {\n        meshes: 0,\n        positions: 0,\n        colors: 0,\n        normals: 0,\n        uvs: 0,\n        indices: 0,\n        textures: 0,\n        transforms: 0,\n        materials: 0,\n        programs: 0\n    },\n    frame: {\n        frameCount: 0,\n        fps: 0,\n        useProgram: 0,\n        bindTexture: 0,\n        bindArray: 0,\n        drawElements: 0,\n        drawArrays: 0,\n        tasksRun: 0,\n        tasksScheduled: 0\n    }\n};\n\n/**\n * @private\n */\n\nfunction xmlToJson(node, attributeRenamer) {\n    if (node.nodeType === node.TEXT_NODE) {\n        var v = node.nodeValue;\n        if (v.match(/^\\s+$/) === null) {\n            return v;\n        }\n    } else if (node.nodeType === node.ELEMENT_NODE ||\n        node.nodeType === node.DOCUMENT_NODE) {\n        var json = {type: node.nodeName, children: []};\n\n        if (node.nodeType === node.ELEMENT_NODE) {\n            for (var j = 0; j < node.attributes.length; j++) {\n                var attribute = node.attributes[j];\n                var nm = attributeRenamer[attribute.nodeName] || attribute.nodeName;\n                json[nm] = attribute.nodeValue;\n            }\n        }\n\n        for (var i = 0; i < node.childNodes.length; i++) {\n            var item = node.childNodes[i];\n            var j = xmlToJson(item, attributeRenamer);\n            if (j) json.children.push(j);\n        }\n\n        return json;\n    }\n}\n\n/**\n * @private\n */\nfunction clone(ob) {\n    return JSON.parse(JSON.stringify(ob));\n}\n\n/**\n * @private\n */\nvar guidChars = [[\"0\", 10], [\"A\", 26], [\"a\", 26], [\"_\", 1], [\"$\", 1]].map(function (a) {\n    var li = [];\n    var st = a[0].charCodeAt(0);\n    var en = st + a[1];\n    for (var i = st; i < en; ++i) {\n        li.push(i);\n    }\n    return String.fromCharCode.apply(null, li);\n}).join(\"\");\n\n/**\n * @private\n */\nfunction b64(v, len) {\n    var r = (!len || len === 4) ? [0, 6, 12, 18] : [0, 6];\n    return r.map(function (i) {\n        return guidChars.substr(parseInt(v / (1 << i)) % 64, 1)\n    }).reverse().join(\"\");\n}\n\n/**\n * @private\n */\nfunction compressGuid(g) {\n    var bs = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30].map(function (i) {\n        return parseInt(g.substr(i, 2), 16);\n    });\n    return b64(bs[0], 2) + [1, 4, 7, 10, 13].map(function (i) {\n        return b64((bs[i] << 16) + (bs[i + 1] << 8) + bs[i + 2]);\n    }).join(\"\");\n}\n\n/**\n * @private\n */\nfunction findNodeOfType(m, t) {\n    var li = [];\n    var _ = function (n) {\n        if (n.type === t) li.push(n);\n        (n.children || []).forEach(function (c) {\n            _(c);\n        });\n    };\n    _(m);\n    return li;\n}\n\n/**\n * @private\n */\nfunction timeout(dt) {\n    return new Promise(function (resolve, reject) {\n        setTimeout(resolve, dt);\n    });\n}\n\n/**\n * @private\n */\nfunction httpRequest(args) {\n    return new Promise(function (resolve, reject) {\n        var xhr = new XMLHttpRequest();\n        xhr.open(args.method || \"GET\", args.url, true);\n        xhr.onload = function (e) {\n            if (xhr.readyState === 4) {\n                if (xhr.status === 200) {\n                    resolve(xhr.responseXML);\n                } else {\n                    reject(xhr.statusText);\n                }\n            }\n        };\n        xhr.send(null);\n    });\n}\n\n/**\n * @private\n */\nconst queryString = function () {\n    // This function is anonymous, is executed immediately and\n    // the return value is assigned to QueryString!\n    var query_string = {};\n    var query = window.location.search.substring(1);\n    var vars = query.split(\"&\");\n    for (var i = 0; i < vars.length; i++) {\n        var pair = vars[i].split(\"=\");\n        // If first entry with this name\n        if (typeof query_string[pair[0]] === \"undefined\") {\n            query_string[pair[0]] = decodeURIComponent(pair[1]);\n            // If second entry with this name\n        } else if (typeof query_string[pair[0]] === \"string\") {\n            var arr = [query_string[pair[0]], decodeURIComponent(pair[1])];\n            query_string[pair[0]] = arr;\n            // If third or later entry with this name\n        } else {\n            query_string[pair[0]].push(decodeURIComponent(pair[1]));\n        }\n    }\n    return query_string;\n}();\n\n/**\n * @private\n */\nfunction loadJSON(url, ok, err) {\n    // Avoid checking ok and err on each use.\n    var defaultCallback = (_value) => undefined;\n    ok = ok || defaultCallback;\n    err = err || defaultCallback;\n\n    var request = new XMLHttpRequest();\n    request.overrideMimeType(\"application/json\");\n    request.open('GET', url, true);\n    request.addEventListener('load', function (event) {\n        var response = event.target.response;\n        if (this.status === 200) {\n            var json;\n            try {\n                json = JSON.parse(response);\n            } catch (e) {\n                err(`utils.loadJSON(): Failed to parse JSON response - ${e}`);\n            }\n            ok(json);\n        } else if (this.status === 0) {\n            // Some browsers return HTTP Status 0 when using non-http protocol\n            // e.g. 'file://' or 'data://'. Handle as success.\n            console.warn('loadFile: HTTP Status 0 received.');\n            try {\n                ok(JSON.parse(response));\n            } catch (e) {\n                err(`utils.loadJSON(): Failed to parse JSON response - ${e}`);\n            }\n        } else {\n            err(event);\n        }\n    }, false);\n\n    request.addEventListener('error', function (event) {\n        err(event);\n    }, false);\n    request.send(null);\n}\n\n/**\n * @private\n */\nfunction loadArraybuffer$1(url, ok, err) {\n    // Check for data: URI\n    var defaultCallback = (_value) => undefined;\n    ok = ok || defaultCallback;\n    err = err || defaultCallback;\n    const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n    const dataUriRegexResult = url.match(dataUriRegex);\n    if (dataUriRegexResult) { // Safari can't handle data URIs through XMLHttpRequest\n        const isBase64 = !!dataUriRegexResult[2];\n        var data = dataUriRegexResult[3];\n        data = window.decodeURIComponent(data);\n        if (isBase64) {\n            data = window.atob(data);\n        }\n        try {\n            const buffer = new ArrayBuffer(data.length);\n            const view = new Uint8Array(buffer);\n            for (var i = 0; i < data.length; i++) {\n                view[i] = data.charCodeAt(i);\n            }\n            core.scheduleTask(() => {\n                ok(buffer);\n            });\n        } catch (error) {\n            core.scheduleTask(() => {\n                err(error);\n            });\n        }\n    } else {\n        const request = new XMLHttpRequest();\n        request.open('GET', url, true);\n        request.responseType = 'arraybuffer';\n        request.onreadystatechange = function () {\n            if (request.readyState === 4) {\n                if (request.status === 200) {\n                    ok(request.response);\n                } else {\n                    err('loadArrayBuffer error : ' + request.response);\n                }\n            }\n        };\n        request.send(null);\n    }\n}\n\n/**\n Tests if the given object is an array\n @private\n */\nfunction isArray$1(value) {\n    return value && !(value.propertyIsEnumerable('length')) && typeof value === 'object' && typeof value.length === 'number';\n}\n\n/**\n Tests if the given value is a string\n @param value\n @returns {Boolean}\n @private\n */\nfunction isString(value) {\n    return (typeof value === 'string' || value instanceof String);\n}\n\n/**\n Tests if the given value is a number\n @param value\n @returns {Boolean}\n @private\n */\nfunction isNumeric(value) {\n    return !isNaN(parseFloat(value)) && isFinite(value);\n}\n\n/**\n Tests if the given value is an ID\n @param value\n @returns {Boolean}\n @private\n */\nfunction isID(value) {\n    return utils.isString(value) || utils.isNumeric(value);\n}\n\n/**\n Tests if the given components are the same, where the components can be either IDs or instances.\n @param c1\n @param c2\n @returns {Boolean}\n @private\n */\nfunction isSameComponent(c1, c2) {\n    if (!c1 || !c2) {\n        return false;\n    }\n    const id1 = (utils.isNumeric(c1) || utils.isString(c1)) ? `${c1}` : c1.id;\n    const id2 = (utils.isNumeric(c2) || utils.isString(c2)) ? `${c2}` : c2.id;\n    return id1 === id2;\n}\n\n/**\n Tests if the given value is a function\n @param value\n @returns {Boolean}\n @private\n */\nfunction isFunction$1(value) {\n    return (typeof value === \"function\");\n}\n\n/**\n Tests if the given value is a JavaScript JSON object, eg, ````{ foo: \"bar\" }````.\n @param value\n @returns {Boolean}\n @private\n */\nfunction isObject$1(value) {\n    const objectConstructor = {}.constructor;\n    return (!!value && value.constructor === objectConstructor);\n}\n\n/** Returns a shallow copy\n */\nfunction copy(o) {\n    return utils.apply(o, {});\n}\n\n/** Add properties of o to o2, overwriting them on o2 if already there\n */\nfunction apply(o, o2) {\n    for (const name in o) {\n        if (o.hasOwnProperty(name)) {\n            o2[name] = o[name];\n        }\n    }\n    return o2;\n}\n\n/**\n Add non-null/defined properties of o to o2\n @private\n */\nfunction apply2(o, o2) {\n    for (const name in o) {\n        if (o.hasOwnProperty(name)) {\n            if (o[name] !== undefined && o[name] !== null) {\n                o2[name] = o[name];\n            }\n        }\n    }\n    return o2;\n}\n\n/**\n Add properties of o to o2 where undefined or null on o2\n @private\n */\nfunction applyIf(o, o2) {\n    for (const name in o) {\n        if (o.hasOwnProperty(name)) {\n            if (o2[name] === undefined || o2[name] === null) {\n                o2[name] = o[name];\n            }\n        }\n    }\n    return o2;\n}\n\n/**\n Returns true if the given map is empty.\n @param obj\n @returns {Boolean}\n @private\n */\nfunction isEmptyObject$1(obj) {\n    for (const name in obj) {\n        if (obj.hasOwnProperty(name)) {\n            return false;\n        }\n    }\n    return true;\n}\n\n/**\n Returns the given ID as a string, in quotes if the ID was a string to begin with.\n\n This is useful for logging IDs.\n\n @param {Number| String} id The ID\n @returns {String}\n @private\n */\nfunction inQuotes(id) {\n    return utils.isNumeric(id) ? (`${id}`) : (`'${id}'`);\n}\n\n/**\n Returns the concatenation of two typed arrays.\n @param a\n @param b\n @returns {*|a}\n @private\n */\nfunction concat(a, b) {\n    const c = new a.constructor(a.length + b.length);\n    c.set(a);\n    c.set(b, a.length);\n    return c;\n}\n\nfunction flattenParentChildHierarchy(root) {\n    var list = [];\n\n    function visit(node) {\n        node.id = node.uuid;\n        delete node.oid;\n        list.push(node);\n        var children = node.children;\n\n        if (children) {\n            for (var i = 0, len = children.length; i < len; i++) {\n                const child = children[i];\n                child.parent = node.id;\n                visit(children[i]);\n            }\n        }\n        node.children = [];\n    }\n\n    visit(root);\n    return list;\n}\n\n/**\n * @private\n */\nconst utils = {\n    xmlToJson: xmlToJson,\n    clone: clone,\n    compressGuid: compressGuid,\n    findNodeOfType: findNodeOfType,\n    timeout: timeout,\n    httpRequest: httpRequest,\n    loadJSON: loadJSON,\n    loadArraybuffer: loadArraybuffer$1,\n    queryString: queryString,\n    isArray: isArray$1,\n    isString: isString,\n    isNumeric: isNumeric,\n    isID: isID,\n    isSameComponent: isSameComponent,\n    isFunction: isFunction$1,\n    isObject: isObject$1,\n    copy: copy,\n    apply: apply,\n    apply2: apply2,\n    applyIf: applyIf,\n    isEmptyObject: isEmptyObject$1,\n    inQuotes: inQuotes,\n    concat: concat,\n    flattenParentChildHierarchy: flattenParentChildHierarchy\n};\n\nconst scenesRenderInfo = {}; // Used for throttling FPS for each Scene\nconst sceneIDMap = new Map$1(); // Ensures unique scene IDs\nconst taskQueue = new Queue(); // Task queue, which is pumped on each frame; tasks are pushed to it with calls to xeokit.schedule\nconst tickEvent = {sceneId: null, time: null, startTime: null, prevTime: null, deltaTime: null};\nconst taskBudget = 10; // Millisecs we're allowed to spend on tasks in each frame\nconst fpsSamples = [];\nconst numFPSSamples = 30;\n\nlet lastTime = 0;\nlet elapsedTime;\nlet totalFPS = 0;\n\n\n/**\n * @private\n */\nfunction Core() {\n\n    /**\n     Semantic version number. The value for this is set by an expression that's concatenated to\n     the end of the built binary by the xeokit build script.\n     @property version\n     @namespace xeokit\n     @type {String}\n     */\n    this.version = \"1.0.0\";\n\n    /**\n     Existing {@link Scene}s , mapped to their IDs\n     @property scenes\n     @namespace xeokit\n     @type {Scene}\n     */\n    this.scenes = {};\n\n    this._superTypes = {}; // For each component type, a list of its supertypes, ordered upwards in the hierarchy.\n\n    /**\n     * Registers a scene on xeokit.\n     * This is called within the xeokit.Scene constructor.\n     * @private\n     */\n    this._addScene = function (scene) {\n        if (scene.id) { // User-supplied ID\n            if (core.scenes[scene.id]) {\n                console.error(`[ERROR] Scene ${utils.inQuotes(scene.id)} already exists`);\n                return;\n            }\n        } else { // Auto-generated ID\n            scene.id = sceneIDMap.addItem({});\n        }\n        core.scenes[scene.id] = scene;\n        const ticksPerOcclusionTest = scene.ticksPerOcclusionTest;\n        const ticksPerRender = scene.ticksPerRender;\n        scenesRenderInfo[scene.id] = {\n            ticksPerOcclusionTest: ticksPerOcclusionTest,\n            ticksPerRender: ticksPerRender,\n            renderCountdown: ticksPerRender\n        };\n        stats.components.scenes++;\n        scene.once(\"destroyed\", () => { // Unregister destroyed scenes\n            sceneIDMap.removeItem(scene.id);\n            delete core.scenes[scene.id];\n            delete scenesRenderInfo[scene.id];\n            stats.components.scenes--;\n        });\n    };\n\n    /**\n     * @private\n     */\n    this.clear = function () {\n        let scene;\n        for (const id in core.scenes) {\n            if (core.scenes.hasOwnProperty(id)) {\n                scene = core.scenes[id];\n                // Only clear the default Scene\n                // but destroy all the others\n                if (id === \"default.scene\") {\n                    scene.clear();\n                } else {\n                    scene.destroy();\n                    delete core.scenes[scene.id];\n                }\n            }\n        }\n    };\n\n    /**\n     * Schedule a task to run at the next frame.\n     *\n     * Internally, this pushes the task to a FIFO queue. Within each frame interval, xeokit processes the queue\n     * for a certain period of time, popping tasks and running them. After each frame interval, tasks that did not\n     * get a chance to run during the task are left in the queue to be run next time.\n     *\n     * @param {Function} callback Callback that runs the task.\n     * @param {Object} [scope] Scope for the callback.\n     */\n    this.scheduleTask = function (callback, scope = null) {\n        taskQueue.push(callback);\n        taskQueue.push(scope);\n    };\n\n    this.runTasks = function (until = -1) { // Pops and processes tasks in the queue, until the given number of milliseconds has elapsed.\n        let time = (new Date()).getTime();\n        let callback;\n        let scope;\n        let tasksRun = 0;\n        while (taskQueue.length > 0 && (until < 0 || time < until)) {\n            callback = taskQueue.shift();\n            scope = taskQueue.shift();\n            if (scope) {\n                callback.call(scope);\n            } else {\n                callback();\n            }\n            time = (new Date()).getTime();\n            tasksRun++;\n        }\n        return tasksRun;\n    };\n\n    this.getNumTasks = function () {\n        return taskQueue.length;\n    };\n}\n\n/**\n * @private\n * @type {Core}\n */\nconst core = new Core();\n\nconst frame = function () {\n    let time = Date.now();\n    elapsedTime = time - lastTime;\n    if (lastTime > 0 && elapsedTime > 0) { // Log FPS stats\n        var newFPS = 1000 / elapsedTime; // Moving average of FPS\n        totalFPS += newFPS;\n        fpsSamples.push(newFPS);\n        if (fpsSamples.length >= numFPSSamples) {\n            totalFPS -= fpsSamples.shift();\n        }\n        stats.frame.fps = Math.round(totalFPS / fpsSamples.length);\n    }\n    for (let id in core.scenes) {\n        core.scenes[id].compile();\n    }\n    runTasks(time);\n    lastTime = time;\n};\n\nfunction customSetInterval(callback, interval) {\n    let expected = Date.now() + interval;\n    function loop() {\n        const elapsed = Date.now() - expected;\n        callback();\n        expected += interval;\n        setTimeout(loop, Math.max(0, interval - elapsed));\n    }\n    loop();\n    return {\n        cancel: function() {\n            // No need to do anything, setTimeout cannot be directly cancelled\n        }\n    };\n}\n\ncustomSetInterval(() => {\n    frame();\n}, 100);\n\nconst renderFrame = function () {\n    let time = Date.now();\n    elapsedTime = time - lastTime;\n    if (lastTime > 0 && elapsedTime > 0) { // Log FPS stats\n        var newFPS = 1000 / elapsedTime; // Moving average of FPS\n        totalFPS += newFPS;\n        fpsSamples.push(newFPS);\n        if (fpsSamples.length >= numFPSSamples) {\n            totalFPS -= fpsSamples.shift();\n        }\n        stats.frame.fps = Math.round(totalFPS / fpsSamples.length);\n    }\n    runTasks(time);\n    fireTickEvents(time);\n    renderScenes();\n    (window.requestPostAnimationFrame !== undefined) ? window.requestPostAnimationFrame(frame) : requestAnimationFrame(renderFrame);\n};\n\nrenderFrame();\n\nfunction runTasks(time) { // Process as many enqueued tasks as we can within the per-frame task budget\n    const tasksRun = core.runTasks(time + taskBudget);\n    const tasksScheduled = core.getNumTasks();\n    stats.frame.tasksRun = tasksRun;\n    stats.frame.tasksScheduled = tasksScheduled;\n    stats.frame.tasksBudget = taskBudget;\n}\n\nfunction fireTickEvents(time) { // Fire tick event on each Scene\n    tickEvent.time = time;\n    for (var id in core.scenes) {\n        if (core.scenes.hasOwnProperty(id)) {\n            var scene = core.scenes[id];\n            tickEvent.sceneId = id;\n            tickEvent.startTime = scene.startTime;\n            tickEvent.deltaTime = tickEvent.prevTime != null ? tickEvent.time - tickEvent.prevTime : 0;\n            /**\n             * Fired on each game loop iteration.\n             *\n             * @event tick\n             * @param {String} sceneID The ID of this Scene.\n             * @param {Number} startTime The time in seconds since 1970 that this Scene was instantiated.\n             * @param {Number} time The time in seconds since 1970 of this \"tick\" event.\n             * @param {Number} prevTime The time of the previous \"tick\" event from this Scene.\n             * @param {Number} deltaTime The time in seconds since the previous \"tick\" event from this Scene.\n             */\n            scene.fire(\"tick\", tickEvent, true);\n        }\n    }\n    tickEvent.prevTime = time;\n}\n\nfunction renderScenes() {\n    const scenes = core.scenes;\n    const forceRender = false;\n    let scene;\n    let renderInfo;\n    let ticksPerOcclusionTest;\n    let ticksPerRender;\n    let id;\n    for (id in scenes) {\n        if (scenes.hasOwnProperty(id)) {\n\n            scene = scenes[id];\n            renderInfo = scenesRenderInfo[id];\n\n            if (!renderInfo) {\n                renderInfo = scenesRenderInfo[id] = {}; // FIXME\n            }\n\n            ticksPerOcclusionTest = scene.ticksPerOcclusionTest;\n            if (renderInfo.ticksPerOcclusionTest !== ticksPerOcclusionTest) {\n                renderInfo.ticksPerOcclusionTest = ticksPerOcclusionTest;\n                renderInfo.renderCountdown = ticksPerOcclusionTest;\n            }\n            if (--scene.occlusionTestCountdown <= 0) {\n                scene.doOcclusionTest();\n                scene.occlusionTestCountdown = ticksPerOcclusionTest;\n            }\n\n            ticksPerRender = scene.ticksPerRender;\n            if (renderInfo.ticksPerRender !== ticksPerRender) {\n                renderInfo.ticksPerRender = ticksPerRender;\n                renderInfo.renderCountdown = ticksPerRender;\n            }\n            if (--renderInfo.renderCountdown === 0) {\n                scene.render(forceRender);\n                renderInfo.renderCountdown = ticksPerRender;\n            }\n        }\n    }\n}\n\n/**\n * @desc Base class for all xeokit components.\n *\n * ## Component IDs\n *\n * Every Component has an ID that's unique within the parent {@link Scene}. xeokit generates\n * the IDs automatically by default, however you can also specify them yourself. In the example below, we're creating a\n * scene comprised of {@link Scene}, {@link Material}, {@link ReadableGeometry} and\n * {@link Mesh} components, while letting xeokit generate its own ID for\n * the {@link ReadableGeometry}:\n *\n *````JavaScript\n * import {Viewer, Mesh, buildTorusGeometry, ReadableGeometry, PhongMaterial, Texture, Fresnel} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *        canvasId: \"myCanvas\"\n *    });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry({\n *          center: [0, 0, 0],\n *          radius: 1.5,\n *          tube: 0.5,\n *          radialSegments: 32,\n *          tubeSegments: 24,\n *          arc: Math.PI * 2.0\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *          id: \"myMaterial\",\n *          ambient: [0.9, 0.3, 0.9],\n *          shininess: 30,\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse/uvGrid2.jpg\"\n *          }),\n *          specularFresnel: new Fresnel(viewer.scene, {\n *              leftColor: [1.0, 1.0, 1.0],\n *              rightColor: [0.0, 0.0, 0.0],\n *              power: 4\n *          })\n *     })\n * });\n *````\n *\n * We can then find those components like this:\n *\n * ````javascript\n * // Find the Material\n * var material = viewer.scene.components[\"myMaterial\"];\n *\n * // Find all PhongMaterials in the Scene\n * var phongMaterials = viewer.scene.types[\"PhongMaterial\"];\n *\n * // Find our Material within the PhongMaterials\n * var materialAgain = phongMaterials[\"myMaterial\"];\n * ````\n *\n * ## Restriction on IDs\n *\n * Auto-generated IDs are of the form ````\"__0\"````, ````\"__1\"````, ````\"__2\"```` ... and so on.\n *\n * Scene maintains a map of these IDs, along with a counter that it increments each time it generates a new ID.\n *\n * If Scene has created the IDs listed above, and we then destroy the ````Component```` with ID ````\"__1\"````,\n * Scene will mark that ID as available, and will reuse it for the next default ID.\n *\n * Therefore, two restrictions your on IDs:\n *\n * * don't use IDs that begin with two underscores, and\n * * don't reuse auto-generated IDs of destroyed Components.\n *\n * ## Logging\n *\n * Components have methods to log ID-prefixed messages to the JavaScript console:\n *\n * ````javascript\n * material.log(\"Everything is fine, situation normal.\");\n * material.warn(\"Wait, whats that red light?\");\n * material.error(\"Aw, snap!\");\n * ````\n *\n * The logged messages will look like this in the console:\n *\n * ````text\n * [LOG]   myMaterial: Everything is fine, situation normal.\n * [WARN]  myMaterial: Wait, whats that red light..\n * [ERROR] myMaterial: Aw, snap!\n * ````\n *\n * ## Destruction\n *\n * Get notification of destruction of Components:\n *\n * ````javascript\n * material.once(\"destroyed\", function() {\n *     this.log(\"Component was destroyed: \" + this.id);\n * });\n * ````\n *\n * Or get notification of destruction of any Component within its {@link Scene}:\n *\n * ````javascript\n * scene.on(\"componentDestroyed\", function(component) {\n *     this.log(\"Component was destroyed: \" + component.id);\n * });\n * ````\n *\n * Then destroy a component like this:\n *\n * ````javascript\n * material.destroy();\n * ````\n */\nclass Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Component\";\n    }\n\n    /**\n     * @private\n     */\n    get isComponent() {\n        return true;\n    }\n\n    constructor(owner = null, cfg = {}) {\n\n        /**\n         * The parent {@link Scene} that contains this Component.\n         *\n         * @property scene\n         * @type {Scene}\n         * @final\n         */\n        this.scene = null;\n\n        if (this.type === \"Scene\") {\n            this.scene = this;\n            /**\n             * The viewer that contains this Scene.\n             * @property viewer\n             * @type {Viewer}\n             */\n            this.viewer = cfg.viewer;\n        } else {\n            if (owner.type === \"Scene\") {\n                this.scene = owner;\n            } else if (owner instanceof Component) {\n                this.scene = owner.scene;\n            } else {\n                throw \"Invalid param: owner must be a Component\"\n            }\n            this._owner = owner;\n        }\n\n        this._dontClear = !!cfg.dontClear; // Prevent Scene#clear from destroying this component\n\n        this._renderer = this.scene._renderer;\n\n        /**\n         Arbitrary, user-defined metadata on this component.\n\n         @property metadata\n         @type Object\n         */\n        this.meta = cfg.meta || {};\n\n\n        /**\n         * ID of this Component, unique within the {@link Scene}.\n         *\n         * Components are mapped by this ID in {@link Scene#components}.\n         *\n         * @property id\n         * @type {String|Number}\n         */\n        this.id = cfg.id; // Auto-generated by Scene by default\n\n        /**\n         True as soon as this Component has been destroyed\n\n         @property destroyed\n         @type {Boolean}\n         */\n        this.destroyed = false;\n\n        this._attached = {}; // Attached components with names.\n        this._attachments = null; // Attached components keyed to IDs - lazy-instantiated\n        this._subIdMap = null; // Subscription subId pool\n        this._subIdEvents = null; // Subscription subIds mapped to event names\n        this._eventSubs = null; // Event names mapped to subscribers\n        this._eventSubsNum = null;\n        this._events = null; // Maps names to events\n        this._eventCallDepth = 0; // Helps us catch stack overflows from recursive events\n        this._ownedComponents = null; // // Components created with #create - lazy-instantiated\n\n        if (this !== this.scene) { // Don't add scene to itself\n            this.scene._addComponent(this); // Assigns this component an automatic ID if not yet assigned\n        }\n\n        this._updateScheduled = false; // True when #_update will be called on next tick\n\n        if (owner) {\n            owner._own(this);\n        }\n    }\n\n    // /**\n    //  * Unique ID for this Component within its {@link Scene}.\n    //  *\n    //  * @property\n    //  * @type {String}\n    //  */\n    // get id() {\n    //     return this._id;\n    // }\n\n    /**\n     Indicates that we need to redraw the scene.\n\n     This is called by certain subclasses after they have made some sort of state update that requires the\n     renderer to perform a redraw.\n\n     For example: a {@link Mesh} calls this on itself whenever you update its\n     {@link Mesh#layer} property, which manually controls its render order in\n     relation to other Meshes.\n\n     If this component has a ````castsShadow```` property that's set ````true````, then this will also indicate\n     that the renderer needs to redraw shadow map associated with this component. Components like\n     {@link DirLight} have that property set when they produce light that creates shadows, while\n     components like {@link Mesh\"}}layer{{/crossLink}} have that property set when they cast shadows.\n\n     @protected\n     */\n    glRedraw() {\n        if (!this._renderer) { // Called from a constructor\n            return;\n        }\n        this._renderer.imageDirty();\n        if (this.castsShadow) { // Light source or object\n            this._renderer.shadowsDirty();\n        }\n    }\n\n    /**\n     Indicates that we need to re-sort the renderer's state-ordered drawables list.\n\n     For efficiency, the renderer keeps its list of drawables ordered so that runs of the same state updates can be\n     combined.  This method is called by certain subclasses after they have made some sort of state update that would\n     require re-ordering of the drawables list.\n\n     For example: a {@link DirLight} calls this on itself whenever you update {@link DirLight#dir}.\n\n     @protected\n     */\n    glResort() {\n        if (!this._renderer) { // Called from a constructor\n            return;\n        }\n        this._renderer.needStateSort();\n    }\n\n    /**\n     * The {@link Component} that owns the lifecycle of this Component, if any.\n     *\n     * When that component is destroyed, this component will be automatically destroyed also.\n     *\n     * Will be null if this Component has no owner.\n     *\n     * @property owner\n     * @type {Component}\n     */\n    get owner() {\n        return this._owner;\n    }\n\n    /**\n     * Tests if this component is of the given type, or is a subclass of the given type.\n     * @type {Boolean}\n     */\n    isType(type) {\n        return this.type === type;\n    }\n\n    /**\n     * Fires an event on this component.\n     *\n     * Notifies existing subscribers to the event, optionally retains the event to give to\n     * any subsequent notifications on the event as they are made.\n     *\n     * @param {String} event The event type name\n     * @param {Object} value The event parameters\n     * @param {Boolean} [forget=false] When true, does not retain for subsequent subscribers\n     */\n    fire(event, value, forget) {\n        if (!this._events) {\n            this._events = {};\n        }\n        if (!this._eventSubs) {\n            this._eventSubs = {};\n            this._eventSubsNum = {};\n        }\n        if (forget !== true) {\n            this._events[event] = value || true; // Save notification\n        }\n        const subs = this._eventSubs[event];\n        let sub;\n        if (subs) { // Notify subscriptions\n            for (const subId in subs) {\n                if (subs.hasOwnProperty(subId)) {\n                    sub = subs[subId];\n                    this._eventCallDepth++;\n                    if (this._eventCallDepth < 300) {\n                        sub.callback.call(sub.scope, value);\n                    } else {\n                        this.error(\"fire: potential stack overflow from recursive event '\" + event + \"' - dropping this event\");\n                    }\n                    this._eventCallDepth--;\n                }\n            }\n        }\n    }\n\n    /**\n     * Subscribes to an event on this component.\n     *\n     * The callback is be called with this component as scope.\n     *\n     * @param {String} event The event\n     * @param {Function} callback Called fired on the event\n     * @param {Object} [scope=this] Scope for the callback\n     * @return {String} Handle to the subscription, which may be used to unsubscribe with {@link #off}.\n     */\n    on(event, callback, scope) {\n        if (!this._events) {\n            this._events = {};\n        }\n        if (!this._subIdMap) {\n            this._subIdMap = new Map$1(); // Subscription subId pool\n        }\n        if (!this._subIdEvents) {\n            this._subIdEvents = {};\n        }\n        if (!this._eventSubs) {\n            this._eventSubs = {};\n        }\n        if (!this._eventSubsNum) {\n            this._eventSubsNum = {};\n        }\n        let subs = this._eventSubs[event];\n        if (!subs) {\n            subs = {};\n            this._eventSubs[event] = subs;\n            this._eventSubsNum[event] = 1;\n        } else {\n            this._eventSubsNum[event]++;\n        }\n        const subId = this._subIdMap.addItem(); // Create unique subId\n        subs[subId] = {\n            callback: callback,\n            scope: scope || this\n        };\n        this._subIdEvents[subId] = event;\n        const value = this._events[event];\n        if (value !== undefined) { // A publication exists, notify callback immediately\n            callback.call(scope || this, value);\n        }\n        return subId;\n    }\n\n    /**\n     * Cancels an event subscription that was previously made with {@link Component#on} or {@link Component#once}.\n     *\n     * @param {String} subId Subscription ID\n     */\n    off(subId) {\n        if (subId === undefined || subId === null) {\n            return;\n        }\n        if (!this._subIdEvents) {\n            return;\n        }\n        const event = this._subIdEvents[subId];\n        if (event) {\n            delete this._subIdEvents[subId];\n            const subs = this._eventSubs[event];\n            if (subs) {\n                delete subs[subId];\n                this._eventSubsNum[event]--;\n            }\n            this._subIdMap.removeItem(subId); // Release subId\n        }\n    }\n\n    /**\n     * Subscribes to the next occurrence of the given event, then un-subscribes as soon as the event is subIdd.\n     *\n     * This is equivalent to calling {@link Component#on}, and then calling {@link Component#off} inside the callback function.\n     *\n     * @param {String} event Data event to listen to\n     * @param {Function} callback Called when fresh data is available at the event\n     * @param {Object} [scope=this] Scope for the callback\n     */\n    once(event, callback, scope) {\n        const self = this;\n        const subId = this.on(event,\n            function (value) {\n                self.off(subId);\n                callback.call(scope || this, value);\n            },\n            scope);\n    }\n\n    /**\n     * Returns true if there are any subscribers to the given event on this component.\n     *\n     * @param {String} event The event\n     * @return {Boolean} True if there are any subscribers to the given event on this component.\n     */\n    hasSubs(event) {\n        return (this._eventSubsNum && (this._eventSubsNum[event] > 0));\n    }\n\n    /**\n     * Logs a console debugging message for this component.\n     *\n     * The console message will have this format: *````[LOG] [<component type> <component id>: <message>````*\n     *\n     * Also fires the message as a \"log\" event on the parent {@link Scene}.\n     *\n     * @param {String} message The message to log\n     */\n    log(message) {\n        message = \"[LOG]\" + this._message(message);\n        window.console.log(message);\n        this.scene.fire(\"log\", message);\n    }\n\n    _message(message) {\n        return \" [\" + this.type + \" \" + utils.inQuotes(this.id) + \"]: \" + message;\n    }\n\n    /**\n     * Logs a warning for this component to the JavaScript console.\n     *\n     * The console message will have this format: *````[WARN] [<component type> =<component id>: <message>````*\n     *\n     * Also fires the message as a \"warn\" event on the parent {@link Scene}.\n     *\n     * @param {String} message The message to log\n     */\n    warn(message) {\n        message = \"[WARN]\" + this._message(message);\n        window.console.warn(message);\n        this.scene.fire(\"warn\", message);\n    }\n\n    /**\n     * Logs an error for this component to the JavaScript console.\n     *\n     * The console message will have this format: *````[ERROR] [<component type> =<component id>: <message>````*\n     *\n     * Also fires the message as an \"error\" event on the parent {@link Scene}.\n     *\n     * @param {String} message The message to log\n     */\n    error(message) {\n        message = \"[ERROR]\" + this._message(message);\n        window.console.error(message);\n        this.scene.fire(\"error\", message);\n    }\n\n    /**\n     * Adds a child component to this.\n     *\n     * When component not given, attaches the scene's default instance for the given name (if any).\n     * Publishes the new child component on this component, keyed to the given name.\n     *\n     * @param {*} params\n     * @param {String} params.name component name\n     * @param {Component} [params.component] The component\n     * @param {String} [params.type] Optional expected type of base type of the child; when supplied, will\n     * cause an exception if the given child is not the same type or a subtype of this.\n     * @param {Boolean} [params.sceneDefault=false]\n     * @param {Boolean} [params.sceneSingleton=false]\n     * @param {Function} [params.onAttached] Optional callback called when component attached\n     * @param {Function} [params.onAttached.callback] Callback function\n     * @param {Function} [params.onAttached.scope] Optional scope for callback\n     * @param {Function} [params.onDetached] Optional callback called when component is detached\n     * @param {Function} [params.onDetached.callback] Callback function\n     * @param {Function} [params.onDetached.scope] Optional scope for callback\n     * @param {{String:Function}} [params.on] Callbacks to subscribe to properties on component\n     * @param {Boolean} [params.recompiles=true] When true, fires \"dirty\" events on this component\n     * @private\n     */\n    _attach(params) {\n\n        const name = params.name;\n\n        if (!name) {\n            this.error(\"Component 'name' expected\");\n            return;\n        }\n\n        let component = params.component;\n        const sceneDefault = params.sceneDefault;\n        const sceneSingleton = params.sceneSingleton;\n        const type = params.type;\n        const on = params.on;\n        const recompiles = params.recompiles !== false;\n\n        // True when child given as config object, where parent manages its instantiation and destruction\n        let managingLifecycle = false;\n\n        if (component) {\n\n            if (utils.isNumeric(component) || utils.isString(component)) {\n\n                // Component ID given\n                // Both numeric and string IDs are supported\n\n                const id = component;\n\n                component = this.scene.components[id];\n\n                if (!component) {\n\n                    // Quote string IDs in errors\n\n                    this.error(\"Component not found: \" + utils.inQuotes(id));\n                    return;\n                }\n            }\n        }\n\n        if (!component) {\n\n            if (sceneSingleton === true) {\n\n                // Using the first instance of the component type we find\n\n                const instances = this.scene.types[type];\n                for (const id2 in instances) {\n                    if (instances.hasOwnProperty) {\n                        component = instances[id2];\n                        break;\n                    }\n                }\n\n                if (!component) {\n                    this.error(\"Scene has no default component for '\" + name + \"'\");\n                    return null;\n                }\n\n            } else if (sceneDefault === true) {\n\n                // Using a default scene component\n\n                component = this.scene[name];\n\n                if (!component) {\n                    this.error(\"Scene has no default component for '\" + name + \"'\");\n                    return null;\n                }\n            }\n        }\n\n        if (component) {\n\n            if (component.scene.id !== this.scene.id) {\n                this.error(\"Not in same scene: \" + component.type + \" \" + utils.inQuotes(component.id));\n                return;\n            }\n\n            if (type) {\n\n                if (!component.isType(type)) {\n                    this.error(\"Expected a \" + type + \" type or subtype: \" + component.type + \" \" + utils.inQuotes(component.id));\n                    return;\n                }\n            }\n        }\n\n        if (!this._attachments) {\n            this._attachments = {};\n        }\n\n        const oldComponent = this._attached[name];\n        let subs;\n        let i;\n        let len;\n\n        if (oldComponent) {\n\n            if (component && oldComponent.id === component.id) {\n\n                // Reject attempt to reattach same component\n                return;\n            }\n\n            const oldAttachment = this._attachments[oldComponent.id];\n\n            // Unsubscribe from events on old component\n\n            subs = oldAttachment.subs;\n\n            for (i = 0, len = subs.length; i < len; i++) {\n                oldComponent.off(subs[i]);\n            }\n\n            delete this._attached[name];\n            delete this._attachments[oldComponent.id];\n\n            const onDetached = oldAttachment.params.onDetached;\n            if (onDetached) {\n                if (utils.isFunction(onDetached)) {\n                    onDetached(oldComponent);\n                } else {\n                    onDetached.scope ? onDetached.callback.call(onDetached.scope, oldComponent) : onDetached.callback(oldComponent);\n                }\n            }\n\n            if (oldAttachment.managingLifecycle) {\n\n                // Note that we just unsubscribed from all events fired by the child\n                // component, so destroying it won't fire events back at us now.\n\n                oldComponent.destroy();\n            }\n        }\n\n        if (component) {\n\n            // Set and publish the new component on this component\n\n            const attachment = {\n                params: params,\n                component: component,\n                subs: [],\n                managingLifecycle: managingLifecycle\n            };\n\n            attachment.subs.push(\n                component.once(\"destroyed\",\n                    function () {\n                        attachment.params.component = null;\n                        this._attach(attachment.params);\n                    },\n                    this));\n\n            if (recompiles) {\n                attachment.subs.push(\n                    component.on(\"dirty\",\n                        function () {\n                            this.fire(\"dirty\", this);\n                        },\n                        this));\n            }\n\n            this._attached[name] = component;\n            this._attachments[component.id] = attachment;\n\n            // Bind destruct listener to new component to remove it\n            // from this component when destroyed\n\n            const onAttached = params.onAttached;\n            if (onAttached) {\n                if (utils.isFunction(onAttached)) {\n                    onAttached(component);\n                } else {\n                    onAttached.scope ? onAttached.callback.call(onAttached.scope, component) : onAttached.callback(component);\n                }\n            }\n\n            if (on) {\n\n                let event;\n                let subIdr;\n                let callback;\n                let scope;\n\n                for (event in on) {\n                    if (on.hasOwnProperty(event)) {\n\n                        subIdr = on[event];\n\n                        if (utils.isFunction(subIdr)) {\n                            callback = subIdr;\n                            scope = null;\n                        } else {\n                            callback = subIdr.callback;\n                            scope = subIdr.scope;\n                        }\n\n                        if (!callback) {\n                            continue;\n                        }\n\n                        attachment.subs.push(component.on(event, callback, scope));\n                    }\n                }\n            }\n        }\n\n        if (recompiles) {\n            this.fire(\"dirty\", this); // FIXME: May trigger spurous mesh recompilations unless able to limit with param?\n        }\n\n        this.fire(name, component); // Component can be null\n\n        return component;\n    }\n\n    _checkComponent(expectedType, component) {\n        if (!component.isComponent) {\n            if (utils.isID(component)) {\n                const id = component;\n                component = this.scene.components[id];\n                if (!component) {\n                    this.error(\"Component not found: \" + id);\n                    return;\n                }\n            } else {\n                this.error(\"Expected a Component or ID\");\n                return;\n            }\n        }\n        if (expectedType !== component.type) {\n            this.error(\"Expected a \" + expectedType + \" Component\");\n            return;\n        }\n        if (component.scene.id !== this.scene.id) {\n            this.error(\"Not in same scene: \" + component.type);\n            return;\n        }\n        return component;\n    }\n\n    _checkComponent2(expectedTypes, component) {\n        if (!component.isComponent) {\n            if (utils.isID(component)) {\n                const id = component;\n                component = this.scene.components[id];\n                if (!component) {\n                    this.error(\"Component not found: \" + id);\n                    return;\n                }\n            } else {\n                this.error(\"Expected a Component or ID\");\n                return;\n            }\n        }\n        if (component.scene.id !== this.scene.id) {\n            this.error(\"Not in same scene: \" + component.type);\n            return;\n        }\n        for (var i = 0, len = expectedTypes.length; i < len; i++) {\n            if (expectedTypes[i] === component.type) {\n                return component;\n            }\n        }\n        this.error(\"Expected component types: \" + expectedTypes);\n        return null;\n    }\n\n    _own(component) {\n        if (!this._ownedComponents) {\n            this._ownedComponents = {};\n        }\n        if (!this._ownedComponents[component.id]) {\n            this._ownedComponents[component.id] = component;\n        }\n        component.once(\"destroyed\", () => {\n            delete this._ownedComponents[component.id];\n        }, this);\n    }\n\n    /**\n     * Protected method, called by sub-classes to queue a call to _update().\n     * @protected\n     * @param {Number} [priority=1]\n     */\n    _needUpdate(priority) {\n        if (!this._updateScheduled) {\n            this._updateScheduled = true;\n            if (priority === 0) {\n                this._doUpdate();\n            } else {\n                core.scheduleTask(this._doUpdate, this);\n            }\n        }\n    }\n\n    /**\n     * @private\n     */\n    _doUpdate() {\n        if (this._updateScheduled) {\n            this._updateScheduled = false;\n            if (this._update) {\n                this._update();\n            }\n        }\n    }\n\n    /**\n     * Schedule a task to perform on the next browser interval\n     * @param task\n     */\n    scheduleTask(task) {\n        core.scheduleTask(task, null);\n    }\n\n    /**\n     * Protected virtual template method, optionally implemented\n     * by sub-classes to perform a scheduled task.\n     *\n     * @protected\n     */\n    _update() {\n    }\n\n    /**\n     * Destroys all {@link Component}s that are owned by this. These are Components that were instantiated with\n     * this Component as their first constructor argument.\n     */\n    clear() {\n        if (this._ownedComponents) {\n            for (var id in this._ownedComponents) {\n                if (this._ownedComponents.hasOwnProperty(id)) {\n                    const component = this._ownedComponents[id];\n                    component.destroy();\n                    delete this._ownedComponents[id];\n                }\n            }\n        }\n    }\n\n    /**\n     * Destroys this component.\n     */\n    destroy() {\n\n        if (this.destroyed) {\n            return;\n        }\n\n        /**\n         * Fired when this Component is destroyed.\n         * @event destroyed\n         */\n        this.fire(\"destroyed\", this.destroyed = true); // Must fire before we blow away subscription maps, below\n\n        // Unsubscribe from child components and destroy then\n\n        let id;\n        let attachment;\n        let component;\n        let subs;\n        let i;\n        let len;\n\n        if (this._attachments) {\n            for (id in this._attachments) {\n                if (this._attachments.hasOwnProperty(id)) {\n                    attachment = this._attachments[id];\n                    component = attachment.component;\n                    subs = attachment.subs;\n                    for (i = 0, len = subs.length; i < len; i++) {\n                        component.off(subs[i]);\n                    }\n                    if (attachment.managingLifecycle) {\n                        component.destroy();\n                    }\n                }\n            }\n        }\n\n        if (this._ownedComponents) {\n            for (id in this._ownedComponents) {\n                if (this._ownedComponents.hasOwnProperty(id)) {\n                    component = this._ownedComponents[id];\n                    component.destroy();\n                    delete this._ownedComponents[id];\n                }\n            }\n        }\n\n        this.scene._removeComponent(this);\n\n        // Memory leak avoidance\n        this._attached = {};\n        this._attachments = null;\n        this._subIdMap = null;\n        this._subIdEvents = null;\n        this._eventSubs = null;\n        this._events = null;\n        this._eventCallDepth = 0;\n        this._ownedComponents = null;\n        this._updateScheduled = false;\n        this._renderer = null;\n    }\n}\n\nconst tempVec3a$i = math.vec3();\nconst tempVec3b$b = math.vec3();\nconst tempMat4a$1 = math.mat4();\n\n/**\n * @private\n */\nclass FrustumPlane {\n\n    constructor() {\n        this.normal = math.vec3();\n        this.offset = 0;\n        this.testVertex = math.vec3();\n    }\n\n    set(nx, ny, nz, offset) {\n        const s = 1.0 / Math.sqrt(nx * nx + ny * ny + nz * nz);\n        this.normal[0] = nx * s;\n        this.normal[1] = ny * s;\n        this.normal[2] = nz * s;\n        this.offset = offset * s;\n        this.testVertex[0] = (this.normal[0] >= 0.0) ? 1 : 0;\n        this.testVertex[1] = (this.normal[1] >= 0.0) ? 1 : 0;\n        this.testVertex[2] = (this.normal[2] >= 0.0) ? 1 : 0;\n    }\n}\n\n/**\n * @private\n */\nclass Frustum$1 {\n    constructor() {\n        this.planes = [\n            new FrustumPlane(), new FrustumPlane(), new FrustumPlane(),\n            new FrustumPlane(), new FrustumPlane(), new FrustumPlane()\n        ];\n    }\n}\n\nFrustum$1.INSIDE = 0;\nFrustum$1.INTERSECT = 1;\nFrustum$1.OUTSIDE = 2;\n\n/** @private */\nfunction setFrustum(frustum, viewMat, projMat) {\n\n    const m = math.mulMat4(projMat, viewMat, tempMat4a$1);\n\n    const m0 = m[0];\n    const m1 = m[1];\n    const m2 = m[2];\n    const m3 = m[3];\n    const m4 = m[4];\n    const m5 = m[5];\n    const m6 = m[6];\n    const m7 = m[7];\n    const m8 = m[8];\n    const m9 = m[9];\n    const m10 = m[10];\n    const m11 = m[11];\n    const m12 = m[12];\n    const m13 = m[13];\n    const m14 = m[14];\n    const m15 = m[15];\n\n    frustum.planes[0].set(m3 - m0, m7 - m4, m11 - m8, m15 - m12);\n    frustum.planes[1].set(m3 + m0, m7 + m4, m11 + m8, m15 + m12);\n    frustum.planes[2].set(m3 - m1, m7 - m5, m11 - m9, m15 - m13);\n    frustum.planes[3].set(m3 + m1, m7 + m5, m11 + m9, m15 + m13);\n    frustum.planes[4].set(m3 - m2, m7 - m6, m11 - m10, m15 - m14);\n    frustum.planes[5].set(m3 + m2, m7 + m6, m11 + m10, m15 + m14);\n}\n\n/** @private */\nfunction frustumIntersectsAABB3(frustum, aabb) {\n\n    let ret = Frustum$1.INSIDE;\n\n    const min = tempVec3a$i;\n    const max = tempVec3b$b;\n\n    min[0] = aabb[0];\n    min[1] = aabb[1];\n    min[2] = aabb[2];\n    max[0] = aabb[3];\n    max[1] = aabb[4];\n    max[2] = aabb[5];\n\n    const bminmax = [min, max];\n\n    for (let i = 0; i < 6; ++i) {\n        const plane = frustum.planes[i];\n        if (((plane.normal[0] * bminmax[plane.testVertex[0]][0]) +\n            (plane.normal[1] * bminmax[plane.testVertex[1]][1]) +\n            (plane.normal[2] * bminmax[plane.testVertex[2]][2]) +\n            (plane.offset)) < 0.0) {\n            return Frustum$1.OUTSIDE;\n        }\n\n        if (((plane.normal[0] * bminmax[1 - plane.testVertex[0]][0]) +\n            (plane.normal[1] * bminmax[1 - plane.testVertex[1]][1]) +\n            (plane.normal[2] * bminmax[1 - plane.testVertex[2]][2]) +\n            (plane.offset)) < 0.0) {\n            ret = Frustum$1.INTERSECT;\n        }\n    }\n\n    return ret;\n}\n\n/**\n * Picks a {@link Viewer}'s {@link Entity}s with a canvas-space 2D marquee box.\n *\n * [<img src=\"https://xeokit.github.io/xeokit-sdk/assets/images/MarqueeSelect.gif\">](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_select)\n *\n * * [[Example 1: Select Objects with Marquee](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_select)]\n * * [[Example 2: View-Fit Objects with Marquee](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_viewFit)]\n *\n * # Usage\n *\n * In the example below, we\n *\n * 1. Create a {@link Viewer}, arrange the {@link Camera}\n * 2. Use an {@link XKTLoaderPlugin} to load a BIM model,\n * 3. Create a {@link ObjectsKdTree3} to automatically index the `Viewer's` {@link Entity}s for fast spatial lookup,\n * 4. Create a `MarqueePicker` to pick {@link Entity}s in the {@link Viewer}, using the {@link ObjectsKdTree3} to accelerate picking\n * 5. Create a {@link MarqueePickerMouseControl} to perform the marquee-picking with the `MarqueePicker`, using mouse input to draw the marquee box on the `Viewer's` canvas.\n *\n * When the {@link MarqueePickerMouseControl} is active:\n *\n * * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s.\n * * Drag left-to-right to pick {@link Entity}s that intersect the box.\n * * Drag right-to-left to pick {@link Entity}s that are fully inside the box.\n * * On release, the `MarqueePicker` will fire a \"picked\" event with IDs of the picked {@link Entity}s, if any.\n * * Handling that event, we mark the {@link Entity}s as selected.\n * * Hold down CTRL to multi-pick.\n *\n * ````javascript\n * import {\n *         Viewer,\n *         XKTLoaderPlugin,\n *         ObjectsKdTree3,\n *         MarqueePicker,\n *         MarqueePickerMouseControl\n * } from \"xeokit-sdk.es.js\";\n *\n * // 1\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [14.9, 14.3, 5.4];\n * viewer.scene.camera.look = [6.5, 8.3, -4.1];\n * viewer.scene.camera.up = [-0.28, 0.9, -0.3];\n *\n * // 2\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const sceneModel = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"../../assets/models/xkt/v8/ifc/HolterTower.ifc.xkt\"\n * });\n *\n * // 3\n *\n * const objectsKdTree3 = new ObjectsKdTree3({viewer});\n *\n * // 4\n *\n * const marqueePicker = new MarqueePicker({viewer, objectsKdTree3});\n *\n * // 5\n *\n * const marqueePickerMouseControl = new MarqueePickerMouseControl({marqueePicker});\n *\n * marqueePicker.on(\"clear\", () => {\n *     viewer.scene.setObjectsSelected(viewer.scene.selectedObjectIds, false);\n * });\n *\n * marqueePicker.on(\"picked\", (objectIds) => {\n *     viewer.scene.setObjectsSelected(objectIds, true);\n * });\n *\n * marqueePickerMouseControl.setActive(true);\n * ````\n *\n * # Design Notes\n *\n * * The {@link ObjectsKdTree3} can be shared with any other components that want to use it to spatially search for {@link Entity}s.\n * * The {@link MarqueePickerMouseControl} can be replaced with other types of controllers (i.e. touch), or used alongside them.\n * * The `MarqueePicker` has no input handlers of its own, and provides an API through which to programmatically control marquee picking. By firing the \"picked\" events, `MarqueePicker` implements the *Blackboard Pattern*.\n */\nclass MarqueePicker extends Component {\n\n    /**\n     * Creates a MarqueePicker.\n     *\n     * @param {*} cfg Configuration\n     * @param {Viewer} cfg.viewer The Viewer to pick Entities from.\n     * @param {ObjectsKdTree3} cfg.objectsKdTree3 A k-d tree that indexes the Entities in the Viewer for fast spatial lookup.\n     */\n    constructor(cfg = {}) {\n\n        if (!cfg.viewer) {\n            throw \"[MarqueePicker] Missing config: viewer\";\n        }\n\n        if (!cfg.objectsKdTree3) {\n            throw \"[MarqueePicker] Missing config: objectsKdTree3\";\n        }\n\n        super(cfg.viewer.scene, cfg);\n\n        this.viewer = cfg.viewer;\n        this._objectsKdTree3 = cfg.objectsKdTree3;\n        this._canvasMarqueeCorner1 = math.vec2();\n        this._canvasMarqueeCorner2 = math.vec2();\n        this._canvasMarquee = math.AABB2();\n        this._marqueeFrustum = new Frustum$1();\n        this._marqueeFrustumProjMat = math.mat4();\n        this._pickMode = false;\n\n        this._marqueeElement = document.createElement('div');\n        document.body.appendChild(this._marqueeElement);\n\n        this._marqueeElement.style.position = \"absolute\";\n        this._marqueeElement.style[\"z-index\"] = \"40000005\";\n        this._marqueeElement.style.width = 8 + \"px\";\n        this._marqueeElement.style.height = 8 + \"px\";\n        this._marqueeElement.style.visibility = \"hidden\";\n        this._marqueeElement.style.top = 0 + \"px\";\n        this._marqueeElement.style.left = 0 + \"px\";\n        this._marqueeElement.style[\"box-shadow\"] = \"0 2px 5px 0 #182A3D;\";\n        this._marqueeElement.style[\"opacity\"] = 1.0;\n        this._marqueeElement.style[\"pointer-events\"] = \"none\";\n    }\n\n    /**\n     * Sets the canvas-space position of the first marquee box corner.\n     *\n     * @param corner1\n     */\n    setMarqueeCorner1(corner1) {\n        this._canvasMarqueeCorner1.set(corner1);\n        this._canvasMarqueeCorner2.set(corner1);\n        this._updateMarquee();\n    }\n\n    /**\n     * Sets the canvas-space position of the second marquee box corner.\n     *\n     * @param corner2\n     */\n    setMarqueeCorner2(corner2) {\n        this._canvasMarqueeCorner2.set(corner2);\n        this._updateMarquee();\n    }\n\n    /**\n     * Sets both canvas-space corner positions of the marquee box.\n     *\n     * @param corner1\n     * @param corner2\n     */\n    setMarquee(corner1, corner2) {\n        this._canvasMarqueeCorner1.set(corner1);\n        this._canvasMarqueeCorner2.set(corner2);\n        this._updateMarquee();\n    }\n\n    /**\n     * Sets if the marquee box is visible.\n     *\n     * @param {boolean} visible True if the marquee box is to be visible, else false.\n     */\n    setMarqueeVisible(visible) {\n        this._marqueVisible = visible;\n        this._marqueeElement.style.visibility = visible ? \"visible\" : \"hidden\";\n    }\n\n    /**\n     * Gets if the marquee box is visible.\n     *\n     * @returns {boolean} True if the marquee box is visible, else false.\n     */\n    getMarqueeVisible() {\n        return this._marqueVisible;\n    }\n\n    /**\n     * Sets the pick mode.\n     *\n     * Supported pick modes are:\n     *\n     * * MarqueePicker.PICK_MODE_INSIDE - picks {@link Entity}s that are completely inside the marquee box.\n     * * MarqueePicker.PICK_MODE_INTERSECTS - picks {@link Entity}s that intersect the marquee box.\n     *\n     * @param {number} pickMode The pick mode.\n     */\n    setPickMode(pickMode) {\n        if (pickMode !== MarqueePicker.PICK_MODE_INSIDE && pickMode !== MarqueePicker.PICK_MODE_INTERSECTS) {\n            throw \"Illegal MarqueePicker pickMode: must be MarqueePicker.PICK_MODE_INSIDE or MarqueePicker.PICK_MODE_INTERSECTS\";\n        }\n        if (pickMode !== this._pickMode) {\n            this._marqueeElement.style[\"background-image\"] =\n                pickMode === MarqueePicker.PICK_MODE_INSIDE\n                    /* Solid */ ? \"url(\\\"data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='6' ry='6' stroke='%23333' stroke-width='4'/%3e%3c/svg%3e\\\")\"\n                    /* Dashed */ : \"url(\\\"data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='6' ry='6' stroke='%23333' stroke-width='4' stroke-dasharray='6%2c 14' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e\\\")\";\n            this._pickMode = pickMode;\n        }\n    }\n\n    /**\n     * Gets the pick mode.\n     *\n     * Supported pick modes are:\n     *\n     * * MarqueePicker.PICK_MODE_INSIDE - picks {@link Entity}s that are completely inside the marquee box.\n     * * MarqueePicker.PICK_MODE_INTERSECTS - picks {@link Entity}s that intersect the marquee box.\n     *\n     * @returns {number} The pick mode.\n     */\n    getPickMode() {\n        return this._pickMode;\n    }\n\n    /**\n     * Fires a \"clear\" event on this MarqueePicker.\n     */\n    clear() {\n        this.fire(\"clear\", {});\n    }\n\n    /**\n     * Attempts to pick {@link Entity}s, using the current MarquePicker settings.\n     *\n     * Fires a \"picked\" event with the IDs of the {@link Entity}s that were picked, if any.\n     *\n     * @returns {string[]} IDs of the {@link Entity}s that were picked, if any\n     */\n    pick() {\n        this._updateMarquee();\n        this._buildMarqueeFrustum();\n        const entityIds = [];\n        const visitNode = (node, intersects = Frustum$1.INTERSECT) => {\n            if (intersects === Frustum$1.INTERSECT) {\n                intersects = frustumIntersectsAABB3(this._marqueeFrustum, node.aabb);\n            }\n            if (intersects === Frustum$1.OUTSIDE) {\n                return;\n            }\n            if (node.entities) {\n                const entities = node.entities;\n                for (let i = 0, len = entities.length; i < len; i++) {\n                    const entity = entities[i];\n                    if (!entity.visible) {\n                        continue;\n                    }\n                    const entityAABB = entity.aabb;\n                    if (this._pickMode === MarqueePicker.PICK_MODE_INSIDE) {\n                        // Select entities that are completely inside marquee\n                        const intersection = frustumIntersectsAABB3(this._marqueeFrustum, entityAABB);\n                        if (intersection === Frustum$1.INSIDE) {\n                            entityIds.push(entity.id);\n                        }\n                    } else {\n                        // Select entities that are partially inside marquee\n                        const intersection = frustumIntersectsAABB3(this._marqueeFrustum, entityAABB);\n                        if (intersection !== Frustum$1.OUTSIDE) {\n                            entityIds.push(entity.id);\n                        }\n                    }\n                }\n            }\n            if (node.left) {\n                visitNode(node.left, intersects);\n            }\n            if (node.right) {\n                visitNode(node.right, intersects);\n            }\n        };\n        if (this._canvasMarquee[2] - this._canvasMarquee[0] > 3 || this._canvasMarquee[3] - this._canvasMarquee[1] > 3) { // Marquee pick if rectangle big enough\n            visitNode(this._objectsKdTree3.root);\n        }\n        this.fire(\"picked\", entityIds);\n        return entityIds;\n    }\n\n    _updateMarquee() {\n        this._canvasMarquee[0] = Math.min(this._canvasMarqueeCorner1[0], this._canvasMarqueeCorner2[0]);\n        this._canvasMarquee[1] = Math.min(this._canvasMarqueeCorner1[1], this._canvasMarqueeCorner2[1]);\n        this._canvasMarquee[2] = Math.max(this._canvasMarqueeCorner1[0], this._canvasMarqueeCorner2[0]);\n        this._canvasMarquee[3] = Math.max(this._canvasMarqueeCorner1[1], this._canvasMarqueeCorner2[1]);\n        this._marqueeElement.style.width = `${this._canvasMarquee[2] - this._canvasMarquee[0]}px`;\n        this._marqueeElement.style.height = `${this._canvasMarquee[3] - this._canvasMarquee[1]}px`;\n        this._marqueeElement.style.left = `${this._canvasMarquee[0]}px`;\n        this._marqueeElement.style.top = `${this._canvasMarquee[1]}px`;\n    }\n\n    _buildMarqueeFrustum() { // https://github.com/xeokit/xeokit-sdk/issues/869#issuecomment-1165375770\n        const canvas = this.viewer.scene.canvas.canvas;\n        const canvasWidth = canvas.clientWidth;\n        const canvasHeight = canvas.clientHeight;\n        const canvasLeft = canvas.clientLeft;\n        const canvasTop = canvas.clientTop;\n        const xCanvasToClip = 2.0 / canvasWidth;\n        const yCanvasToClip = 2.0 / canvasHeight;\n        const NEAR_SCALING = 17;\n        const ratio = canvas.clientHeight / canvas.clientWidth;\n        const FAR_PLANE = 10000;\n        const left = (this._canvasMarquee[0] - canvasLeft) * xCanvasToClip + -1;\n        const right = (this._canvasMarquee[2] - canvasLeft) * xCanvasToClip + -1;\n        const bottom = -(this._canvasMarquee[3] - canvasTop) * yCanvasToClip + 1;\n        const top = -(this._canvasMarquee[1] - canvasTop) * yCanvasToClip + 1;\n        const near = this.viewer.scene.camera.frustum.near * (NEAR_SCALING * ratio);\n        const far = FAR_PLANE;\n        math.frustumMat4(\n            left,\n            right,\n            bottom * ratio,\n            top * ratio,\n            near,\n            far,\n            this._marqueeFrustumProjMat,\n        );\n        setFrustum(this._marqueeFrustum, this.viewer.scene.camera.viewMatrix, this._marqueeFrustumProjMat);\n    }\n\n    /**\n     * Destroys this MarqueePicker.\n     *\n     * Does not destroy the {@link Viewer} or the {@link ObjectsKdTree3} provided to the constructor of this MarqueePicker.\n     */\n    destroy() {\n        super.destroy();\n        if (this._marqueeElement.parentElement) {\n            this._marqueeElement.parentElement.removeChild(this._marqueeElement);\n            this._marqueeElement = null;\n            this._objectsKdTree3 = null;\n        }\n    }\n}\n\n/**\n * Pick mode that picks {@link Entity}s that intersect the marquee box.\n *\n * @type {number}\n */\nMarqueePicker.PICK_MODE_INTERSECTS = 0;\n\n/**\n * Pick mode that picks {@link Entity}s that are completely inside the marquee box.\n *\n * @type {number}\n */\nMarqueePicker.PICK_MODE_INSIDE = 1;\n\n/**\n * Controls a {@link MarqueePicker} with mouse input.\n *\n * See {@link MarqueePicker} for usage example.\n *\n * When the MarqueePickerMouseControl is active:\n *\n * * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s.\n * * Drag left-to-right to pick Entities that intersect the box.\n * * Drag right-to-left to pick Entities that are fully inside the box.\n * * On release, the MarqueePicker will fire a \"picked\" event with IDs of the picked Entities , if any.\n */\nclass MarqueePickerMouseControl extends Component {\n\n    /**\n     * Creates a new MarqueePickerMouseControl.\n     *\n     * @param {*} cfg Configuration\n     * @param {MarqueePicker} cfg.marqueePicker The MarqueePicker to control.\n     */\n    constructor(cfg) {\n\n        super(cfg.marqueePicker, cfg);\n\n        const marqueePicker = cfg.marqueePicker;\n        const scene = marqueePicker.viewer.scene;\n        const canvas = scene.canvas.canvas;\n\n        let pageStartX;\n        let pageStartY;\n        let pageEndX;\n        let pageEndY;\n\n        let canvasStartX;\n        let canvasEndX;\n\n        let isMouseDragging = false;\n        let isMouseDown = false;\n        let mouseWasUpOffCanvas = false;\n        let mouseDownTimer;\n\n        canvas.addEventListener(\"mousedown\", (e) => {\n            if (!this.getActive()) {\n                return;\n            }\n            if (e.button !== 0) { // Left button only\n                return;\n            }\n            mouseDownTimer = setTimeout(function () {\n                const input = marqueePicker.viewer.scene.input;\n                if (!input.keyDown[input.KEY_CTRL]) { // Clear selection unless CTRL down\n                    marqueePicker.clear();\n                }\n                pageStartX = e.pageX;\n                pageStartY = e.pageY;\n                canvasStartX = e.offsetX;\n                marqueePicker.setMarqueeCorner1([pageStartX, pageStartY]);\n                isMouseDragging = true;\n                marqueePicker.viewer.cameraControl.pointerEnabled = false; // Disable camera rotation\n                marqueePicker.setMarqueeVisible(true);\n                canvas.style.cursor = \"crosshair\";\n            }, 400);\n\n            isMouseDown = true;\n        });\n\n        canvas.addEventListener(\"mouseup\", (e) => {\n            if (!this.getActive()) {\n                return;\n            }\n            if (!isMouseDragging && !mouseWasUpOffCanvas) {\n                return\n            }\n            if (e.button !== 0) {\n                return;\n            }\n            clearTimeout(mouseDownTimer);\n            pageEndX = e.pageX;\n            pageEndY = e.pageY;\n            const width = Math.abs(pageEndX - pageStartX);\n            const height = Math.abs(pageEndY - pageStartY);\n            isMouseDragging = false;\n            marqueePicker.viewer.cameraControl.pointerEnabled = true; // Enable camera rotation\n            if (mouseWasUpOffCanvas) {\n                mouseWasUpOffCanvas = false;\n            }\n            if (width > 3 || height > 3) { // Marquee pick if rectangle big enough\n                marqueePicker.pick();\n            }\n        }); // Bubbling\n\n        document.addEventListener(\"mouseup\", (e) => {\n            if (!this.getActive()) {\n                return;\n            }\n            if (e.button !== 0) { // check if left button was clicked\n                return;\n            }\n            clearTimeout(mouseDownTimer);\n            if (!isMouseDragging) {\n                return\n            }\n            marqueePicker.setMarqueeVisible(false);\n            isMouseDragging = false;\n            isMouseDown = false;\n            mouseWasUpOffCanvas = true;\n            marqueePicker.viewer.cameraControl.pointerEnabled = true;\n        }, true); // Capturing\n\n        canvas.addEventListener(\"mousemove\", (e) => {\n            if (!this.getActive()) {\n                return;\n            }\n            if (e.button !== 0) { // check if left button was clicked\n                return;\n            }\n\n            if (!isMouseDown) {\n                return;\n            }\n\n            clearTimeout(mouseDownTimer);\n\n            if (!isMouseDragging) {\n                return\n            }\n\n            pageEndX = e.pageX;\n            pageEndY = e.pageY;\n            canvasEndX = e.offsetX;\n\n            marqueePicker.setMarqueeVisible(true);\n            marqueePicker.setMarqueeCorner2([pageEndX, pageEndY]);\n            marqueePicker.setPickMode((canvasStartX < canvasEndX) ? MarqueePicker.PICK_MODE_INSIDE : MarqueePicker.PICK_MODE_INTERSECTS);\n\n        });\n    }\n\n    /**\n     * Activates or deactivates this MarqueePickerMouseControl.\n     *\n     * @param {boolean} active Whether or not to activate.\n     */\n    setActive(active) {\n        if (this._active === active) {\n            return;\n        }\n        this._active = active;\n        this.fire(\"active\", this._active);\n    }\n\n    /**\n     * Gets if this MarqueePickerMouseControl is active.\n     *\n     * @returns {boolean}\n     */\n    getActive() {\n        return this._active;\n    }\n\n    /**\n     *\n     */\n    destroy() {\n\n    }\n}\n\n/**\n * A PointerCircle shows a circle, centered at the position of the\n * mouse or touch pointer.\n */\nclass PointerCircle {\n\n    /**\n     * Constructs a new PointerCircle.\n     * @param viewer The Viewer\n     * @param [cfg] PointerCircle configuration.\n     * @param [cfg.active=true] Whether PointerCircle is active. The PointerCircle can only be shown when this is `true` (default).\n     */\n    constructor(viewer, cfg = {}) {\n\n        this.viewer = viewer;\n        this.scene = this.viewer.scene;\n        this._circleDiv = document.createElement('div');\n        this.viewer.scene.canvas.canvas.parentNode.insertBefore(this._circleDiv, this.viewer.scene.canvas.canvas);\n        this._circleDiv.style.backgroundColor = \"transparent\";\n        this._circleDiv.style.border = \"2px solid green\";\n        this._circleDiv.style.borderRadius = \"50px\";\n        this._circleDiv.style.width = \"50px\";\n        this._circleDiv.style.height = \"50px\";\n        this._circleDiv.style.margin = \"-200px -200px\";\n        this._circleDiv.style.zIndex = \"100000\";\n        this._circleDiv.style.position = \"absolute\";\n        this._circleDiv.style.pointerEvents = \"none\";\n\n        this._circlePos = null;\n\n        this._circleMaxRadius = 200;\n        this._circleMinRadius = 2;\n\n        this._active = (cfg.active !== false);\n        this._visible = false;\n\n        this._running = false;\n        this._destroyed = false;\n    }\n\n    /**\n     * Show the circle at the given canvas coordinates and begin shrinking it.\n     */\n    start(circlePos) {\n        if (this._destroyed) {\n            return;\n        }\n        this._circlePos = circlePos;\n        this._running = false;\n        this._circleRadius = this._circleMaxRadius;\n        this._circleDiv.style.borderRadius = `${this._circleRadius}px`;\n        this._circleDiv.style.marginLeft = `${this._circlePos[0] - this._circleRadius}px`;\n        this._circleDiv.style.marginTop = `${this._circlePos[1] - this._circleRadius}px`;\n\n        const startValue = this._circleMaxRadius;\n        const endValue = 2;\n        let startTime;\n        const duration = 300;\n\n        const animateCircle = (currentTime) => {\n            if (!this._running) {\n                return;\n            }\n            if (!startTime) {\n                startTime = currentTime;\n            }\n\n            const elapsedTime = currentTime - startTime;\n            const progress = Math.min(elapsedTime / duration, 1);\n            const interpolatedValue = startValue + (endValue - startValue) * progress;\n\n            this._circleRadius = interpolatedValue;\n            this._circleDiv.style.width = `${this._circleRadius}px`;\n            this._circleDiv.style.height = `${this._circleRadius}px`;\n            this._circleDiv.style.marginLeft = `${this._circlePos[0] - this._circleRadius / 2}px`;\n            this._circleDiv.style.marginTop = `${this._circlePos[1] - this._circleRadius / 2}px`;\n\n            if (progress < 1) {\n                requestAnimationFrame(animateCircle);\n            }\n        };\n        this._running = true;\n        requestAnimationFrame(animateCircle);\n        this._circleDiv.style.visibility = \"visible\";\n    }\n\n    /**\n     * Stop the shrinking circle and hide it.\n     */\n    stop() {\n        if (this._destroyed) {\n            return;\n        }\n        this._running = false;\n        this._circleRadius = this._circleMaxRadius;\n        this._circleDiv.style.borderRadius = `${this._circleRadius}px`;\n        this._circleDiv.style.visibility = \"hidden\";\n    }\n\n    /**\n     * Sets the zoom factor for the lens.\n     *\n     * This is `2` by default.\n     *\n     * @param durationMs\n     */\n    set durationMs(durationMs) {\n        this.stop();\n        this._durationMs = durationMs;\n    }\n\n    /**\n     * Gets the zoom factor for the lens.\n     *\n     * This is `2` by default.\n     *\n     * @returns Number\n     */\n    get durationMs() {\n        return this._durationMs;\n    }\n\n    /**\n     * Destroys this PointerCircle.\n     */\n    destroy() {\n        if (!this._destroyed) {\n            this.stop();\n            this._circleDiv.parentElement.removeChild(this._circleDiv);\n            this._destroyed = true;\n        }\n    }\n}\n\n/**\n * @desc Localization service for a {@link Viewer}.\n *\n * * A LocaleService is a container of string translations (\"messages\") for various locales.\n * * A {@link Viewer} has its own default LocaleService at {@link Viewer#localeService}.\n * * We can replace that with our own LocaleService, or a custom subclass, via the Viewer's constructor.\n * * Viewer plugins that need localized translations will attempt to them for the currently active locale from the LocaleService.\n * * Whenever we switch the LocaleService to a different locale, plugins will automatically refresh their translations for that locale.\n *\n * ## Usage\n *\n * In the example below, we'll create a {@link Viewer} that uses an {@link XKTLoaderPlugin} to load a BIM model, and a\n * {@link NavCubePlugin}, which shows a camera navigation cube in the corner of the canvas.\n *\n * We'll also configure our Viewer with our own LocaleService instance, configured with English, Māori and French\n * translations for our NavCubePlugin.\n *\n * We could instead have just used the Viewer's default LocaleService, but this example demonstrates how we might\n * configure the Viewer our own custom LocaleService subclass.\n *\n * The translations fetched by our NavCubePlugin will be:\n *\n *  * \"NavCube.front\"\n *  * \"NavCube.back\"\n *  * \"NavCube.top\"\n *  * \"NavCube.bottom\"\n *  * \"NavCube.left\"\n *  * \"NavCube.right\"\n *\n * <br>\n * These are paths that resolve to our translations for the currently active locale, and are hard-coded within\n * the NavCubePlugin.\n *\n * For example, if  the LocaleService's locale is set to \"fr\", then the path \"NavCube.back\" will drill down\n * into ````messages->fr->NavCube->front```` and fetch \"Arrière\".\n *\n * If we didn't provide that particular translation in our LocaleService, or any translations for that locale,\n * then the NavCubePlugin will just fall back on its own default hard-coded translation, which in this case is \"BACK\".\n *\n * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#localization_NavCubePlugin)]\n *\n * ````javascript\n * import {Viewer, LocaleService, NavCubePlugin, XKTLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *\n *      canvasId: \"myCanvas\",\n *\n *      localeService: new LocaleService({\n *          messages: {\n *              \"en\": { // English\n *                  \"NavCube\": {\n *                      \"front\": \"Front\",\n *                      \"back\": \"Back\",\n *                      \"top\": \"Top\",\n *                      \"bottom\": \"Bottom\",\n *                      \"left\": \"Left\",\n *                      \"right\": \"Right\"\n *                  }\n *              },\n *              \"mi\": { // Māori\n *                  \"NavCube\": {\n *                      \"front\": \"Mua\",\n *                      \"back\": \"Tuarā\",\n *                      \"top\": \"Runga\",\n *                      \"bottom\": \"Raro\",\n *                      \"left\": \"Mauī\",\n *                      \"right\": \"Tika\"\n *                  }\n *              },\n *              \"fr\": { // Francais\n *                  \"NavCube\": {\n *                      \"front\": \"Avant\",\n *                      \"back\": \"Arrière\",\n *                      \"top\": \"Supérieur\",\n *                      \"bottom\": \"Inférieur\",\n *                      \"left\": \"Gauche\",\n *                      \"right\": \"Droit\"\n *                  }\n *              }\n *          },\n *          locale: \"en\"\n *      })\n *  });\n *\n * viewer.camera.eye = [-3.93, 2.85, 27.01];\n * viewer.camera.look = [4.40, 3.72, 8.89];\n * viewer.camera.up = [-0.01, 0.99, 0.03];\n *\n * const navCubePlugin = new NavCubePlugin(viewer, {\n *      canvasID: \"myNavCubeCanvas\"\n *  });\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/xkt/Duplex.ifc.xkt\",\n *     edges: true\n * });\n * ````\n *\n * We can dynamically switch our Viewer to a different locale at any time, which will update the text on the\n * faces of our NavCube:\n *\n * ````javascript\n * viewer.localeService.locale = \"mi\"; // Switch to Māori\n * ````\n *\n * We can load new translations at any time:\n *\n * ````javascript\n * viewer.localeService.loadMessages({\n *     \"jp\": { // Japanese\n *         \"NavCube\": {\n *             \"front\": \"前部\",\n *             \"back\": \"裏\",\n *             \"top\": \"上\",\n *             \"bottom\": \"底\",\n *             \"left\": \"左\",\n *             \"right\": \"右\"\n *         }\n *     }\n * });\n * ````\n *\n * And we can clear the translations if needed:\n *\n * ````javascript\n * viewer.localeService.clearMessages();\n * ````\n *\n * We can get an \"updated\" event from the LocaleService whenever we switch locales or load messages, which is useful\n * for triggering UI elements to refresh themselves with updated translations. Internally, our {@link NavCubePlugin}\n * subscribes to this event, fetching new strings for itself via {@link LocaleService#translate} each time the\n * event is fired.\n *\n * ````javascript\n * viewer.localeService.on(\"updated\", () => {\n *     console.log( viewer.localeService.translate(\"NavCube.left\") );\n * });\n * ````\n * @since 2.0\n */\nclass LocaleService {\n\n    /**\n     * Constructs a LocaleService.\n     *\n     * @param {*} [params={}]\n     * @param {JSON} [params.messages]\n     * @param {String} [params.locale]\n     */\n    constructor(params = {}) {\n\n        this._eventSubIDMap = null;\n        this._eventSubEvents = null;\n        this._eventSubs = null;\n        this._events = null;\n\n        this._locale = \"en\";\n        this._messages = {};\n        this._locales = [];\n        this._locale = \"en\";\n\n        this.messages = params.messages;\n        this.locale = params.locale;\n    }\n\n    /**\n     * Replaces the current set of locale translations.\n     *\n     * * Fires an \"updated\" event when done.\n     * * Automatically refreshes any plugins that depend on the translations.\n     * * Does not change the current locale.\n     *\n     * ## Usage\n     *\n     * ````javascript\n     * viewer.localeService.setMessages({\n     *     messages: {\n     *         \"en\": { // English\n     *             \"NavCube\": {\n     *                 \"front\": \"Front\",\n     *                 \"back\": \"Back\",\n     *                 \"top\": \"Top\",\n     *                 \"bottom\": \"Bottom\",\n     *                 \"left\": \"Left\",\n     *                 \"right\": \"Right\"\n     *             }\n     *         },\n     *         \"mi\": { // Māori\n     *             \"NavCube\": {\n     *                 \"front\": \"Mua\",\n     *                 \"back\": \"Tuarā\",\n     *                 \"top\": \"Runga\",\n     *                 \"bottom\": \"Raro\",\n     *                 \"left\": \"Mauī\",\n     *                 \"right\": \"Tika\"\n     *             }\n     *         }\n     *    }\n     * });\n     * ````\n     *\n     * @param {*} messages The new translations.\n     */\n    set messages(messages) {\n        this._messages = messages || {};\n        this._locales = Object.keys(this._messages);\n        this.fire(\"updated\", this);\n    }\n\n    /**\n     * Loads a new set of locale translations, adding them to the existing translations.\n     *\n     * * Fires an \"updated\" event when done.\n     * * Automatically refreshes any plugins that depend on the translations.\n     * * Does not change the current locale.\n     *\n     * ## Usage\n     *\n     * ````javascript\n     * viewer.localeService.loadMessages({\n     *     \"jp\": { // Japanese\n     *         \"NavCube\": {\n     *             \"front\": \"前部\",\n     *             \"back\": \"裏\",\n     *             \"top\": \"上\",\n     *             \"bottom\": \"底\",\n     *             \"left\": \"左\",\n     *             \"right\": \"右\"\n     *         }\n     *     }\n     * });\n     * ````\n     *\n     * @param {*} messages The new translations.\n     */\n    loadMessages(messages = {}) {\n        for (let locale in messages) {\n            this._messages[locale] = messages[locale];\n        }\n        this.messages = this._messages;\n    }\n\n    /**\n     * Clears all locale translations.\n     *\n     * * Fires an \"updated\" event when done.\n     * * Does not change the current locale.\n     * * Automatically refreshes any plugins that depend on the translations, which will cause those\n     * plugins to fall back on their internal hard-coded text values, since this method removes all\n     * our translations.\n     */\n    clearMessages() {\n        this.messages = {};\n    }\n\n    /**\n     * Gets the list of available locales.\n     *\n     * These are derived from the currently configured set of translations.\n     *\n     * @returns {String[]} The list of available locales.\n     */\n    get locales() {\n        return this._locales;\n    }\n\n    /**\n     * Sets the current locale.\n     *\n     * * Fires an \"updated\" event when done.\n     * * The given locale does not need to be in the list of available locales returned by {@link LocaleService#locales}, since\n     * this method assumes that you may want to load the locales at a later point.\n     * * Automatically refreshes any plugins that depend on the translations.\n     * * We can then get translations for the locale, if translations have been loaded for it, via {@link LocaleService#translate} and {@link LocaleService#translatePlurals}.\n     *\n     * @param {String} locale The new current locale.\n     */\n    set locale(locale) {\n        locale = locale || \"de\";\n        if (this._locale === locale) {\n            return;\n        }\n        this._locale = locale;\n        this.fire(\"updated\", locale);\n    }\n\n    /**\n     * Gets the current locale.\n     *\n     * @returns {String} The current locale.\n     */\n    get locale() {\n        return this._locale;\n    }\n\n    /**\n     * Translates the given string according to the current locale.\n     *\n     * Returns null if no translation can be found.\n     *\n     * @param {String} msg String to translate.\n     * @param {*} [args] Extra parameters.\n     * @returns {String|null} Translated string if found, else null.\n     */\n    translate(msg, args) {\n        const localeMessages = this._messages[this._locale];\n        if (!localeMessages) {\n            return null;\n        }\n        const localeMessage = resolvePath$1(msg, localeMessages);\n        if (localeMessage) {\n            if (args) {\n                return vsprintf(localeMessage, args);\n            }\n            return localeMessage;\n        }\n        return null;\n    }\n\n    /**\n     * Translates the given phrase according to the current locale.\n     *\n     * Returns null if no translation can be found.\n     *\n     * @param {String} msg Phrase to translate.\n     * @param {Number} count The plural number.\n     * @param {*} [args] Extra parameters.\n     * @returns {String|null} Translated string if found, else null.\n     */\n    translatePlurals(msg, count, args) {\n        const localeMessages = this._messages[this._locale];\n        if (!localeMessages) {\n            return null;\n        }\n        let localeMessage = resolvePath$1(msg, localeMessages);\n        count = parseInt(\"\" + count, 10);\n        if (count === 0) {\n            localeMessage = localeMessage.zero;\n        } else {\n            localeMessage = (count > 1) ? localeMessage.other : localeMessage.one;\n        }\n        if (!localeMessage) {\n            return null;\n        }\n        localeMessage = vsprintf(localeMessage, [count]);\n        if (args) {\n            localeMessage = vsprintf(localeMessage, args);\n        }\n        return localeMessage;\n    }\n\n    /**\n     * Fires an event on this LocaleService.\n     *\n     * Notifies existing subscribers to the event, optionally retains the event to give to\n     * any subsequent notifications on the event as they are made.\n     *\n     * @param {String} event The event type name.\n     * @param {Object} value The event parameters.\n     * @param {Boolean} [forget=false] When true, does not retain for subsequent subscribers.\n     */\n    fire(event, value, forget) {\n        if (!this._events) {\n            this._events = {};\n        }\n        if (!this._eventSubs) {\n            this._eventSubs = {};\n        }\n        if (forget !== true) {\n            this._events[event] = value || true; // Save notification\n        }\n        const subs = this._eventSubs[event];\n        if (subs) {\n            for (const subId in subs) {\n                if (subs.hasOwnProperty(subId)) {\n                    const sub = subs[subId];\n                    sub.callback(value);\n                }\n            }\n        }\n    }\n\n    /**\n     * Subscribes to an event on this LocaleService.\n     *\n     * @param {String} event The event\n     * @param {Function} callback Callback fired on the event\n     * @return {String} Handle to the subscription, which may be used to unsubscribe with {@link #off}.\n     */\n    on(event, callback) {\n        if (!this._events) {\n            this._events = {};\n        }\n        if (!this._eventSubIDMap) {\n            this._eventSubIDMap = new Map$1(); // Subscription subId pool\n        }\n        if (!this._eventSubEvents) {\n            this._eventSubEvents = {};\n        }\n        if (!this._eventSubs) {\n            this._eventSubs = {};\n        }\n        let subs = this._eventSubs[event];\n        if (!subs) {\n            subs = {};\n            this._eventSubs[event] = subs;\n        }\n        const subId = this._eventSubIDMap.addItem(); // Create unique subId\n        subs[subId] = {\n            callback: callback\n        };\n        this._eventSubEvents[subId] = event;\n        const value = this._events[event];\n        if (value !== undefined) {\n            callback(value);\n        }\n        return subId;\n    }\n\n    /**\n     * Cancels an event subscription that was previously made with {@link LocaleService#on}.\n     *\n     * @param {String} subId Subscription ID\n     */\n    off(subId) {\n        if (subId === undefined || subId === null) {\n            return;\n        }\n        if (!this._eventSubEvents) {\n            return;\n        }\n        const event = this._eventSubEvents[subId];\n        if (event) {\n            delete this._eventSubEvents[subId];\n            const subs = this._eventSubs[event];\n            if (subs) {\n                delete subs[subId];\n            }\n            this._eventSubIDMap.removeItem(subId); // Release subId\n        }\n    }\n}\n\nfunction resolvePath$1(key, json) {\n    if (json[key]) {\n        return json[key];\n    }\n    const parts = key.split(\".\");\n    let obj = json;\n    for (let i = 0, len = parts.length; obj && (i < len); i++) {\n        const part = parts[i];\n        obj = obj[part];\n    }\n    return obj;\n}\n\nfunction vsprintf(msg, args = []) {\n    return msg.replace(/\\{\\{|\\}\\}|\\{(\\d+)\\}/g, function (m, n) {\n        if (m === \"{{\") {\n            return \"{\";\n        }\n        if (m === \"}}\") {\n            return \"}\";\n        }\n        return args[n];\n    });\n}\n\n/**\n * @desc Abstract base class for curve classes.\n */\nclass Curve extends Component {\n\n    /**\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this Curve as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Curve}, generated automatically when omitted.\n     * @param {Object} [cfg] Configs for this Curve.\n     * @param {Number} [cfg.t=0] Current position on this Curve, in range between ````0..1````.\n     */\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n        this.t = cfg.t;\n    }\n\n    /**\n     * Sets the progress along this Curve.\n     *\n     * Automatically clamps to range ````[0..1]````.\n     *\n     * Default value is ````0````.\n     *\n     * @param {Number} value The progress value.\n     */\n    set t(value) {\n        value = value || 0;\n        this._t = value < 0.0 ? 0.0 : (value > 1.0 ? 1.0 : value);\n    }\n\n    /**\n     * Gets the progress along this Curve.\n     *\n     * @returns {Number} The progress value.\n     */\n    get t() {\n        return this._t;\n    }\n\n    /**\n     * Gets the tangent on this Curve at position {@link Curve#t}.\n     *\n     * @returns {Number[]} The tangent.\n     */\n    get tangent() {\n        return this.getTangent(this._t);\n    }\n\n    /**\n     * Gets the length of this Curve.\n     *\n     * @returns {Number} The Curve length.\n     */\n    get length() {\n        var lengths = this._getLengths();\n        return lengths[lengths.length - 1];\n    }\n\n    /**\n     * Returns a normalized tangent vector on this Curve at the given position.\n     *\n     * @param {Number} t Position to get tangent at.\n     * @returns {Number[]} Normalized tangent vector\n     */\n    getTangent(t) {\n        var delta = 0.0001;\n        if (t === undefined) {\n            t = this._t;\n        }\n        var t1 = t - delta;\n        var t2 = t + delta;\n        if (t1 < 0) {\n            t1 = 0;\n        }\n        if (t2 > 1) {\n            t2 = 1;\n        }\n        var pt1 = this.getPoint(t1);\n        var pt2 = this.getPoint(t2);\n        var vec = math.subVec3(pt2, pt1, []);\n        return math.normalizeVec3(vec, []);\n    }\n\n    getPointAt(u) {\n        var t = this.getUToTMapping(u);\n        return this.getPoint(t);\n    }\n\n    /**\n     * Samples points on this Curve, at the given number of equally-spaced divisions.\n     *\n     * @param {Number} divisions The number of divisions.\n     * @returns {{Array of Array}} Array of sampled 3D points.\n     */\n    getPoints(divisions) {\n        if (!divisions) {\n            divisions = 5;\n        }\n        var d, pts = [];\n        for (d = 0; d <= divisions; d++) {\n            pts.push(this.getPoint(d / divisions));\n        }\n        return pts;\n    }\n\n    _getLengths(divisions) {\n        if (!divisions) {\n            divisions = (this.__arcLengthDivisions) ? (this.__arcLengthDivisions) : 200;\n        }\n        if (this.cacheArcLengths && (this.cacheArcLengths.length === divisions + 1) && !this.needsUpdate) {\n            return this.cacheArcLengths;\n\n        }\n        this.needsUpdate = false;\n        var cache = [];\n        var current;\n        var last = this.getPoint(0);\n        var p;\n        var sum = 0;\n        cache.push(0);\n        for (p = 1; p <= divisions; p++) {\n            current = this.getPoint(p / divisions);\n            sum += math.lenVec3(math.subVec3(current, last, []));\n            cache.push(sum);\n            last = current;\n        }\n        this.cacheArcLengths = cache;\n        return cache; // { sums: cache, sum:sum }, Sum is in the last element.\n    }\n\n    _updateArcLengths() {\n        this.needsUpdate = true;\n        this._getLengths();\n    }\n\n    // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equi distance\n\n    getUToTMapping(u, distance) {\n        var arcLengths = this._getLengths();\n        var i = 0;\n        var il = arcLengths.length;\n        var t;\n        var targetArcLength; // The targeted u distance value to get\n        if (distance) {\n            targetArcLength = distance;\n        } else {\n            targetArcLength = u * arcLengths[il - 1];\n        }\n        //var time = Date.now();\n        var low = 0, high = il - 1, comparison;\n        while (low <= high) {\n            i = Math.floor(low + (high - low) / 2); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n            comparison = arcLengths[i] - targetArcLength;\n            if (comparison < 0) {\n                low = i + 1;\n            } else if (comparison > 0) {\n                high = i - 1;\n            } else {\n                high = i;\n                break;\n                // DONE\n            }\n        }\n        i = high;\n        if (arcLengths[i] === targetArcLength) {\n            t = i / (il - 1);\n            return t;\n        }\n        var lengthBefore = arcLengths[i];\n        var lengthAfter = arcLengths[i + 1];\n        var segmentLength = lengthAfter - lengthBefore;\n        var segmentFraction = (targetArcLength - lengthBefore) / segmentLength;\n        t = (i + segmentFraction) / (il - 1);\n        return t;\n    }\n}\n\n/**\n * @desc A {@link Curve} along which a 3D position can be animated.\n *\n * * As shown in the diagram below, a SplineCurve is defined by three or more control points.\n * * You can sample a {@link SplineCurve#point} and a {@link Curve#tangent} vector on a SplineCurve for any given value of {@link SplineCurve#t} in the range ````[0..1]````.\n * * When you set {@link SplineCurve#t} on a SplineCurve, its {@link SplineCurve#point} and {@link Curve#tangent} will update accordingly.\n * * To build a complex path, you can combine an unlimited combination of SplineCurves, {@link CubicBezierCurve} and {@link QuadraticBezierCurve} into a {@link Path}.\n * <br>\n * <img style=\"border:1px solid; background: white;\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/72/Quadratic_spline_six_segments.svg/200px-Quadratic_spline_six_segments.svg.png\"/><br>\n *\n * * <a href=\"https://en.wikipedia.org/wiki/Spline_(mathematics)\">Spline Curve from Wikipedia</a>*\n */\nclass SplineCurve extends Curve {\n\n    /**\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this SplineCurve as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Array} [cfg.points=[]] Control points on this SplineCurve.\n     * @param {Number} [cfg.t=0] Current position on this SplineCurve, in range between 0..1.\n     * @param {Number} [cfg.t=0] Current position on this CubicBezierCurve, in range between 0..1.\n     */\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n        this.points = cfg.points;\n        this.t = cfg.t;\n    }\n\n    /**\n     * Sets the control points on this SplineCurve.\n     *\n     * Default value is ````[]````.\n     *\n     * @param {Number[]} value New control points.\n     */\n    set points(value) {\n        this._points = value || [];\n    }\n\n    /**\n     * Gets the control points on this SplineCurve.\n     *\n     * Default value is ````[]````.\n     *\n     * @returns {Number[]} The control points.\n     */\n    get points() {\n        return this._points;\n    }\n\n    /**\n     * Sets the progress along this SplineCurve.\n     *\n     * Automatically clamps to range ````[0..1]````.\n     *\n     * Default value is ````0````.\n     *\n     * @param {Number} value The new progress.\n     */\n    set t(value) {\n        value = value || 0;\n        this._t = value < 0.0 ? 0.0 : (value > 1.0 ? 1.0 : value);\n    }\n\n    /**\n     * Gets the progress along this SplineCurve.\n     *\n     * Automatically clamps to range ````[0..1]````.\n     *\n     * Default value is ````0````.\n     *\n     * @returns {Number} The new progress.\n     */\n    get t() {\n        return this._t;\n    }\n\n    /**\n     * Gets the point on this SplineCurve at position {@link SplineCurve#t}.\n     *\n     * @returns {Number[]} The point at {@link SplineCurve#t}.\n     */\n    get point() {\n        return this.getPoint(this._t);\n    }\n\n    /**\n     * Returns point on this SplineCurve at the given position.\n     *\n     * @param {Number} t Position to get point at.\n     * @returns {Number[]} Point at the given position.\n     */\n    getPoint(t) {\n\n        var points = this.points;\n\n        if (points.length < 3) {\n            this.error(\"Can't sample point from SplineCurve - not enough points on curve - returning [0,0,0].\");\n            return;\n        }\n\n        var point = (points.length - 1) * t;\n\n        var intPoint = Math.floor(point);\n        var weight = point - intPoint;\n\n        var point0 = points[intPoint === 0 ? intPoint : intPoint - 1];\n        var point1 = points[intPoint];\n        var point2 = points[intPoint > points.length - 2 ? points.length - 1 : intPoint + 1];\n        var point3 = points[intPoint > points.length - 3 ? points.length - 1 : intPoint + 2];\n\n        var vector = math.vec3();\n\n        vector[0] = math.catmullRomInterpolate(point0[0], point1[0], point2[0], point3[0], weight);\n        vector[1] = math.catmullRomInterpolate(point0[1], point1[1], point2[1], point3[1], weight);\n        vector[2] = math.catmullRomInterpolate(point0[2], point1[2], point2[2], point3[2], weight);\n\n        return vector;\n    }\n\n    getJSON() {\n        return {\n            points: points,\n            t: this._t\n        };\n    }\n}\n\nconst tempVec3a$h = math.vec3();\n\n/**\n * @desc Defines a sequence of frames along which a {@link CameraPathAnimation} can animate a {@link Camera}.\n *\n * See {@link CameraPathAnimation} for usage.\n */\nclass CameraPath extends Component {\n\n    /**\n     * Returns \"CameraPath\".\n     *\n     * @private\n     *\n     * @returns {string} \"CameraPath\"\n     */\n    get type() {\n        return \"CameraPath\"\n    }\n\n    /**\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this CameraPath as well.\n     * @param [cfg] {*} Configuration\n     * @param {String} [cfg.id]  Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {{t:Number, eye:Object, look:Object, up: Object}[]} [cfg.frames] Initial sequence of frames.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._frames = [];\n\n        this._eyeCurve = new SplineCurve(this);\n        this._lookCurve = new SplineCurve(this);\n        this._upCurve = new SplineCurve(this);\n\n        if (cfg.frames) {\n            this.addFrames(cfg.frames);\n            this.smoothFrameTimes(1);\n        }\n    }\n\n    /**\n     * Gets the camera frames in this CameraPath.\n     *\n     * @returns {{t:Number, eye:Object, look:Object, up: Object}[]} The frames on this CameraPath.\n     */\n    get frames() {\n        return this._frames;\n    }\n\n    /**\n     * Gets the {@link SplineCurve} along which {@link Camera#eye} travels.\n     * @returns {SplineCurve} The SplineCurve for {@link Camera#eye}.\n     */\n    get eyeCurve() {\n        return this._eyeCurve;\n    }\n\n    /**\n     * Gets the {@link SplineCurve} along which {@link Camera#look} travels.\n     * @returns {SplineCurve} The SplineCurve for {@link Camera#look}.\n     */\n    get lookCurve() {\n        return this._lookCurve;\n    }\n\n    /**\n     * Gets the {@link SplineCurve} along which {@link Camera#up} travels.\n     * @returns {SplineCurve} The SplineCurve for {@link Camera#up}.\n     */\n    get upCurve() {\n        return this._upCurve;\n    }\n\n    /**\n     * Adds a frame to this CameraPath, given as the current position of the {@link Camera}.\n     *\n     * @param {Number} t Time instant for the new frame.\n     */\n    saveFrame(t) {\n        const camera = this.scene.camera;\n        this.addFrame(t, camera.eye, camera.look, camera.up);\n    }\n\n    /**\n     * Adds a frame to this CameraPath, specified as values for eye, look and up vectors at a given time instant.\n     *\n     * @param {Number} t Time instant for the new frame.\n     * @param {Number[]} eye A three-element vector specifying the eye position for the new frame.\n     * @param {Number[]} look A three-element vector specifying the look position for the new frame.\n     * @param {Number[]} up A three-element vector specifying the up vector for the new frame.\n     */\n    addFrame(t, eye, look, up) {\n        const frame = {\n            t: t,\n            eye: eye.slice(0),\n            look: look.slice(0),\n            up: up.slice(0)\n        };\n        this._frames.push(frame);\n        this._eyeCurve.points.push(frame.eye);\n        this._lookCurve.points.push(frame.look);\n        this._upCurve.points.push(frame.up);\n    }\n\n    /**\n     * Adds multiple frames to this CameraPath, each frame specified as a set of values for eye, look and up vectors at a given time instant.\n     *\n     * @param {{t:Number, eye:Object, look:Object, up: Object}[]} frames Frames to add to this CameraPath.\n     */\n    addFrames(frames) {\n        let frame;\n        for (let i = 0, len = frames.length; i < len; i++) {\n            frame = frames[i];\n            this.addFrame(frame.t || 0, frame.eye, frame.look, frame.up);\n        }\n    }\n\n    /**\n     * Sets the position of the {@link Camera} to a position interpolated within this CameraPath at the given time instant.\n     *\n     * @param {Number} t Time instant.\n     */\n    loadFrame(t) {\n\n        const camera = this.scene.camera;\n\n        t = t / (this._frames[this._frames.length - 1].t - this._frames[0].t);\n        t = t < 0.0 ? 0.0 : (t > 1.0 ? 1.0 : t);\n\n        camera.eye = this._eyeCurve.getPoint(t, tempVec3a$h);\n        camera.look = this._lookCurve.getPoint(t, tempVec3a$h);\n        camera.up = this._upCurve.getPoint(t, tempVec3a$h);\n    }\n\n    /**\n     * Gets eye, look and up vectors on this CameraPath at a given instant.\n     *\n     * @param {Number} t Time instant.\n     * @param {Number[]} eye The eye position to update.\n     * @param {Number[]} look The look position to update.\n     * @param {Number[]} up The up vector to update.\n     */\n    sampleFrame(t, eye, look, up) {\n        t = t < 0.0 ? 0.0 : (t > 1.0 ? 1.0 : t);\n        this._eyeCurve.getPoint(t, eye);\n        this._lookCurve.getPoint(t, look);\n        this._upCurve.getPoint(t, up);\n    }\n\n    /**\n     * Given a total duration (in seconds) for this CameraPath, recomputes the time instant at each frame so that,\n     * when animated by {@link CameraPathAnimation}, the {@link Camera} will move along the path at a constant rate.\n     *\n     * @param {Number} duration The total duration for this CameraPath.\n     */\n    smoothFrameTimes(duration) {\n        const numFrames = this._frames.length;\n        if (numFrames === 0) {\n            return;\n        }\n        const vec = math.vec3();\n        var totalLen = 0;\n        this._frames[0].t = 0;\n        const lens = [];\n        for (let i = 1, len = this._frames.length; i < len; i++) {\n            var lenVec = math.lenVec3(math.subVec3(this._frames[i].eye, this._frames[i - 1].eye, vec));\n            lens[i] = lenVec;\n            totalLen += lenVec;\n        }\n        for (let i = 1, len = this._frames.length; i < len; i++) {\n            const interFrameRate = (lens[i] / totalLen) * duration;\n            this._frames[i].t = this._frames[i-1].t + interFrameRate;\n        }\n    }\n\n    /**\n     * Removes all frames from this CameraPath.\n     */\n    clearFrames() {\n        this._frames = [];\n        this._eyeCurve.points = [];\n        this._lookCurve.points = [];\n        this._upCurve.points = [];\n    }\n}\n\nconst tempVec3$8 = math.vec3();\nconst newLook = math.vec3();\nconst newEye = math.vec3();\nconst newUp = math.vec3();\nconst newLookEyeVec = math.vec3();\n\n/**\n * @desc Jumps or flies the {@link Scene}'s {@link Camera} to a given target.\n *\n * * Located at {@link Viewer#cameraFlight}\n * * Can fly or jump to its target.\n * * While flying, can be stopped, or redirected to a different target.\n * * Can also smoothly transition between ortho and perspective projections.\n *\n *\n * A CameraFlightAnimation's target can be:\n *\n * * specific ````eye````, ````look```` and ````up```` positions,\n * * an axis-aligned World-space bounding box (AABB), or\n * * an instance or ID of any {@link Component} subtype that provides a World-space AABB.\n *\n * A target can also contain a ````projection```` type to transition into. For example, if your {@link Camera#projection} is\n * currently ````\"perspective\"```` and you supply {@link CameraFlightAnimation#flyTo} with a ````projection```` property\n * equal to \"ortho\", then CameraFlightAnimation will smoothly transition the Camera into an orthographic projection.\n *\n * Configure {@link CameraFlightAnimation#fit} and {@link CameraFlightAnimation#fitFOV} to make it stop at the point\n * where the target occupies a certain amount of the field-of-view.\n *\n * ## Flying to an Entity\n *\n * Flying to an {@link Entity}:\n *\n * ````Javascript\n * var entity = new Mesh(viewer.scene);\n *\n * // Fly to the Entity's World-space AABB\n * viewer.cameraFlight.flyTo(entity);\n * ````\n * ## Flying to a Position\n *\n * Flying the CameraFlightAnimation from the previous example to specified eye, look and up positions:\n *\n * ````Javascript\n * viewer.cameraFlight.flyTo({\n *    eye: [-5,-5,-5],\n *    look: [0,0,0]\n *    up: [0,1,0],\n *    duration: 1 // Default, seconds\n * },() => {\n *      // Done\n * });\n * ````\n *\n * ## Flying to an AABB\n *\n * Flying the CameraFlightAnimation from the previous two examples explicitly to the {@link Boundary3D\"}}Boundary3D's{{/crossLink}}\n * axis-aligned bounding box:\n *\n * ````Javascript\n * viewer.cameraFlight.flyTo(entity.aabb);\n * ````\n *\n * ## Transitioning Between Projections\n *\n * CameraFlightAnimation also allows us to smoothly transition between Camera projections. We can do that by itself, or\n * in addition to flying the Camera to a target.\n *\n * Let's transition the Camera to orthographic projection:\n *\n * [[Run example](/examples/index.html#camera_CameraFlightAnimation_projection)]\n *\n * ````Javascript\n * viewer.cameraFlight.flyTo({ projection: \"ortho\", () => {\n *      // Done\n * });\n * ````\n *\n * Now let's transition the Camera back to perspective projection:\n *\n * ````Javascript\n * viewer.cameraFlight.flyTo({ projection: \"perspective\"}, () => {\n *      // Done\n * });\n * ````\n *\n * Fly Camera to a position, while transitioning to orthographic projection:\n *\n * ````Javascript\n * viewer.cameraFlight.flyTo({\n *     eye: [-100,20,2],\n *     look: [0,0,-40],\n *     up: [0,1,0],\n *     projection: \"ortho\", () => {\n *        // Done\n * });\n * ````\n */\nclass CameraFlightAnimation extends Component {\n\n    /**\n     * @private\n     */\n    get type() {\n        return \"CameraFlightAnimation\";\n    }\n\n    /**\n     @constructor\n     @private\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._look1 = math.vec3();\n        this._eye1 = math.vec3();\n        this._up1 = math.vec3();\n        this._look2 = math.vec3();\n        this._eye2 = math.vec3();\n        this._up2 = math.vec3();\n        this._orthoScale1 = 1;\n        this._orthoScale2 = 1;\n        this._flying = false;\n        this._flyEyeLookUp = false;\n        this._flyingEye = false;\n        this._flyingLook = false;\n        this._callback = null;\n        this._callbackScope = null;\n        this._time1 = null;\n        this._time2 = null;\n        this.easing = cfg.easing !== false;\n\n        this.duration = cfg.duration;\n        this.fit = cfg.fit;\n        this.fitFOV = cfg.fitFOV;\n        this.trail = cfg.trail;\n    }\n\n    /**\n     * Flies the {@link Camera} to a target.\n     *\n     *  * When the target is a boundary, the {@link Camera} will fly towards the target and stop when the target fills most of the canvas.\n     *  * When the target is an explicit {@link Camera} position, given as ````eye````, ````look```` and ````up````, then CameraFlightAnimation will interpolate the {@link Camera} to that target and stop there.\n     *\n     * @param {Object|Component} [params=Scene] Either a parameters object or a {@link Component} subtype that has\n     * an AABB. Defaults to the {@link Scene}, which causes the {@link Camera} to fit the Scene in view.\n     * @param {Number} [params.arc=0] Factor in range ````[0..1]```` indicating how much the {@link Camera#eye} position\n     * will swing away from its {@link Camera#look} position as it flies to the target.\n     * @param {Number|String|Component} [params.component] ID or instance of a component to fly to. Defaults to the entire {@link Scene}.\n     * @param {Number[]} [params.aabb] World-space axis-aligned bounding box (AABB) target to fly to.\n     * @param {Number[]} [params.eye] Position to fly the eye position to.\n     * @param {Number[]} [params.look] Position to fly the look position to.\n     * @param {Number[]} [params.up] Position to fly the up vector to.\n     * @param {String} [params.projection] Projection type to transition into as we fly. Can be any of the values of {@link Camera.projection}.\n     * @param {Boolean} [params.fit=true] Whether to fit the target to the view volume. Overrides {@link CameraFlightAnimation#fit}.\n     * @param {Number} [params.fitFOV] How much of field-of-view, in degrees, that a target {@link Entity} or its AABB should\n     * fill the canvas on arrival. Overrides {@link CameraFlightAnimation#fitFOV}.\n     * @param {Number} [params.duration] Flight duration in seconds.  Overrides {@link CameraFlightAnimation#duration}.\n     * @param {Number} [params.orthoScale] Animate the Camera's orthographic scale to this target value. See {@link Ortho#scale}.\n     * @param {Function} [callback] Callback fired on arrival.\n     * @param {Object} [scope] Optional scope for callback.\n     */\n    flyTo(params, callback, scope) {\n\n        params = params || this.scene;\n\n        if (this._flying) {\n            this.stop();\n        }\n\n        this._flying = false;\n        this._flyingEye = false;\n        this._flyingLook = false;\n        this._flyingEyeLookUp = false;\n\n        this._callback = callback;\n        this._callbackScope = scope;\n\n        const camera = this.scene.camera;\n        const flyToProjection = (!!params.projection) && (params.projection !== camera.projection);\n\n        this._eye1[0] = camera.eye[0];\n        this._eye1[1] = camera.eye[1];\n        this._eye1[2] = camera.eye[2];\n\n        this._look1[0] = camera.look[0];\n        this._look1[1] = camera.look[1];\n        this._look1[2] = camera.look[2];\n\n        this._up1[0] = camera.up[0];\n        this._up1[1] = camera.up[1];\n        this._up1[2] = camera.up[2];\n\n        this._orthoScale1 = camera.ortho.scale;\n        this._orthoScale2 = params.orthoScale || this._orthoScale1;\n\n        let aabb;\n        let eye;\n        let look;\n        let up;\n        let componentId;\n\n        if (params.aabb) {\n            aabb = params.aabb;\n\n        } else if (params.length === 6) {\n            aabb = params;\n\n        } else if ((params.eye && params.look) || params.up) {\n            eye = params.eye;\n            look = params.look;\n            up = params.up;\n\n        } else if (params.eye) {\n            eye = params.eye;\n\n        } else if (params.look) {\n            look = params.look;\n\n        } else { // Argument must be an instance or ID of a Component (subtype)\n\n            let component = params;\n\n            if (utils.isNumeric(component) || utils.isString(component)) {\n\n                componentId = component;\n                component = this.scene.components[componentId];\n\n                if (!component) {\n                    this.error(\"Component not found: \" + utils.inQuotes(componentId));\n                    if (callback) {\n                        if (scope) {\n                            callback.call(scope);\n                        } else {\n                            callback();\n                        }\n                    }\n                    return;\n                }\n            }\n            if (!flyToProjection) {\n                aabb = component.aabb || this.scene.aabb;\n            }\n        }\n\n        const poi = params.poi;\n\n        if (aabb) {\n\n            if (aabb[3] < aabb[0] || aabb[4] < aabb[1] || aabb[5] < aabb[2]) { // Don't fly to an inverted boundary\n                return;\n            }\n\n            if (aabb[3] === aabb[0] && aabb[4] === aabb[1] && aabb[5] === aabb[2]) { // Don't fly to an empty boundary\n                return;\n            }\n\n            aabb = aabb.slice();\n            const aabbCenter = math.getAABB3Center(aabb);\n\n            this._look2 = poi || aabbCenter;\n\n            const eyeLookVec = math.subVec3(this._eye1, this._look1, tempVec3$8);\n            const eyeLookVecNorm = math.normalizeVec3(eyeLookVec);\n            const diag = poi ? math.getAABB3DiagPoint(aabb, poi) : math.getAABB3Diag(aabb);\n            const fitFOV = params.fitFOV || this._fitFOV;\n            const sca = Math.abs(diag / Math.tan(fitFOV * math.DEGTORAD));\n\n            this._orthoScale2 = diag * 1.1;\n\n            this._eye2[0] = this._look2[0] + (eyeLookVecNorm[0] * sca);\n            this._eye2[1] = this._look2[1] + (eyeLookVecNorm[1] * sca);\n            this._eye2[2] = this._look2[2] + (eyeLookVecNorm[2] * sca);\n\n            this._up2[0] = this._up1[0];\n            this._up2[1] = this._up1[1];\n            this._up2[2] = this._up1[2];\n\n            this._flyingEyeLookUp = true;\n\n        } else if (eye || look || up) {\n\n            this._flyingEyeLookUp = !!eye && !!look && !!up;\n            this._flyingEye = !!eye && !look;\n            this._flyingLook = !!look && !eye;\n\n            if (eye) {\n                this._eye2[0] = eye[0];\n                this._eye2[1] = eye[1];\n                this._eye2[2] = eye[2];\n            }\n\n            if (look) {\n                this._look2[0] = look[0];\n                this._look2[1] = look[1];\n                this._look2[2] = look[2];\n            }\n\n            if (up) {\n                this._up2[0] = up[0];\n                this._up2[1] = up[1];\n                this._up2[2] = up[2];\n            }\n        }\n\n        if (flyToProjection) {\n\n            if (params.projection === \"ortho\" && camera.projection !== \"ortho\") {\n                this._projection2 = \"ortho\";\n                this._projMatrix1 = camera.projMatrix.slice();\n                this._projMatrix2 = camera.ortho.matrix.slice();\n                camera.projection = \"customProjection\";\n            }\n\n            if (params.projection === \"perspective\" && camera.projection !== \"perspective\") {\n                this._projection2 = \"perspective\";\n                this._projMatrix1 = camera.projMatrix.slice();\n                this._projMatrix2 = camera.perspective.matrix.slice();\n                camera.projection = \"customProjection\";\n            }\n        } else {\n            this._projection2 = null;\n        }\n\n        this.fire(\"started\", params, true);\n\n        this._time1 = Date.now();\n        this._time2 = this._time1 + (Number.isFinite(params.duration) ? params.duration * 1000 : this._duration);\n\n        this._flying = true; // False as soon as we stop\n\n        core.scheduleTask(this._update, this);\n    }\n\n    /**\n     * Jumps the {@link Scene}'s {@link Camera} to the given target.\n     *\n     * * When the target is a boundary, this CameraFlightAnimation will position the {@link Camera} at where the target fills most of the canvas.\n     * * When the target is an explicit {@link Camera} position, given as ````eye````, ````look```` and ````up```` vectors, then this CameraFlightAnimation will jump the {@link Camera} to that target.\n     *\n     * @param {*|Component} params  Either a parameters object or a {@link Component} subtype that has a World-space AABB.\n     * @param {Number} [params.arc=0]  Factor in range [0..1] indicating how much the {@link Camera#eye} will swing away from its {@link Camera#look} as it flies to the target.\n     * @param {Number|String|Component} [params.component] ID or instance of a component to fly to.\n     * @param {Number[]} [params.aabb]  World-space axis-aligned bounding box (AABB) target to fly to.\n     * @param {Number[]} [params.eye] Position to fly the eye position to.\n     * @param {Number[]} [params.look]  Position to fly the look position to.\n     * @param {Number[]} [params.up] Position to fly the up vector to.\n     * @param {String} [params.projection] Projection type to transition into. Can be any of the values of {@link Camera.projection}.\n     * @param {Number} [params.fitFOV] How much of field-of-view, in degrees, that a target {@link Entity} or its AABB should fill the canvas on arrival. Overrides {@link CameraFlightAnimation#fitFOV}.\n     * @param {Boolean} [params.fit] Whether to fit the target to the view volume. Overrides {@link CameraFlightAnimation#fit}.\n     */\n    jumpTo(params) {\n        this._jumpTo(params);\n    }\n\n    _jumpTo(params) {\n\n        if (this._flying) {\n            this.stop();\n        }\n\n        const camera = this.scene.camera;\n\n        var aabb;\n        var componentId;\n        var newEye;\n        var newLook;\n        var newUp;\n\n        if (params.aabb) { // Boundary3D\n            aabb = params.aabb;\n\n        } else if (params.length === 6) { // AABB\n            aabb = params;\n\n        } else if (params.eye || params.look || params.up) { // Camera pose\n            newEye = params.eye;\n            newLook = params.look;\n            newUp = params.up;\n\n        } else { // Argument must be an instance or ID of a Component (subtype)\n\n            let component = params;\n\n            if (utils.isNumeric(component) || utils.isString(component)) {\n                componentId = component;\n                component = this.scene.components[componentId];\n                if (!component) {\n                    this.error(\"Component not found: \" + utils.inQuotes(componentId));\n                    return;\n                }\n            }\n            aabb = component.aabb || this.scene.aabb;\n        }\n\n        const poi = params.poi;\n\n        if (aabb) {\n\n            if (aabb[3] <= aabb[0] || aabb[4] <= aabb[1] || aabb[5] <= aabb[2]) { // Don't fly to an empty boundary\n                return;\n            }\n\n            var diag = poi ? math.getAABB3DiagPoint(aabb, poi) : math.getAABB3Diag(aabb);\n\n            newLook = poi || math.getAABB3Center(aabb, newLook);\n\n            if (this._trail) {\n                math.subVec3(camera.look, newLook, newLookEyeVec);\n            } else {\n                math.subVec3(camera.eye, camera.look, newLookEyeVec);\n            }\n\n            math.normalizeVec3(newLookEyeVec);\n            let dist;\n            const fit = (params.fit !== undefined) ? params.fit : this._fit;\n\n            if (fit) {\n                dist = Math.abs((diag) / Math.tan((params.fitFOV || this._fitFOV) * math.DEGTORAD));\n\n            } else {\n                dist = math.lenVec3(math.subVec3(camera.eye, camera.look, tempVec3$8));\n            }\n\n            math.mulVec3Scalar(newLookEyeVec, dist);\n\n            camera.eye = math.addVec3(newLook, newLookEyeVec, tempVec3$8);\n            camera.look = newLook;\n\n            this.scene.camera.ortho.scale = diag * 1.1;\n\n        } else if (newEye || newLook || newUp) {\n\n            if (newEye) {\n                camera.eye = newEye;\n            }\n            if (newLook) {\n                camera.look = newLook;\n            }\n            if (newUp) {\n                camera.up = newUp;\n            }\n        }\n\n        if (params.projection) {\n            camera.projection = params.projection;\n        }\n    }\n\n    _update() {\n        if (!this._flying) {\n            return;\n        }\n        const time = Date.now();\n        let t = (time - this._time1) / (this._time2 - this._time1);\n        const stopping = (t >= 1);\n\n        if (t > 1) {\n            t = 1;\n        }\n\n        const tFlight = this.easing ? CameraFlightAnimation._ease(t, 0, 1, 1) : t;\n        const camera = this.scene.camera;\n\n        if (this._flyingEye || this._flyingLook) {\n\n            if (this._flyingEye) {\n                math.subVec3(camera.eye, camera.look, newLookEyeVec);\n                camera.eye = math.lerpVec3(tFlight, 0, 1, this._eye1, this._eye2, newEye);\n                camera.look = math.subVec3(newEye, newLookEyeVec, newLook);\n            } else if (this._flyingLook) {\n                camera.look = math.lerpVec3(tFlight, 0, 1, this._look1, this._look2, newLook);\n                camera.up = math.lerpVec3(tFlight, 0, 1, this._up1, this._up2, newUp);\n            }\n\n        } else if (this._flyingEyeLookUp) {\n\n            camera.eye = math.lerpVec3(tFlight, 0, 1, this._eye1, this._eye2, newEye);\n            camera.look = math.lerpVec3(tFlight, 0, 1, this._look1, this._look2, newLook);\n            camera.up = math.lerpVec3(tFlight, 0, 1, this._up1, this._up2, newUp);\n        }\n\n        if (this._projection2) {\n            const tProj = (this._projection2 === \"ortho\") ? CameraFlightAnimation._easeOutExpo(t, 0, 1, 1) : CameraFlightAnimation._easeInCubic(t, 0, 1, 1);\n            camera.customProjection.matrix = math.lerpMat4(tProj, 0, 1, this._projMatrix1, this._projMatrix2);\n\n        } else {\n            camera.ortho.scale = this._orthoScale1 + (t * (this._orthoScale2 - this._orthoScale1));\n        }\n\n        if (stopping) {\n            camera.ortho.scale = this._orthoScale2;\n            this.stop();\n            return;\n        }\n        core.scheduleTask(this._update, this); // Keep flying\n    }\n\n    static _ease(t, b, c, d) { // Quadratic easing out - decelerating to zero velocity http://gizma.com/easing\n        t /= d;\n        return -c * t * (t - 2) + b;\n    }\n\n    static _easeInCubic(t, b, c, d) {\n        t /= d;\n        return c * t * t * t + b;\n    }\n\n    static _easeOutExpo(t, b, c, d) {\n        return c * (-Math.pow(2, -10 * t / d) + 1) + b;\n    }\n\n    /**\n     * Stops an earlier flyTo, fires arrival callback.\n     */\n    stop() {\n        if (!this._flying) {\n            return;\n        }\n        this._flying = false;\n        this._time1 = null;\n        this._time2 = null;\n        if (this._projection2) {\n            this.scene.camera.projection = this._projection2;\n        }\n        const callback = this._callback;\n        if (callback) {\n            this._callback = null;\n            if (this._callbackScope) {\n                callback.call(this._callbackScope);\n            } else {\n                callback();\n            }\n        }\n        this.fire(\"stopped\", true, true);\n    }\n\n    /**\n     * Cancels an earlier flyTo without calling the arrival callback.\n     */\n    cancel() {\n        if (!this._flying) {\n            return;\n        }\n        this._flying = false;\n        this._time1 = null;\n        this._time2 = null;\n        if (this._callback) {\n            this._callback = null;\n        }\n        this.fire(\"canceled\", true, true);\n    }\n\n    /**\n     * Sets the flight duration, in seconds, when calling {@link CameraFlightAnimation#flyTo}.\n     *\n     * Stops any flight currently in progress.\n     *\n     * default value is ````0.5````.\n     *\n     * @param {Number} value New duration value.\n     */\n    set duration(value) {\n        this._duration = Number.isFinite(value) ? (value * 1000.0) : 500;\n        this.stop();\n    }\n\n    /**\n     * Gets the flight duration, in seconds, when calling {@link CameraFlightAnimation#flyTo}.\n     *\n     * default value is ````0.5````.\n     *\n     * @returns {Number} New duration value.\n     */\n    get duration() {\n        return this._duration / 1000.0;\n    }\n\n    /**\n     * Sets if, when CameraFlightAnimation is flying to a boundary, it will always adjust the distance between the\n     * {@link Camera#eye} and {@link Camera#look} so as to ensure that the target boundary is always filling the view volume.\n     *\n     * When false, the eye will remain at its current distance from the look position.\n     *\n     * Default value is ````true````.\n     *\n     * @param {Boolean} value Set ````true```` to activate this behaviour.\n     */\n    set fit(value) {\n        this._fit = value !== false;\n    }\n\n    /**\n     * Gets if, when CameraFlightAnimation is flying to a boundary, it will always adjust the distance between the\n     * {@link Camera#eye} and {@link Camera#look} so as to ensure that the target boundary is always filling the view volume.\n     *\n     * When false, the eye will remain at its current distance from the look position.\n     *\n     * Default value is ````true````.\n     *\n     * @returns {Boolean} value Set ````true```` to activate this behaviour.\n     */\n    get fit() {\n        return this._fit;\n    }\n\n    /**\n     * Sets how much of the perspective field-of-view, in degrees, that a target {@link Entity#aabb} should\n     * fill the canvas when calling {@link CameraFlightAnimation#flyTo} or {@link CameraFlightAnimation#jumpTo}.\n     *\n     * Default value is ````45````.\n     *\n     * @param {Number} value New FOV value.\n     */\n    set fitFOV(value) {\n        this._fitFOV = value || 45;\n    }\n\n    /**\n     * Gets how much of the perspective field-of-view, in degrees, that a target {@link Entity#aabb} should\n     * fill the canvas when calling {@link CameraFlightAnimation#flyTo} or {@link CameraFlightAnimation#jumpTo}.\n     *\n     * Default value is ````45````.\n     *\n     * @returns {Number} Current FOV value.\n     */\n    get fitFOV() {\n        return this._fitFOV;\n    }\n\n    /**\n     * Sets if this CameraFlightAnimation to point the {@link Camera}\n     * in the direction that it is travelling when flying to a target after calling {@link CameraFlightAnimation#flyTo}.\n     *\n     * Default value is ````true````.\n     *\n     * @param {Boolean} value Set ````true```` to activate trailing behaviour.\n     */\n    set trail(value) {\n        this._trail = !!value;\n    }\n\n    /**\n     * Gets if this CameraFlightAnimation points the {@link Camera}\n     * in the direction that it is travelling when flying to a target after calling {@link CameraFlightAnimation#flyTo}.\n     *\n     * Default value is ````true````.\n     *\n     * @returns {Boolean} True if trailing behaviour is active.\n     */\n    get trail() {\n        return this._trail;\n    }\n\n    /**\n     * @private\n     */\n    destroy() {\n        this.stop();\n        super.destroy();\n    }\n}\n\n/**\n * @desc Animates the {@link Scene}'s's {@link Camera} along a {@link CameraPath}.\n *\n * ## Usage\n *\n * In the example below, we'll load a model using a {@link GLTFLoaderPlugin}, then animate a {@link Camera}\n * through the frames in a {@link CameraPath}.\n *\n *  * [[Run this example](/examples/index.html#camera_CameraPathAnimation)]\n *\n * ````Javascript\n * import {Viewer, GLTFLoaderPlugin, CameraPath, CameraPathAnimation} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer and arrange camera\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.camera.eye = [124.86756896972656, -93.50288391113281, 173.2632598876953];\n * viewer.camera.look = [102.14186096191406, -90.24193572998047, 173.4224395751953];\n * viewer.camera.up = [0.23516440391540527, 0.9719591736793518, -0.0016466031083837152];\n *\n * // Load model\n *\n * const gltfLoader = new GLTFLoaderPlugin(viewer);\n *\n * const model = gltfLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/gltf/modern_office/scene.gltf\",\n *     edges: true,\n *     edgeThreshold: 20,\n *     xrayed: false\n * });\n *\n * // Create a CameraPath\n *\n * var cameraPath = new CameraPath(viewer.scene, {\n *     frames: [\n *         {\n *             t:    0,\n *             eye:  [124.86, -93.50, 173.26],\n *             look: [102.14, -90.24, 173.42],\n *             up:   [0.23, 0.97, -0.00]\n *         },\n *         {\n *             t:    1,\n *             eye:  [79.75, -85.98, 226.57],\n *             look: [99.24, -84.11, 238.56],\n *             up:   [-0.14, 0.98, -0.09]\n *         },\n *         // Rest of the frames omitted for brevity\n *     ]\n * });\n *\n * // Create a CameraPathAnimation to play our CameraPath\n *\n * var cameraPathAnimation = new CameraPathAnimation(viewer.scene, {\n *     cameraPath: cameraPath,\n *     playingRate: 0.2 // Playing 0.2 time units per second\n * });\n *\n * // Once model loaded, start playing after a couple of seconds delay\n *\n * model.on(\"loaded\", function () {\n *     setTimeout(function () {\n *         cameraPathAnimation.play(0); // Play from the beginning of the CameraPath\n *     }, 2000);\n * });\n * ````\n */\nclass CameraPathAnimation extends Component {\n\n    /**\n     * Returns \"CameraPathAnimation\".\n     *\n     * @private\n     * @returns {string} \"CameraPathAnimation\"\n     */\n    get type() {\n        return \"CameraPathAnimation\"\n    }\n\n    /**\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this CameraPathAnimation as well.\n     * @param {*} [cfg] Configuration\n     * @param {String} [cfg.id]  Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {CameraPath} [cfg.eyeCurve] A {@link CameraPath} that defines the path of a {@link Camera}.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._cameraFlightAnimation = new CameraFlightAnimation(this);\n        this._t = 0;\n        this.state = CameraPathAnimation.SCRUBBING;\n        this._playingFromT = 0;\n        this._playingToT = 0;\n        this._playingRate = cfg.playingRate || 1.0;\n        this._playingDir = 1.0;\n        this._lastTime = null;\n\n        this.cameraPath = cfg.cameraPath;\n\n        this._tick = this.scene.on(\"tick\", this._updateT, this);\n    }\n\n    _updateT() {\n        const cameraPath = this._cameraPath;\n        if (!cameraPath) {\n            return;\n        }\n        let numFrames;\n        let t;\n        const time = performance.now();\n        const elapsedSecs = (this._lastTime) ? (time - this._lastTime) * 0.001 : 0;\n        this._lastTime = time;\n        if (elapsedSecs === 0) {\n            return;\n        }\n        switch (this.state) {\n            case CameraPathAnimation.SCRUBBING:\n                return;\n            case CameraPathAnimation.PLAYING:\n                this._t += this._playingRate * elapsedSecs;\n                numFrames = this._cameraPath.frames.length;\n                if (numFrames === 0 || (this._playingDir < 0 && this._t <= 0) || (this._playingDir > 0 && this._t >= this._cameraPath.frames[numFrames - 1].t)) {\n                    this.state = CameraPathAnimation.SCRUBBING;\n                    this._t = this._cameraPath.frames[numFrames - 1].t;\n                    this.fire(\"stopped\");\n                    return;\n                }\n                cameraPath.loadFrame(this._t);\n                break;\n            case CameraPathAnimation.PLAYING_TO:\n                t = this._t + (this._playingRate * elapsedSecs * this._playingDir);\n                if ((this._playingDir < 0 && t <= this._playingToT) || (this._playingDir > 0 && t >= this._playingToT)) {\n                    t = this._playingToT;\n                    this.state = CameraPathAnimation.SCRUBBING;\n                    this.fire(\"stopped\");\n                }\n                this._t = t;\n                cameraPath.loadFrame(this._t);\n                break;\n        }\n    }\n\n    /*\n    * @private\n     */\n    _ease(t, b, c, d) {\n        t /= d;\n        return -c * t * (t - 2) + b;\n    }\n\n    /**\n     * Sets the {@link CameraPath} animated by this CameraPathAnimation.\n     *\n     @param {CameraPath} value The new CameraPath.\n     */\n    set cameraPath(value) {\n        this._cameraPath = value;\n    }\n\n    /**\n     * Gets the {@link CameraPath} animated by this CameraPathAnimation.\n     *\n     @returns {CameraPath} The CameraPath.\n     */\n    get cameraPath() {\n        return this._cameraPath;\n    }\n\n    /**\n     * Sets the rate at which the CameraPathAnimation animates the {@link Camera} along the {@link CameraPath}.\n     *\n     *  @param {Number} value The amount of progress per second.\n     */\n    set rate(value) {\n        this._playingRate = value;\n    }\n\n    /**\n     * Gets the rate at which the CameraPathAnimation animates the {@link Camera} along the {@link CameraPath}.\n     *\n     * @returns {*|number} The current playing rate.\n     */\n    get rate() {\n        return this._playingRate;\n    }\n\n    /**\n     * Begins animating the {@link Camera} along CameraPathAnimation's {@link CameraPath} from the beginning.\n     */\n    play() {\n        if (!this._cameraPath) {\n            return;\n        }\n        this._lastTime = null;\n        this.state = CameraPathAnimation.PLAYING;\n    }\n\n    /**\n     * Begins animating the {@link Camera} along CameraPathAnimation's {@link CameraPath} from the given time.\n     *\n     * @param {Number} t Time instant.\n     */\n    playToT(t) {\n        const cameraPath = this._cameraPath;\n        if (!cameraPath) {\n            return;\n        }\n        this._playingFromT = this._t;\n        this._playingToT = t;\n        this._playingDir = (this._playingToT - this._playingFromT) < 0 ? -1 : 1;\n        this._lastTime = null;\n        this.state = CameraPathAnimation.PLAYING_TO;\n    }\n\n    /**\n     * Animates the {@link Camera} along CameraPathAnimation's {@link CameraPath} to the given frame.\n     *\n     * @param {Number} frameIdx Index of the frame to play to.\n     */\n    playToFrame(frameIdx) {\n        const cameraPath = this._cameraPath;\n        if (!cameraPath) {\n            return;\n        }\n        const frame = cameraPath.frames[frameIdx];\n        if (!frame) {\n            this.error(\"playToFrame - frame index out of range: \" + frameIdx);\n            return;\n        }\n        this.playToT(frame.t);\n    }\n\n    /**\n     * Flies the {@link Camera} directly to the given frame on the CameraPathAnimation's {@link CameraPath}.\n     *\n     * @param {Number} frameIdx Index of the frame to play to.\n     * @param {Function} [ok] Callback to fire when playing is complete.\n     */\n    flyToFrame(frameIdx, ok) {\n        const cameraPath = this._cameraPath;\n        if (!cameraPath) {\n            return;\n        }\n        const frame = cameraPath.frames[frameIdx];\n        if (!frame) {\n            this.error(\"flyToFrame - frame index out of range: \" + frameIdx);\n            return;\n        }\n        this.state = CameraPathAnimation.SCRUBBING;\n        this._cameraFlightAnimation.flyTo(frame, ok);\n    }\n\n    /**\n     * Scrubs the {@link Camera} to the given time on the CameraPathAnimation's {@link CameraPath}.\n     *\n     * @param {Number} t Time instant.\n     */\n    scrubToT(t) {\n        const cameraPath = this._cameraPath;\n        if (!cameraPath) {\n            return;\n        }\n        const camera = this.scene.camera;\n        if (!camera) {\n            return;\n        }\n        this._t = t;\n        cameraPath.loadFrame(this._t);\n        this.state = CameraPathAnimation.SCRUBBING;\n    }\n\n    /**\n     * Scrubs the {@link Camera} to the given frame on the CameraPathAnimation's {@link CameraPath}.\n     *\n     * @param {Number} frameIdx Index of the frame to scrub to.\n     */\n    scrubToFrame(frameIdx) {\n        const cameraPath = this._cameraPath;\n        if (!cameraPath) {\n            return;\n        }\n        const camera = this.scene.camera;\n        if (!camera) {\n            return;\n        }\n        const frame = cameraPath.frames[frameIdx];\n        if (!frame) {\n            this.error(\"playToFrame - frame index out of range: \" + frameIdx);\n            return;\n        }\n        cameraPath.loadFrame(this._t);\n        this.state = CameraPathAnimation.SCRUBBING;\n    }\n\n    /**\n     * Stops playing this CameraPathAnimation.\n     */\n    stop() {\n        this.state = CameraPathAnimation.SCRUBBING;\n        this.fire(\"stopped\");\n    }\n\n    destroy() {\n        super.destroy();\n        this.scene.off(this._tick);\n    }\n}\n\nCameraPathAnimation.STOPPED = 0;\nCameraPathAnimation.SCRUBBING = 1;\nCameraPathAnimation.PLAYING = 2;\nCameraPathAnimation.PLAYING_TO = 3;\n\n/**\n * @desc Defines a shape for one or more {@link Mesh}es.\n *\n * * {@link ReadableGeometry} is a subclass that stores its data in both browser and GPU memory. Use ReadableGeometry when you need to keep the geometry arrays in browser memory.\n * * {@link VBOGeometry} is a subclass that stores its data solely in GPU memory. Use VBOGeometry when you need a lower memory footprint and don't need to keep the geometry data in browser memory.\n */\nclass Geometry extends Component {\n\n    /** @private */\n    get type() {\n        return \"Geometry\";\n    }\n\n    /** @private */\n    get isGeometry() {\n        return true;\n    }\n\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n        stats.memory.meshes++;\n    }\n\n    destroy() {\n        super.destroy();\n        stats.memory.meshes--;\n    }\n}\n\nconst ids$2 = new Map$1({});\n\n/**\n * @desc Represents a chunk of state changes applied by the {@link Scene}'s renderer while it renders a frame.\n *\n * * Contains properties that represent the state changes.\n * * Has a unique automatically-generated numeric ID, which the renderer can use to sort these, in order to avoid applying redundant state changes for each frame.\n * * Initialize your own properties on a RenderState via its constructor.\n *\n * @private\n */\nclass RenderState {\n\n    constructor(cfg) {\n\n        /**\n         The RenderState's ID, unique within the renderer.\n         @property id\n         @type {Number}\n         @final\n         */\n        this.id = ids$2.addItem({});\n        for (const key in cfg) {\n            if (cfg.hasOwnProperty(key)) {\n                this[key] = cfg[key];\n            }\n        }\n    }\n\n    /**\n     Destroys this RenderState.\n     */\n    destroy() {\n        ids$2.removeItem(this.id);\n    }\n}\n\n/**\n * @desc Represents a WebGL ArrayBuffer.\n *\n * @private\n */\nclass ArrayBuf {\n\n    constructor(gl, type, data, numItems, itemSize, usage, normalized, stride, offset) {\n\n        this._gl = gl;\n        this.type = type;\n        this.allocated = false;\n\n        switch (data.constructor) {\n\n            case Uint8Array:\n                this.itemType = gl.UNSIGNED_BYTE;\n                this.itemByteSize = 1;\n                break;\n\n            case Int8Array:\n                this.itemType = gl.BYTE;\n                this.itemByteSize = 1;\n                break;\n\n            case  Uint16Array:\n                this.itemType = gl.UNSIGNED_SHORT;\n                this.itemByteSize = 2;\n                break;\n\n            case  Int16Array:\n                this.itemType = gl.SHORT;\n                this.itemByteSize = 2;\n                break;\n\n            case Uint32Array:\n                this.itemType = gl.UNSIGNED_INT;\n                this.itemByteSize = 4;\n                break;\n\n            case Int32Array:\n                this.itemType = gl.INT;\n                this.itemByteSize = 4;\n                break;\n\n            default:\n                this.itemType = gl.FLOAT;\n                this.itemByteSize = 4;\n        }\n\n        this.usage = usage;\n        this.length = 0;\n        this.dataLength = numItems;\n        this.numItems = 0;\n        this.itemSize = itemSize;\n        this.normalized = !!normalized;\n        this.stride = stride || 0;\n        this.offset = offset || 0;\n\n        this._allocate(data);\n    }\n\n    _allocate(data) {\n        this.allocated = false;\n        this._handle = this._gl.createBuffer();\n        if (!this._handle) {\n            throw \"Failed to allocate WebGL ArrayBuffer\";\n        }\n        if (this._handle) {\n            this._gl.bindBuffer(this.type, this._handle);\n            this._gl.bufferData(this.type, data.length > this.dataLength ? data.slice(0, this.dataLength) : data, this.usage);\n            this._gl.bindBuffer(this.type, null);\n            this.length = data.length;\n            this.numItems = this.length / this.itemSize;\n            this.allocated = true;\n        }\n    }\n\n    setData(data, offset) {\n        if (!this.allocated) {\n            return;\n        }\n        if (data.length + (offset || 0) > this.length) {            // Needs reallocation\n            this.destroy();\n            this._allocate(data);\n        } else {            // No reallocation needed\n            this._gl.bindBuffer(this.type, this._handle);\n            if (offset || offset === 0) {\n                this._gl.bufferSubData(this.type, offset * this.itemByteSize, data);\n            } else {\n                this._gl.bufferData(this.type, data, this.usage);\n            }\n            this._gl.bindBuffer(this.type, null);\n        }\n    }\n\n    bind() {\n        if (!this.allocated) {\n            return;\n        }\n        this._gl.bindBuffer(this.type, this._handle);\n    }\n\n    unbind() {\n        if (!this.allocated) {\n            return;\n        }\n        this._gl.bindBuffer(this.type, null);\n    }\n\n    bindAtLocation(location) {\n        this.bind();\n        this._gl.vertexAttribPointer(location, this.itemSize, this.itemType, this.normalized, 0, 0);\n    }\n\n    destroy() {\n        if (!this.allocated) {\n            return;\n        }\n        this._gl.deleteBuffer(this._handle);\n        this._handle = null;\n        this.allocated = false;\n    }\n}\n\n/**\n * @private\n */\nvar buildEdgeIndices = (function () {\n\n    const uniquePositions = [];\n    const indicesLookup = [];\n    const indicesReverseLookup = [];\n    const weldedIndices = [];\n\n// TODO: Optimize with caching, but need to cater to both compressed and uncompressed positions\n\n    const faces = [];\n    let numFaces = 0;\n    const compa = new Uint16Array(3);\n    const compb = new Uint16Array(3);\n    const compc = new Uint16Array(3);\n    const a = math.vec3();\n    const b = math.vec3();\n    const c = math.vec3();\n    const cb = math.vec3();\n    const ab = math.vec3();\n    const cross = math.vec3();\n    const normal = math.vec3();\n\n    function weldVertices(positions, indices) {\n        const positionsMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n        let vx;\n        let vy;\n        let vz;\n        let key;\n        const precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n        const precision = Math.pow(10, precisionPoints);\n        let i;\n        let len;\n        let lenUniquePositions = 0;\n        for (i = 0, len = positions.length; i < len; i += 3) {\n            vx = positions[i];\n            vy = positions[i + 1];\n            vz = positions[i + 2];\n            key = Math.round(vx * precision) + '_' + Math.round(vy * precision) + '_' + Math.round(vz * precision);\n            if (positionsMap[key] === undefined) {\n                positionsMap[key] = lenUniquePositions / 3;\n                uniquePositions[lenUniquePositions++] = vx;\n                uniquePositions[lenUniquePositions++] = vy;\n                uniquePositions[lenUniquePositions++] = vz;\n            }\n            indicesLookup[i / 3] = positionsMap[key];\n        }\n        for (i = 0, len = indices.length; i < len; i++) {\n            weldedIndices[i] = indicesLookup[indices[i]];\n            indicesReverseLookup[weldedIndices[i]] = indices[i];\n        }\n    }\n\n    function buildFaces(numIndices, positionsDecodeMatrix) {\n        numFaces = 0;\n        for (let i = 0, len = numIndices; i < len; i += 3) {\n            const ia = ((weldedIndices[i]) * 3);\n            const ib = ((weldedIndices[i + 1]) * 3);\n            const ic = ((weldedIndices[i + 2]) * 3);\n            if (positionsDecodeMatrix) {\n                compa[0] = uniquePositions[ia];\n                compa[1] = uniquePositions[ia + 1];\n                compa[2] = uniquePositions[ia + 2];\n                compb[0] = uniquePositions[ib];\n                compb[1] = uniquePositions[ib + 1];\n                compb[2] = uniquePositions[ib + 2];\n                compc[0] = uniquePositions[ic];\n                compc[1] = uniquePositions[ic + 1];\n                compc[2] = uniquePositions[ic + 2];\n                // Decode\n                math.decompressPosition(compa, positionsDecodeMatrix, a);\n                math.decompressPosition(compb, positionsDecodeMatrix, b);\n                math.decompressPosition(compc, positionsDecodeMatrix, c);\n            } else {\n                a[0] = uniquePositions[ia];\n                a[1] = uniquePositions[ia + 1];\n                a[2] = uniquePositions[ia + 2];\n                b[0] = uniquePositions[ib];\n                b[1] = uniquePositions[ib + 1];\n                b[2] = uniquePositions[ib + 2];\n                c[0] = uniquePositions[ic];\n                c[1] = uniquePositions[ic + 1];\n                c[2] = uniquePositions[ic + 2];\n            }\n            math.subVec3(c, b, cb);\n            math.subVec3(a, b, ab);\n            math.cross3Vec3(cb, ab, cross);\n            math.normalizeVec3(cross, normal);\n            const face = faces[numFaces] || (faces[numFaces] = {normal: math.vec3()});\n            face.normal[0] = normal[0];\n            face.normal[1] = normal[1];\n            face.normal[2] = normal[2];\n            numFaces++;\n        }\n    }\n\n    return function (positions, indices, positionsDecodeMatrix, edgeThreshold) {\n        weldVertices(positions, indices);\n        buildFaces(indices.length, positionsDecodeMatrix);\n        const edgeIndices = [];\n        const thresholdDot = Math.cos(math.DEGTORAD * edgeThreshold);\n        const edges = {};\n        let edge1;\n        let edge2;\n        let index1;\n        let index2;\n        let key;\n        let largeIndex = false;\n        let edge;\n        let normal1;\n        let normal2;\n        let dot;\n        let ia;\n        let ib;\n        for (let i = 0, len = indices.length; i < len; i += 3) {\n            const faceIndex = i / 3;\n            for (let j = 0; j < 3; j++) {\n                edge1 = weldedIndices[i + j];\n                edge2 = weldedIndices[i + ((j + 1) % 3)];\n                index1 = Math.min(edge1, edge2);\n                index2 = Math.max(edge1, edge2);\n                key = index1 + \",\" + index2;\n                if (edges[key] === undefined) {\n                    edges[key] = {\n                        index1: index1,\n                        index2: index2,\n                        face1: faceIndex,\n                        face2: undefined\n                    };\n                } else {\n                    edges[key].face2 = faceIndex;\n                }\n            }\n        }\n        for (key in edges) {\n            edge = edges[key];\n            // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n            if (edge.face2 !== undefined) {\n                normal1 = faces[edge.face1].normal;\n                normal2 = faces[edge.face2].normal;\n                dot = math.dotVec3(normal1, normal2);\n                if (dot > thresholdDot) {\n                    continue;\n                }\n            }\n            ia = indicesReverseLookup[edge.index1];\n            ib = indicesReverseLookup[edge.index2];\n            if (!largeIndex && ia > 65535 || ib > 65535) {\n                largeIndex = true;\n            }\n            edgeIndices.push(ia);\n            edgeIndices.push(ib);\n        }\n        return (largeIndex) ? new Uint32Array(edgeIndices) : new Uint16Array(edgeIndices);\n    };\n})();\n\n/**\n * Private geometry compression and decompression utilities.\n */\n\n/**\n * @private\n * @param array\n * @returns {{min: Float32Array, max: Float32Array}}\n */\nfunction getPositionsBounds(array) {\n    const min = new Float32Array(3);\n    const max = new Float32Array(3);\n    let i, j;\n    for (i = 0; i < 3; i++) {\n        min[i] = Number.MAX_VALUE;\n        max[i] = -Number.MAX_VALUE;\n    }\n    for (i = 0; i < array.length; i += 3) {\n        for (j = 0; j < 3; j++) {\n            min[j] = Math.min(min[j], array[i + j]);\n            max[j] = Math.max(max[j], array[i + j]);\n        }\n    }\n    return {\n        min: min,\n        max: max\n    };\n}\n\nconst createPositionsDecodeMatrix$1 = (function () {\n    const translate = math.mat4();\n    const scale = math.mat4();\n    return function (aabb, positionsDecodeMatrix) {\n        positionsDecodeMatrix = positionsDecodeMatrix || math.mat4();\n        const xmin = aabb[0];\n        const ymin = aabb[1];\n        const zmin = aabb[2];\n        const xwid = aabb[3] - xmin;\n        const ywid = aabb[4] - ymin;\n        const zwid = aabb[5] - zmin;\n        const maxInt = 65535;\n        math.identityMat4(translate);\n        math.translationMat4v(aabb, translate);\n        math.identityMat4(scale);\n        math.scalingMat4v([xwid / maxInt, ywid / maxInt, zwid / maxInt], scale);\n        math.mulMat4(translate, scale, positionsDecodeMatrix);\n        return positionsDecodeMatrix;\n    };\n})();\n\n/**\n * @private\n */\nvar compressPositions = (function () { // http://cg.postech.ac.kr/research/mesh_comp_mobile/mesh_comp_mobile_conference.pdf\n    const translate = math.mat4();\n    const scale = math.mat4();\n    return function (array, min, max) {\n        const quantized = new Uint16Array(array.length);\n        const multiplier = new Float32Array([\n            max[0] !== min[0] ? 65535 / (max[0] - min[0]) : 0,\n            max[1] !== min[1] ? 65535 / (max[1] - min[1]) : 0,\n            max[2] !== min[2] ? 65535 / (max[2] - min[2]) : 0\n        ]);\n        let i;\n        for (i = 0; i < array.length; i += 3) {\n            quantized[i + 0] = Math.max(0, Math.min(65535, Math.floor((array[i + 0] - min[0]) * multiplier[0])));\n            quantized[i + 1] = Math.max(0, Math.min(65535, Math.floor((array[i + 1] - min[1]) * multiplier[1])));\n            quantized[i + 2] = Math.max(0, Math.min(65535, Math.floor((array[i + 2] - min[2]) * multiplier[2])));\n        }\n        math.identityMat4(translate);\n        math.translationMat4v(min, translate);\n        math.identityMat4(scale);\n        math.scalingMat4v([\n            (max[0] - min[0]) / 65535,\n            (max[1] - min[1]) / 65535,\n            (max[2] - min[2]) / 65535\n        ], scale);\n        const decodeMat = math.mulMat4(translate, scale, math.identityMat4());\n        return {\n            quantized: quantized,\n            decodeMatrix: decodeMat\n        };\n    };\n})();\n\nfunction compressPosition(p, aabb, q) {\n    const multiplier = new Float32Array([\n        aabb[3] !== aabb[0] ? 65535 / (aabb[3] - aabb[0]) : 0,\n        aabb[4] !== aabb[1] ? 65535 / (aabb[4] - aabb[1]) : 0,\n        aabb[5] !== aabb[2] ? 65535 / (aabb[5] - aabb[2]) : 0\n    ]);\n    q[0] = Math.max(0, Math.min(65535, Math.floor((p[0] - aabb[0]) * multiplier[0])));\n    q[1] = Math.max(0, Math.min(65535, Math.floor((p[1] - aabb[1]) * multiplier[1])));\n    q[2] = Math.max(0, Math.min(65535, Math.floor((p[2] - aabb[2]) * multiplier[2])));\n}\n\nfunction decompressPosition(position, decodeMatrix, dest) {\n    dest[0] = position[0] * decodeMatrix[0] + decodeMatrix[12];\n    dest[1] = position[1] * decodeMatrix[5] + decodeMatrix[13];\n    dest[2] = position[2] * decodeMatrix[10] + decodeMatrix[14];\n    return dest;\n}\n\nfunction decompressAABB(aabb, decodeMatrix, dest = aabb) {\n    dest[0] = aabb[0] * decodeMatrix[0] + decodeMatrix[12];\n    dest[1] = aabb[1] * decodeMatrix[5] + decodeMatrix[13];\n    dest[2] = aabb[2] * decodeMatrix[10] + decodeMatrix[14];\n    dest[3] = aabb[3] * decodeMatrix[0] + decodeMatrix[12];\n    dest[4] = aabb[4] * decodeMatrix[5] + decodeMatrix[13];\n    dest[5] = aabb[5] * decodeMatrix[10] + decodeMatrix[14];\n    return dest;\n}\n\n/**\n * @private\n */\nfunction decompressPositions(positions, decodeMatrix, dest = new Float32Array(positions.length)) {\n    for (let i = 0, len = positions.length; i < len; i += 3) {\n        dest[i + 0] = positions[i + 0] * decodeMatrix[0] + decodeMatrix[12];\n        dest[i + 1] = positions[i + 1] * decodeMatrix[5] + decodeMatrix[13];\n        dest[i + 2] = positions[i + 2] * decodeMatrix[10] + decodeMatrix[14];\n    }\n    return dest;\n}\n\n//--------------- UVs --------------------------------------------------------------------------------------------------\n\n/**\n * @private\n * @param array\n * @returns {{min: Float32Array, max: Float32Array}}\n */\nfunction getUVBounds(array) {\n    const min = new Float32Array(2);\n    const max = new Float32Array(2);\n    let i, j;\n    for (i = 0; i < 2; i++) {\n        min[i] = Number.MAX_VALUE;\n        max[i] = -Number.MAX_VALUE;\n    }\n    for (i = 0; i < array.length; i += 2) {\n        for (j = 0; j < 2; j++) {\n            min[j] = Math.min(min[j], array[i + j]);\n            max[j] = Math.max(max[j], array[i + j]);\n        }\n    }\n    return {\n        min: min,\n        max: max\n    };\n}\n\n/**\n * @private\n */\nvar compressUVs = (function () {\n    const translate = math.mat3();\n    const scale = math.mat3();\n    return function (array, min, max) {\n        const quantized = new Uint16Array(array.length);\n        const multiplier = new Float32Array([\n            65535 / (max[0] - min[0]),\n            65535 / (max[1] - min[1])\n        ]);\n        let i;\n        for (i = 0; i < array.length; i += 2) {\n            quantized[i + 0] = Math.max(0, Math.min(65535, Math.floor((array[i + 0] - min[0]) * multiplier[0])));\n            quantized[i + 1] = Math.max(0, Math.min(65535, Math.floor((array[i + 1] - min[1]) * multiplier[1])));\n        }\n        math.identityMat3(translate);\n        math.translationMat3v(min, translate);\n        math.identityMat3(scale);\n        math.scalingMat3v([\n            (max[0] - min[0]) / 65535,\n            (max[1] - min[1]) / 65535\n        ], scale);\n        const decodeMat = math.mulMat3(translate, scale, math.identityMat3());\n        return {\n            quantized: quantized,\n            decodeMatrix: decodeMat\n        };\n    };\n})();\n\n\n//--------------- Normals ----------------------------------------------------------------------------------------------\n\n/**\n * @private\n */\nfunction compressNormals(array) { // http://jcgt.org/published/0003/02/01/\n\n    // Note: three elements for each encoded normal, in which the last element in each triplet is redundant.\n    // This is to work around a mysterious WebGL issue where 2-element normals just wouldn't work in the shader :/\n\n    const encoded = new Int8Array(array.length);\n    let oct, dec, best, currentCos, bestCos;\n    for (let i = 0; i < array.length; i += 3) {\n        // Test various combinations of ceil and floor\n        // to minimize rounding errors\n        best = oct = octEncodeVec3$1(array, i, \"floor\", \"floor\");\n        dec = octDecodeVec2$1(oct);\n        currentCos = bestCos = dot$1(array, i, dec);\n        oct = octEncodeVec3$1(array, i, \"ceil\", \"floor\");\n        dec = octDecodeVec2$1(oct);\n        currentCos = dot$1(array, i, dec);\n        if (currentCos > bestCos) {\n            best = oct;\n            bestCos = currentCos;\n        }\n        oct = octEncodeVec3$1(array, i, \"floor\", \"ceil\");\n        dec = octDecodeVec2$1(oct);\n        currentCos = dot$1(array, i, dec);\n        if (currentCos > bestCos) {\n            best = oct;\n            bestCos = currentCos;\n        }\n        oct = octEncodeVec3$1(array, i, \"ceil\", \"ceil\");\n        dec = octDecodeVec2$1(oct);\n        currentCos = dot$1(array, i, dec);\n        if (currentCos > bestCos) {\n            best = oct;\n            bestCos = currentCos;\n        }\n        encoded[i] = best[0];\n        encoded[i + 1] = best[1];\n    }\n    return encoded;\n}\n\n/**\n * @private\n */\nfunction octEncodeVec3$1(array, i, xfunc, yfunc) { // Oct-encode single normal vector in 2 bytes\n    let x = array[i] / (Math.abs(array[i]) + Math.abs(array[i + 1]) + Math.abs(array[i + 2]));\n    let y = array[i + 1] / (Math.abs(array[i]) + Math.abs(array[i + 1]) + Math.abs(array[i + 2]));\n    if (array[i + 2] < 0) {\n        let tempx = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n        let tempy = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n        x = tempx;\n        y = tempy;\n    }\n    return new Int8Array([\n        Math[xfunc](x * 127.5 + (x < 0 ? -1 : 0)),\n        Math[yfunc](y * 127.5 + (y < 0 ? -1 : 0))\n    ]);\n}\n\n/**\n * Decode an oct-encoded normal\n */\nfunction octDecodeVec2$1(oct) {\n    let x = oct[0];\n    let y = oct[1];\n    x /= x < 0 ? 127 : 128;\n    y /= y < 0 ? 127 : 128;\n    const z = 1 - Math.abs(x) - Math.abs(y);\n    if (z < 0) {\n        x = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n        y = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n    }\n    const length = Math.sqrt(x * x + y * y + z * z);\n    return [\n        x / length,\n        y / length,\n        z / length\n    ];\n}\n\n/**\n * Dot product of a normal in an array against a candidate decoding\n * @private\n */\nfunction dot$1(array, i, vec3) {\n    return array[i] * vec3[0] + array[i + 1] * vec3[1] + array[i + 2] * vec3[2];\n}\n\n/**\n * @private\n */\nfunction decompressUV(uv, decodeMatrix, dest) {\n    dest[0] = uv[0] * decodeMatrix[0] + decodeMatrix[6];\n    dest[1] = uv[1] * decodeMatrix[4] + decodeMatrix[7];\n}\n\n/**\n * @private\n */\nfunction decompressUVs(uvs, decodeMatrix, dest = new Float32Array(uvs.length)) {\n    for (let i = 0, len = uvs.length; i < len; i += 3) {\n        dest[i + 0] = uvs[i + 0] * decodeMatrix[0] + decodeMatrix[6];\n        dest[i + 1] = uvs[i + 1] * decodeMatrix[4] + decodeMatrix[7];\n    }\n    return dest;\n}\n\n/**\n * @private\n */\nfunction decompressNormal(oct, result) {\n    let x = oct[0];\n    let y = oct[1];\n    x = (2 * x + 1) / 255;\n    y = (2 * y + 1) / 255;\n    const z = 1 - Math.abs(x) - Math.abs(y);\n    if (z < 0) {\n        x = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n        y = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n    }\n    const length = Math.sqrt(x * x + y * y + z * z);\n    result[0] = x / length;\n    result[1] = y / length;\n    result[2] = z / length;\n    return result;\n}\n\n/**\n * @private\n */\nfunction decompressNormals(octs, result) {\n    for (let i = 0, j = 0, len = octs.length; i < len; i += 2) {\n        let x = octs[i + 0];\n        let y = octs[i + 1];\n        x = (2 * x + 1) / 255;\n        y = (2 * y + 1) / 255;\n        const z = 1 - Math.abs(x) - Math.abs(y);\n        if (z < 0) {\n            x = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n            y = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n        }\n        const length = Math.sqrt(x * x + y * y + z * z);\n        result[j + 0] = x / length;\n        result[j + 1] = y / length;\n        result[j + 2] = z / length;\n        j += 3;\n    }\n    return result;\n}\n\n/**\n * @private\n */\nconst geometryCompressionUtils = {\n\n    getPositionsBounds: getPositionsBounds,\n    createPositionsDecodeMatrix: createPositionsDecodeMatrix$1,\n    compressPositions: compressPositions,\n    compressPosition:compressPosition,\n    decompressPositions: decompressPositions,\n    decompressPosition: decompressPosition,\n    decompressAABB: decompressAABB,\n\n    getUVBounds: getUVBounds,\n    compressUVs: compressUVs,\n    decompressUVs: decompressUVs,\n    decompressUV: decompressUV,\n\n    compressNormals: compressNormals,\n    decompressNormals: decompressNormals,\n    decompressNormal: decompressNormal\n};\n\nconst memoryStats$1 = stats.memory;\nconst tempAABB$3 = math.AABB3();\n\n/**\n * @desc A {@link Geometry} that keeps its geometry data in both browser and GPU memory.\n *\n * ReadableGeometry uses more memory than {@link VBOGeometry}, which only stores its geometry data in GPU memory.\n *\n * ## Usage\n *\n * Creating a {@link Mesh} with a ReadableGeometry that defines a single triangle, plus a {@link PhongMaterial} with diffuse {@link Texture}:\n *\n * [[Run this example](/examples/index.html#geometry_ReadableGeometry)]\n *\n * ````javascript\n * import {Viewer, Mesh, ReadableGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *         canvasId: \"myCanvas\"\n *     });\n *\n * const myMesh = new Mesh(viewer.scene, {\n *         geometry: new ReadableGeometry(viewer.scene, {\n *             primitive: \"triangles\",\n *             positions: [0.0, 3, 0.0, -3, -3, 0.0, 3, -3, 0.0],\n *             normals: [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0],\n *             uv: [0.0, 0.0, 0.5, 1.0, 1.0, 0.0],\n *             indices: [0, 1, 2]\n *         }),\n *         material: new PhongMaterial(viewer.scene, {\n *             diffuseMap: new Texture(viewer.scene, {\n *                 src: \"textures/diffuse/uvGrid2.jpg\"\n *             }),\n *             backfaces: true\n *         })\n *     });\n *\n * // Get geometry data from browser memory:\n *\n * const positions = myMesh.geometry.positions; // Flat arrays\n * const normals = myMesh.geometry.normals;\n * const uv = myMesh.geometry.uv;\n * const indices = myMesh.geometry.indices;\n *\n * ````\n */\nclass ReadableGeometry extends Geometry {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"ReadableGeometry\";\n    }\n\n    /**\n     * @private\n     * @returns {Boolean}\n     */\n    get isReadableGeometry() {\n        return true;\n    }\n\n    /**\n     *\n     @class ReadableGeometry\n     @module xeokit\n     @submodule geometry\n     @constructor\n     @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     @param {*} [cfg] Configs\n     @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene},\n     generated automatically when omitted.\n     @param {String:Object} [cfg.meta] Optional map of user-defined metadata to attach to this Geometry.\n     @param [cfg.primitive=\"triangles\"] {String} The primitive type. Accepted values are 'points', 'lines', 'line-loop', 'line-strip', 'triangles', 'triangle-strip' and 'triangle-fan'.\n     @param [cfg.positions] {Number[]} Positions array.\n     @param [cfg.normals] {Number[]} Vertex normal vectors array.\n     @param [cfg.uv] {Number[]} UVs array.\n     @param [cfg.colors] {Number[]} Vertex colors.\n     @param [cfg.indices] {Number[]} Indices array.\n     @param [cfg.autoVertexNormals=false] {Boolean} Set true to automatically generate normal vectors from the positions and\n     indices, if those are supplied.\n     @param [cfg.compressGeometry=false] {Boolean} Stores positions, colors, normals and UVs in compressGeometry and oct-encoded formats\n     for reduced memory footprint and GPU bus usage.\n     @param [cfg.edgeThreshold=10] {Number} When a {@link Mesh} renders this Geometry as wireframe,\n     this indicates the threshold angle (in degrees) between the face normals of adjacent triangles below which the edge is discarded.\n     @extends Component\n     * @param owner\n     * @param cfg\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({ // Arrays for emphasis effects are got from xeokit.Geometry friend methods\n            compressGeometry: !!cfg.compressGeometry,\n            primitive: null, // WebGL enum\n            primitiveName: null, // String\n            positions: null,    // Uint16Array when compressGeometry == true, else Float32Array\n            normals: null,      // Uint8Array when compressGeometry == true, else Float32Array\n            colors: null,\n            uv: null,           // Uint8Array when compressGeometry == true, else Float32Array\n            indices: null,\n            positionsDecodeMatrix: null, // Set when compressGeometry == true\n            uvDecodeMatrix: null, // Set when compressGeometry == true\n            positionsBuf: null,\n            normalsBuf: null,\n            colorsbuf: null,\n            uvBuf: null,\n            indicesBuf: null,\n            hash: \"\"\n        });\n\n        this._numTriangles = 0;\n\n        this._edgeThreshold = cfg.edgeThreshold || 10.0;\n\n        // Lazy-generated VBOs\n\n        this._edgeIndicesBuf = null;\n        this._pickTrianglePositionsBuf = null;\n        this._pickTriangleColorsBuf = null;\n\n        // Local-space Boundary3D\n\n        this._aabbDirty = true;\n\n        this._boundingSphere = true;\n        this._aabb = null;\n        this._aabbDirty = true;\n\n        this._obb = null;\n        this._obbDirty = true;\n\n        const state = this._state;\n        const gl = this.scene.canvas.gl;\n\n        // Primitive type\n\n        cfg.primitive = cfg.primitive || \"triangles\";\n        switch (cfg.primitive) {\n            case \"points\":\n                state.primitive = gl.POINTS;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"lines\":\n                state.primitive = gl.LINES;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"line-loop\":\n                state.primitive = gl.LINE_LOOP;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"line-strip\":\n                state.primitive = gl.LINE_STRIP;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"triangles\":\n                state.primitive = gl.TRIANGLES;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"triangle-strip\":\n                state.primitive = gl.TRIANGLE_STRIP;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"triangle-fan\":\n                state.primitive = gl.TRIANGLE_FAN;\n                state.primitiveName = cfg.primitive;\n                break;\n            default:\n                this.error(\"Unsupported value for 'primitive': '\" + cfg.primitive +\n                    \"' - supported values are 'points', 'lines', 'line-loop', 'line-strip', 'triangles', \" +\n                    \"'triangle-strip' and 'triangle-fan'. Defaulting to 'triangles'.\");\n                state.primitive = gl.TRIANGLES;\n                state.primitiveName = cfg.primitive;\n        }\n\n        if (cfg.positions) {\n            if (this._state.compressGeometry) {\n                const bounds = geometryCompressionUtils.getPositionsBounds(cfg.positions);\n                const result = geometryCompressionUtils.compressPositions(cfg.positions, bounds.min, bounds.max);\n                state.positions = result.quantized;\n                state.positionsDecodeMatrix = result.decodeMatrix;\n            } else {\n                state.positions = cfg.positions.constructor === Float32Array ? cfg.positions : new Float32Array(cfg.positions);\n            }\n        }\n        if (cfg.colors) {\n            state.colors = cfg.colors.constructor === Float32Array ? cfg.colors : new Float32Array(cfg.colors);\n        }\n        if (cfg.uv) {\n            if (this._state.compressGeometry) {\n                const bounds = geometryCompressionUtils.getUVBounds(cfg.uv);\n                const result = geometryCompressionUtils.compressUVs(cfg.uv, bounds.min, bounds.max);\n                state.uv = result.quantized;\n                state.uvDecodeMatrix = result.decodeMatrix;\n            } else {\n                state.uv = cfg.uv.constructor === Float32Array ? cfg.uv : new Float32Array(cfg.uv);\n            }\n        }\n        if (cfg.normals) {\n            if (this._state.compressGeometry) {\n                state.normals = geometryCompressionUtils.compressNormals(cfg.normals);\n            } else {\n                state.normals = cfg.normals.constructor === Float32Array ? cfg.normals : new Float32Array(cfg.normals);\n            }\n        }\n        if (cfg.indices) {\n            state.indices = (cfg.indices.constructor === Uint32Array || cfg.indices.constructor === Uint16Array) ? cfg.indices : new Uint32Array(cfg.indices);\n            if (this._state.primitiveName === \"triangles\") {\n                this._numTriangles = (cfg.indices.length / 3);\n            }\n        }\n\n        this._buildHash();\n\n        memoryStats$1.meshes++;\n\n        if (state.indices) {\n            state.indicesBuf = new ArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, state.indices, state.indices.length, 1, gl.STATIC_DRAW);\n            memoryStats$1.indices += state.indicesBuf.numItems;\n        }\n        if (state.positions) {\n            state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, state.positions, state.positions.length, 3, gl.STATIC_DRAW);\n            memoryStats$1.positions += state.positionsBuf.numItems;\n        }\n        if (state.normals) {\n            let normalized = state.compressGeometry;\n            state.normalsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, state.normals, state.normals.length, 3, gl.STATIC_DRAW, normalized);\n            memoryStats$1.normals += state.normalsBuf.numItems;\n        }\n        if (state.colors) {\n            state.colorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, state.colors, state.colors.length, 4, gl.STATIC_DRAW);\n            memoryStats$1.colors += state.colorsBuf.numItems;\n        }\n        if (state.uv) {\n            state.uvBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, state.uv, state.uv.length, 2, gl.STATIC_DRAW);\n            memoryStats$1.uvs += state.uvBuf.numItems;\n        }\n    }\n\n    _buildHash() {\n        const state = this._state;\n        const hash = [\"/g\"];\n        hash.push(\"/\" + state.primitive + \";\");\n        if (state.positions) {\n            hash.push(\"p\");\n        }\n        if (state.colors) {\n            hash.push(\"c\");\n        }\n        if (state.normals || state.autoVertexNormals) {\n            hash.push(\"n\");\n        }\n        if (state.uv) {\n            hash.push(\"u\");\n        }\n        if (state.compressGeometry) {\n            hash.push(\"cp\");\n        }\n        hash.push(\";\");\n        state.hash = hash.join(\"\");\n    }\n\n    _getEdgeIndices() {\n        if (!this._edgeIndicesBuf) {\n            this._buildEdgeIndices();\n        }\n        return this._edgeIndicesBuf;\n    }\n\n    _getPickTrianglePositions() {\n        if (!this._pickTrianglePositionsBuf) {\n            this._buildPickTriangleVBOs();\n        }\n        return this._pickTrianglePositionsBuf;\n    }\n\n    _getPickTriangleColors() {\n        if (!this._pickTriangleColorsBuf) {\n            this._buildPickTriangleVBOs();\n        }\n        return this._pickTriangleColorsBuf;\n    }\n\n    _buildEdgeIndices() { // FIXME: Does not adjust indices after other objects are deleted from vertex buffer!!\n        const state = this._state;\n        if (!state.positions || !state.indices) {\n            return;\n        }\n        const gl = this.scene.canvas.gl;\n        const edgeIndices = buildEdgeIndices(state.positions, state.indices, state.positionsDecodeMatrix, this._edgeThreshold);\n        this._edgeIndicesBuf = new ArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, edgeIndices, edgeIndices.length, 1, gl.STATIC_DRAW);\n        memoryStats$1.indices += this._edgeIndicesBuf.numItems;\n    }\n\n    _buildPickTriangleVBOs() { // Builds positions and indices arrays that allow each triangle to have a unique color\n        const state = this._state;\n        if (!state.positions || !state.indices) {\n            return;\n        }\n        const gl = this.scene.canvas.gl;\n        const arrays = math.buildPickTriangles(state.positions, state.indices, state.compressGeometry);\n        const positions = arrays.positions;\n        const colors = arrays.colors;\n        this._pickTrianglePositionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, positions, positions.length, 3, gl.STATIC_DRAW);\n        this._pickTriangleColorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, colors, colors.length, 4, gl.STATIC_DRAW, true);\n        memoryStats$1.positions += this._pickTrianglePositionsBuf.numItems;\n        memoryStats$1.colors += this._pickTriangleColorsBuf.numItems;\n    }\n\n    _buildPickVertexVBOs() {\n        // var state = this._state;\n        // if (!state.positions || !state.indices) {\n        //     return;\n        // }\n        // var gl = this.scene.canvas.gl;\n        // var arrays = math.buildPickVertices(state.positions, state.indices, state.compressGeometry);\n        // var pickVertexPositions = arrays.positions;\n        // var pickColors = arrays.colors;\n        // this._pickVertexPositionsBuf = new xeokit.renderer.ArrayBuf(gl, gl.ARRAY_BUFFER, pickVertexPositions, pickVertexPositions.length, 3, gl.STATIC_DRAW);\n        // this._pickVertexColorsBuf = new xeokit.renderer.ArrayBuf(gl, gl.ARRAY_BUFFER, pickColors, pickColors.length, 4, gl.STATIC_DRAW, true);\n        // memoryStats.positions += this._pickVertexPositionsBuf.numItems;\n        // memoryStats.colors += this._pickVertexColorsBuf.numItems;\n    }\n\n    /**\n     * Gets the Geometry's primitive type.\n\n     Valid types are: 'points', 'lines', 'line-loop', 'line-strip', 'triangles', 'triangle-strip' and 'triangle-fan'.\n\n     @property primitive\n     @default \"triangles\"\n     @type {String}\n     */\n    get primitive() {\n        return this._state.primitiveName;\n    }\n\n    /**\n     Indicates if this Geometry is quantized.\n\n     Compression is an internally-performed optimization which stores positions, colors, normals and UVs\n     in quantized and oct-encoded formats for reduced memory footprint and GPU bus usage.\n\n     Quantized geometry may not be updated.\n\n     @property compressGeometry\n     @default false\n     @type {Boolean}\n     @final\n     */\n    get compressGeometry() {\n        return this._state.compressGeometry;\n    }\n\n    /**\n     The Geometry's vertex positions.\n\n     @property positions\n     @default null\n     @type {Number[]}\n     */\n    get positions() {\n        if (!this._state.positions) {\n            return null;\n        }\n        if (!this._state.compressGeometry) {\n            return this._state.positions;\n        }\n        if (!this._decompressedPositions) {\n            this._decompressedPositions = new Float32Array(this._state.positions.length);\n            geometryCompressionUtils.decompressPositions(this._state.positions, this._state.positionsDecodeMatrix, this._decompressedPositions);\n        }\n        return this._decompressedPositions;\n    }\n\n    set positions(newPositions) {\n        const state = this._state;\n        const positions = state.positions;\n        if (!positions) {\n            this.error(\"can't update geometry positions - geometry has no positions\");\n            return;\n        }\n        if (positions.length !== newPositions.length) {\n            this.error(\"can't update geometry positions - new positions are wrong length\");\n            return;\n        }\n        if (this._state.compressGeometry) {\n            const bounds = geometryCompressionUtils.getPositionsBounds(newPositions);\n            const result = geometryCompressionUtils.compressPositions(newPositions, bounds.min, bounds.max);\n            newPositions = result.quantized; // TODO: Copy in-place\n            state.positionsDecodeMatrix = result.decodeMatrix;\n        }\n        positions.set(newPositions);\n        if (state.positionsBuf) {\n            state.positionsBuf.setData(positions);\n        }\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     The Geometry's vertex normals.\n\n     @property normals\n     @default null\n     @type {Number[]}\n     */\n    get normals() {\n        if (!this._state.normals) {\n            return;\n        }\n        if (!this._state.compressGeometry) {\n            return this._state.normals;\n        }\n        if (!this._decompressedNormals) {\n            const lenCompressed = this._state.normals.length;\n            const lenDecompressed = lenCompressed + (lenCompressed / 2); // 2 -> 3\n            this._decompressedNormals = new Float32Array(lenDecompressed);\n            geometryCompressionUtils.decompressNormals(this._state.normals, this._decompressedNormals);\n        }\n        return this._decompressedNormals;\n    }\n\n    set normals(newNormals) {\n        if (this._state.compressGeometry) {\n            this.error(\"can't update geometry normals - quantized geometry is immutable\"); // But will be eventually\n            return;\n        }\n        const state = this._state;\n        const normals = state.normals;\n        if (!normals) {\n            this.error(\"can't update geometry normals - geometry has no normals\");\n            return;\n        }\n        if (normals.length !== newNormals.length) {\n            this.error(\"can't update geometry normals - new normals are wrong length\");\n            return;\n        }\n        normals.set(newNormals);\n        if (state.normalsBuf) {\n            state.normalsBuf.setData(normals);\n        }\n        this.glRedraw();\n    }\n\n\n    /**\n     The Geometry's UV coordinates.\n\n     @property uv\n     @default null\n     @type {Number[]}\n     */\n    get uv() {\n        if (!this._state.uv) {\n            return null;\n        }\n        if (!this._state.compressGeometry) {\n            return this._state.uv;\n        }\n        if (!this._decompressedUV) {\n            this._decompressedUV = new Float32Array(this._state.uv.length);\n            geometryCompressionUtils.decompressUVs(this._state.uv, this._state.uvDecodeMatrix, this._decompressedUV);\n        }\n        return this._decompressedUV;\n    }\n\n    set uv(newUV) {\n        if (this._state.compressGeometry) {\n            this.error(\"can't update geometry UVs - quantized geometry is immutable\"); // But will be eventually\n            return;\n        }\n        const state = this._state;\n        const uv = state.uv;\n        if (!uv) {\n            this.error(\"can't update geometry UVs - geometry has no UVs\");\n            return;\n        }\n        if (uv.length !== newUV.length) {\n            this.error(\"can't update geometry UVs - new UVs are wrong length\");\n            return;\n        }\n        uv.set(newUV);\n        if (state.uvBuf) {\n            state.uvBuf.setData(uv);\n        }\n        this.glRedraw();\n    }\n\n    /**\n     The Geometry's vertex colors.\n\n     @property colors\n     @default null\n     @type {Number[]}\n     */\n    get colors() {\n        return this._state.colors;\n    }\n\n    set colors(newColors) {\n        if (this._state.compressGeometry) {\n            this.error(\"can't update geometry colors - quantized geometry is immutable\"); // But will be eventually\n            return;\n        }\n        const state = this._state;\n        const colors = state.colors;\n        if (!colors) {\n            this.error(\"can't update geometry colors - geometry has no colors\");\n            return;\n        }\n        if (colors.length !== newColors.length) {\n            this.error(\"can't update geometry colors - new colors are wrong length\");\n            return;\n        }\n        colors.set(newColors);\n        if (state.colorsBuf) {\n            state.colorsBuf.setData(colors);\n        }\n        this.glRedraw();\n    }\n\n    /**\n     The Geometry's indices.\n\n     If ````xeokit.WEBGL_INFO.SUPPORTED_EXTENSIONS[\"OES_element_index_uint\"]```` is true, then this can be\n     a ````Uint32Array````, otherwise it needs to be a ````Uint16Array````.\n\n     @property indices\n     @default null\n     @type Uint16Array | Uint32Array\n     @final\n     */\n    get indices() {\n        return this._state.indices;\n    }\n\n    /**\n     * Local-space axis-aligned 3D boundary (AABB) of this geometry.\n     *\n     * The AABB is represented by a six-element Float64Array containing the min/max extents of the\n     * axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n     *\n     * @property aabb\n     * @final\n     * @type {Number[]}\n     */\n    get aabb() {\n        if (this._aabbDirty) {\n            if (!this._aabb) {\n                this._aabb = math.AABB3();\n            }\n            math.positions3ToAABB3(this._state.positions, this._aabb, this._state.positionsDecodeMatrix);\n            this._aabbDirty = false;\n        }\n        return this._aabb;\n    }\n\n    /**\n     * Local-space oriented 3D boundary (OBB) of this geometry.\n     *\n     * The OBB is represented by a 32-element Float64Array containing the eight vertices of the box,\n     * where each vertex is a homogeneous coordinate having [x,y,z,w] elements.\n     *\n     * @property obb\n     * @final\n     * @type {Number[]}\n     */\n    get obb() {\n        if (this._obbDirty) {\n            if (!this._obb) {\n                this._obb = math.OBB3();\n            }\n            math.positions3ToAABB3(this._state.positions, tempAABB$3, this._state.positionsDecodeMatrix);\n            math.AABB3ToOBB3(tempAABB$3, this._obb);\n            this._obbDirty = false;\n        }\n        return this._obb;\n    }\n\n    _getMetrics() {\n        if (! (\"_metrics\" in this)) {\n            switch (this._state.primitiveName) {\n            case \"solid\":\n            case \"surface\":\n            case \"triangles\": {\n                const indices = this._state.indices;\n                const positions = this._state.positions;\n                const getPos = (i, out) => {\n                    const idx = indices[i] * 3;\n                    for (let j = 0; j < 3; ++j) {\n                        out[j] = positions[idx + j];\n                    }                    return out;\n                };\n                const tmp = [ math.vec3(), math.vec3(), math.vec3(), math.vec3() ];\n                let totalArea = 0;\n                const centroid = math.vec3([ 0, 0, 0 ]);\n                for (let i = 0; i < indices.length; i += 3) {\n                    const v0 = getPos(i,   tmp[0]);\n                    const v1 = getPos(i+1, tmp[1]);\n                    const v2 = getPos(i+2, tmp[2]);\n                    math.addVec3(v0, v1, tmp[3]);\n                    math.addVec3(v2, tmp[3], tmp[3]);\n                    const faceArea = math.lenVec3(\n                        math.cross3Vec3(\n                            math.subVec3(v1, v0, tmp[1]),\n                            math.subVec3(v2, v0, tmp[2]),\n                            tmp[0])) / 2;\n                    totalArea += faceArea;\n                    math.mulVec3Scalar(tmp[3], faceArea, tmp[3]);\n                    math.addVec3(centroid, tmp[3], centroid);\n                }\n                this._metrics = { surfaceArea: totalArea, centroid: math.mulVec3Scalar(centroid, 1 / totalArea / 3, centroid) };\n                break;\n            }\n            default:\n                this._metrics = { surfaceArea: 0 };\n                break;\n            }\n        }\n        return this._metrics;\n    }\n\n    /**\n     * Returns the surface area of this Mesh.\n     * @returns {number}\n     */\n    get surfaceArea() {\n        return this._getMetrics().surfaceArea;\n    }\n\n    /**\n     * Returns the centroid of this Mesh.\n     * @returns {number}\n     */\n    get centroid() {\n        return this._getMetrics().centroid;\n    }\n\n    /**\n     * Approximate number of triangles in this ReadableGeometry.\n     *\n     * Will be zero if {@link ReadableGeometry#primitive} is not 'triangles', 'triangle-strip' or 'triangle-fan'.\n     *\n     * @type {Number}\n     */\n    get numTriangles() {\n        return this._numTriangles;\n    }\n\n    _setAABBDirty() {\n        if (this._aabbDirty) {\n            return;\n        }\n        this._aabbDirty = true;\n        this._aabbDirty = true;\n        this._obbDirty = true;\n    }\n\n    _getState() {\n        return this._state;\n    }\n\n    /**\n     * Destroys this ReadableGeometry\n     */\n    destroy() {\n        super.destroy();\n        const state = this._state;\n        if (state.indicesBuf) {\n            state.indicesBuf.destroy();\n        }\n        if (state.positionsBuf) {\n            state.positionsBuf.destroy();\n        }\n        if (state.normalsBuf) {\n            state.normalsBuf.destroy();\n        }\n        if (state.uvBuf) {\n            state.uvBuf.destroy();\n        }\n        if (state.colorsBuf) {\n            state.colorsBuf.destroy();\n        }\n        if (this._edgeIndicesBuf) {\n            this._edgeIndicesBuf.destroy();\n        }\n        if (this._pickTrianglePositionsBuf) {\n            this._pickTrianglePositionsBuf.destroy();\n        }\n        if (this._pickTriangleColorsBuf) {\n            this._pickTriangleColorsBuf.destroy();\n        }\n        if (this._pickVertexPositionsBuf) {\n            this._pickVertexPositionsBuf.destroy();\n        }\n        if (this._pickVertexColorsBuf) {\n            this._pickVertexColorsBuf.destroy();\n        }\n        state.destroy();\n        memoryStats$1.meshes--;\n    }\n}\n\nconst memoryStats = stats.memory;\nconst tempAABB$2 = math.AABB3();\n\n/**\n * @desc A {@link Geometry} that keeps its geometry data solely in GPU memory, without retaining it in browser memory.\n *\n * VBOGeometry uses less memory than {@link ReadableGeometry}, which keeps its geometry data in both browser and GPU memory.\n *\n * ## Usage\n *\n * Creating a {@link Mesh} with a VBOGeometry that defines a single triangle, plus a {@link PhongMaterial} with diffuse {@link Texture}:\n *\n * [[Run this example](/examples/index.html#geometry_VBOGeometry)]\n *\n * ````javascript\n * import {Viewer, Mesh, VBOGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *         canvasId: \"myCanvas\"\n *     });\n *\n * new Mesh(viewer.scene, {\n *         geometry: new VBOGeometry(viewer.scene, {\n *             primitive: \"triangles\",\n *             positions: [0.0, 3, 0.0, -3, -3, 0.0, 3, -3, 0.0],\n *             normals: [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0],\n *             uv: [0.0, 0.0, 0.5, 1.0, 1.0, 0.0],\n *             indices: [0, 1, 2]\n *         }),\n *         material: new PhongMaterial(viewer.scene, {\n *             diffuseMap: new Texture(viewer.scene, {\n *                 src: \"textures/diffuse/uvGrid2.jpg\"\n *             }),\n *             backfaces: true\n *         })\n *     });\n * ````\n */\nclass VBOGeometry extends Geometry {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"VBOGeometry\";\n    }\n\n    /**\n     * @private\n     * @returns {Boolean}\n     */\n    get isVBOGeometry() {\n        return true;\n    }\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {String} [cfg.primitive=\"triangles\"]  The primitive type. Accepted values are 'points', 'lines', 'line-loop', 'line-strip', 'triangles', 'triangle-strip' and 'triangle-fan'.\n     * @param {Number[]} [cfg.positions]  Positions array.\n     * @param {Number[]} [cfg.normals]  Vertex normal vectors array.\n     * @param {Number[]} [cfg.uv]  UVs array.\n     * @param {Number[]} [cfg.colors]  Vertex colors.\n     * @param {Number[]} [cfg.indices]  Indices array.\n     * @param {Number} [cfg.edgeThreshold=10]  When autogenerating edges for supporting {@link Drawable#edges}, this indicates the threshold angle (in degrees) between the face normals of adjacent triangles below which the edge is discarded.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({ // Arrays for emphasis effects are got from xeokit.GeometryLite friend methods\n            compressGeometry: true,\n            primitive: null, // WebGL enum\n            primitiveName: null, // String\n            positionsDecodeMatrix: null, // Set when compressGeometry == true\n            uvDecodeMatrix: null, // Set when compressGeometry == true\n            positionsBuf: null,\n            normalsBuf: null,\n            colorsbuf: null,\n            uvBuf: null,\n            indicesBuf: null,\n            hash: \"\"\n        });\n\n        this._numTriangles = 0;\n\n        this._edgeThreshold = cfg.edgeThreshold || 10.0;\n        this._aabb = null;\n        this._obb = math.OBB3();\n\n        const state = this._state;\n        const gl = this.scene.canvas.gl;\n\n        cfg.primitive = cfg.primitive || \"triangles\";\n        switch (cfg.primitive) {\n            case \"points\":\n                state.primitive = gl.POINTS;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"lines\":\n                state.primitive = gl.LINES;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"line-loop\":\n                state.primitive = gl.LINE_LOOP;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"line-strip\":\n                state.primitive = gl.LINE_STRIP;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"triangles\":\n                state.primitive = gl.TRIANGLES;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"triangle-strip\":\n                state.primitive = gl.TRIANGLE_STRIP;\n                state.primitiveName = cfg.primitive;\n                break;\n            case \"triangle-fan\":\n                state.primitive = gl.TRIANGLE_FAN;\n                state.primitiveName = cfg.primitive;\n                break;\n            default:\n                this.error(\"Unsupported value for 'primitive': '\" + cfg.primitive +\n                    \"' - supported values are 'points', 'lines', 'line-loop', 'line-strip', 'triangles', \" +\n                    \"'triangle-strip' and 'triangle-fan'. Defaulting to 'triangles'.\");\n                state.primitive = gl.TRIANGLES;\n                state.primitiveName = cfg.primitive;\n        }\n\n        if (!cfg.positions) {\n            this.error(\"Config expected: positions\");\n            return; // TODO: Recover?\n        }\n\n        if (!cfg.indices) {\n            this.error(\"Config expected: indices\");\n            return; // TODO: Recover?\n        }\n\n        var positions;\n\n        {\n            const positionsDecodeMatrix = cfg.positionsDecodeMatrix;\n\n            if (positionsDecodeMatrix) ; else {\n\n                // Uncompressed positions\n\n                const bounds = geometryCompressionUtils.getPositionsBounds(cfg.positions);\n                const result = geometryCompressionUtils.compressPositions(cfg.positions, bounds.min, bounds.max);\n                positions = result.quantized;\n                state.positionsDecodeMatrix = result.decodeMatrix;\n                state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, positions, positions.length, 3, gl.STATIC_DRAW);\n                memoryStats.positions += state.positionsBuf.numItems;\n                math.positions3ToAABB3(cfg.positions, this._aabb);\n                math.positions3ToAABB3(positions, tempAABB$2, state.positionsDecodeMatrix);\n                math.AABB3ToOBB3(tempAABB$2, this._obb);\n            }\n        }\n\n        if (cfg.colors) {\n            const colors = cfg.colors.constructor === Float32Array ? cfg.colors : new Float32Array(cfg.colors);\n            state.colorsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, colors, colors.length, 4, gl.STATIC_DRAW);\n            memoryStats.colors += state.colorsBuf.numItems;\n        }\n\n        if (cfg.uv) {\n            const bounds = geometryCompressionUtils.getUVBounds(cfg.uv);\n            const result = geometryCompressionUtils.compressUVs(cfg.uv, bounds.min, bounds.max);\n            const uv = result.quantized;\n            state.uvDecodeMatrix = result.decodeMatrix;\n            state.uvBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, uv, uv.length, 2, gl.STATIC_DRAW);\n            memoryStats.uvs += state.uvBuf.numItems;\n        }\n\n        if (cfg.normals) {\n            const normals = geometryCompressionUtils.compressNormals(cfg.normals);\n            let normalized = state.compressGeometry;\n            state.normalsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, normals, normals.length, 3, gl.STATIC_DRAW, normalized);\n            memoryStats.normals += state.normalsBuf.numItems;\n        }\n\n        {\n            const indices = (cfg.indices.constructor === Uint32Array || cfg.indices.constructor === Uint16Array) ? cfg.indices : new Uint32Array(cfg.indices);\n            state.indicesBuf = new ArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, indices, indices.length, 1, gl.STATIC_DRAW);\n            memoryStats.indices += state.indicesBuf.numItems;\n            const edgeIndices = buildEdgeIndices(positions, indices, state.positionsDecodeMatrix, this._edgeThreshold);\n            this._edgeIndicesBuf = new ArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, edgeIndices, edgeIndices.length, 1, gl.STATIC_DRAW);\n\n            if (this._state.primitiveName === \"triangles\") {\n                this._numTriangles = (cfg.indices.length / 3);\n            }\n        }\n\n        this._buildHash();\n\n        memoryStats.meshes++;\n    }\n\n    _buildHash() {\n        const state = this._state;\n        const hash = [\"/g\"];\n        hash.push(\"/\" + state.primitive + \";\");\n        if (state.positionsBuf) {\n            hash.push(\"p\");\n        }\n        if (state.colorsBuf) {\n            hash.push(\"c\");\n        }\n        if (state.normalsBuf || state.autoVertexNormals) {\n            hash.push(\"n\");\n        }\n        if (state.uvBuf) {\n            hash.push(\"u\");\n        }\n        hash.push(\"cp\"); // Always compressed\n        hash.push(\";\");\n        state.hash = hash.join(\"\");\n    }\n\n    _getEdgeIndices() {\n        return this._edgeIndicesBuf;\n    }\n\n    /**\n     * Gets the primitive type.\n     *\n     * Possible types are: 'points', 'lines', 'line-loop', 'line-strip', 'triangles', 'triangle-strip' and 'triangle-fan'.\n     *\n     * @type {String}\n     */\n    get primitive() {\n        return this._state.primitiveName;\n    }\n\n    /**\n     * Gets the local-space axis-aligned 3D boundary (AABB).\n     *\n     * The AABB is represented by a six-element Float64Array containing the min/max extents of the axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n     *\n     * @type {Number[]}\n     */\n    get aabb() {\n        return this._aabb;\n    }\n\n    /**\n     * Gets the local-space oriented 3D boundary (OBB).\n     *\n     * The OBB is represented by a 32-element Float64Array containing the eight vertices of the box, where each vertex is a homogeneous coordinate having [x,y,z,w] elements.\n     *\n     * @type {Number[]}\n     */\n    get obb() {\n        return this._obb;\n    }\n\n    /**\n     * Approximate number of triangles in this VBOGeometry.\n     *\n     * Will be zero if {@link VBOGeometry#primitive} is not 'triangles', 'triangle-strip' or 'triangle-fan'.\n     *\n     * @type {Number}\n     */\n    get numTriangles() {\n        return this._numTriangles;\n    }\n\n    /** @private */\n    _getState() {\n        return this._state;\n    }\n\n    /**\n     * Destroys this component.\n     */\n    destroy() {\n        super.destroy();\n        const state = this._state;\n        if (state.indicesBuf) {\n            state.indicesBuf.destroy();\n        }\n        if (state.positionsBuf) {\n            state.positionsBuf.destroy();\n        }\n        if (state.normalsBuf) {\n            state.normalsBuf.destroy();\n        }\n        if (state.uvBuf) {\n            state.uvBuf.destroy();\n        }\n        if (state.colorsBuf) {\n            state.colorsBuf.destroy();\n        }\n        if (this._edgeIndicesBuf) {\n            this._edgeIndicesBuf.destroy();\n        }\n        state.destroy();\n        memoryStats.meshes--;\n    }\n}\n\n/**\n * @private\n */\nvar K3D = {};\n\nK3D.load = function(path, resp)\n{\n    var request = new XMLHttpRequest();\n    request.open(\"GET\", path, true);\n    request.responseType = \"arraybuffer\";\n    request.onload = function(e){resp(e.target.response);};\n    request.send();\n};\n\nK3D.save = function(buff, path)\n{\n    var dataURI = \"data:application/octet-stream;base64,\" + btoa(K3D.parse._buffToStr(buff));\n    window.location.href = dataURI;\n};\n\nK3D.clone = function(o)\n{\n    return JSON.parse(JSON.stringify(o));\n};\n\n\n\nK3D.bin = {};\n\nK3D.bin.f  = new Float32Array(1);\nK3D.bin.fb = new Uint8Array(K3D.bin.f.buffer);\n\nK3D.bin.rf\t\t= function(buff, off) { var f = K3D.bin.f, fb = K3D.bin.fb; for(var i=0; i<4; i++) fb[i] = buff[off+i]; return f[0]; };\nK3D.bin.rsl\t\t= function(buff, off) { return buff[off] | buff[off+1]<<8; };\nK3D.bin.ril\t\t= function(buff, off) { return buff[off] | buff[off+1]<<8 | buff[off+2]<<16 | buff[off+3]<<24; };\nK3D.bin.rASCII0 = function(buff, off) { var s = \"\"; while(buff[off]!=0) s += String.fromCharCode(buff[off++]); return s; };\n\n\nK3D.bin.wf\t\t= function(buff, off, v) { var f=new Float32Array(buff.buffer, off, 1); f[0]=v; };\nK3D.bin.wsl\t\t= function(buff, off, v) { buff[off]=v; buff[off+1]=v>>8; };\nK3D.bin.wil\t\t= function(buff, off, v) { buff[off]=v; buff[off+1]=v>>8; buff[off+2]=v>>16; buff[off+3]>>24; };\nK3D.parse = {};\n\nK3D.parse._buffToStr = function(buff)\n{\n    var a = new Uint8Array(buff);\n    var s = \"\";\n    for(var i=0; i<a.length; i++) s = s.concat(String.fromCharCode(a[i]));\n    return s;\n};\n\nK3D.parse._strToBuff = function(str)\n{\n    var buf = new ArrayBuffer(str.length);\n    var bufView = new Uint8Array(buf);\n    for (var i=0; i<str.length; i++) bufView[i] = str.charCodeAt(i);\n    return buf;\n};\n\nK3D.parse._readLine = function(a, off)\t// Uint8Array, offset\n{\n    var s = \"\";\n    while(a[off] != 10) s += String.fromCharCode(a[off++]);\n    return s;\n};\nK3D.parse.fromJSON = function(buff)\n{\n    var json = JSON.parse(K3D.parse._buffToStr(buff));\n    return json;\n};\n\nK3D.parse.toJSON = function(object)\n{\n    var str = JSON.stringify(object);\n    return K3D.parse._strToBuff(str);\n};\n\nK3D.parse.fromOBJ = function(buff)\n{\n    var res = {};\n    res.groups = {};\n\n    res.c_verts = [];\n    res.c_uvt\t= [];\n    res.c_norms = [];\n\n    res.i_verts = [];\n    res.i_uvt   = [];\n    res.i_norms = [];\n\n    var cg = {from: 0, to:0};\t// current group\n    var off = 0;\n    var a = new Uint8Array(buff);\n\n    while(off < a.length)\n    {\n        var line = K3D.parse._readLine(a, off);\n        off += line.length + 1;\n        line = line.replace(/ +(?= )/g,'');\n        line = line.replace(/(^\\s+|\\s+$)/g, '');\n        var cds = line.split(\" \");\n        if(cds[0] == \"g\")\n        {\n            cg.to = res.i_verts.length;\n            if(res.groups[cds[1]] == null) res.groups[cds[1]] = {from:res.i_verts.length, to:0};\n            cg = res.groups[cds[1]];\n        }\n        if(cds[0] == \"v\")\n        {\n            var x = parseFloat(cds[1]);\n            var y = parseFloat(cds[2]);\n            var z = parseFloat(cds[3]);\n            res.c_verts.push(x,y,z);\n        }\n        if(cds[0] == \"vt\")\n        {\n            var x = parseFloat(cds[1]);\n            var y = 1-parseFloat(cds[2]);\n            res.c_uvt.push(x,y);\n        }\n        if(cds[0] == \"vn\")\n        {\n            var x = parseFloat(cds[1]);\n            var y = parseFloat(cds[2]);\n            var z = parseFloat(cds[3]);\n            res.c_norms.push(x,y,z);\n        }\n        if(cds[0] == \"f\")\n        {\n            var v0a = cds[1].split(\"/\"), v1a = cds[2].split(\"/\"), v2a = cds[3].split(\"/\");\n            var vi0 = parseInt(v0a[0])-1, vi1 = parseInt(v1a[0])-1, vi2 = parseInt(v2a[0])-1;\n            var ui0 = parseInt(v0a[1])-1, ui1 = parseInt(v1a[1])-1, ui2 = parseInt(v2a[1])-1;\n            var ni0 = parseInt(v0a[2])-1, ni1 = parseInt(v1a[2])-1, ni2 = parseInt(v2a[2])-1;\n\n            var vlen = res.c_verts.length/3, ulen = res.c_uvt.length/2, nlen = res.c_norms.length/3;\n            if(vi0<0) vi0 = vlen + vi0+1; if(vi1<0) vi1 = vlen + vi1+1;\tif(vi2<0) vi2 = vlen + vi2+1;\n            if(ui0<0) ui0 = ulen + ui0+1; if(ui1<0) ui1 = ulen + ui1+1;\tif(ui2<0) ui2 = ulen + ui2+1;\n            if(ni0<0) ni0 = nlen + ni0+1; if(ni1<0) ni1 = nlen + ni1+1;\tif(ni2<0) ni2 = nlen + ni2+1;\n\n            res.i_verts.push(vi0, vi1, vi2);  //cg.i_verts.push(vi0, vi1, vi2)\n            res.i_uvt  .push(ui0, ui1, ui2);  //cg.i_uvt  .push(ui0, ui1, ui2);\n            res.i_norms.push(ni0, ni1, ni2);  //cg.i_norms.push(ni0, ni1, ni2);\n            if(cds.length == 5)\n            {\n                var v3a = cds[4].split(\"/\");\n                var vi3 = parseInt(v3a[0])-1, ui3 = parseInt(v3a[1])-1, ni3 = parseInt(v3a[2])-1;\n                if(vi3<0) vi3 = vlen + vi3+1;\n                if(ui3<0) ui3 = ulen + ui3+1;\n                if(ni3<0) ni3 = nlen + ni3+1;\n                res.i_verts.push(vi0, vi2, vi3);  //cg.i_verts.push(vi0, vi2, vi3);\n                res.i_uvt  .push(ui0, ui2, ui3);  //cg.i_uvt  .push(ui0, ui2, ui3);\n                res.i_norms.push(ni0, ni2, ni3);  //cg.i_norms.push(ni0, ni2, ni3);\n            }\n        }\n    }\n    cg.to = res.i_verts.length;\n\n    return res;\n};\n\n\nK3D.parse.fromMD2 = function(buff)\n{\n    buff = new Uint8Array(buff);\n    var res = {};\n    var head = {};\n    //res.head = head;\n    head.ident\t\t\t= K3D.bin.ril(buff,  0);             /* magic number: \"IDP2\" */\n    head.version\t\t= K3D.bin.ril(buff,  4);             /* version: must be 8 */\n\n    head.skinwidth\t\t= K3D.bin.ril(buff,  8);             /* texture width */\n    head.skinheight\t\t= K3D.bin.ril(buff, 12);             /* texture height */\n\n    head.framesize\t\t= K3D.bin.ril(buff, 16);             /* size in bytes of a frame */\n\n    head.num_skins\t\t= K3D.bin.ril(buff, 20);             /* number of skins */\n    head.num_vertices\t= K3D.bin.ril(buff, 24);             /* number of vertices per frame */\n    head.num_st\t\t\t= K3D.bin.ril(buff, 28);             /* number of texture coordinates */\n    head.num_tris\t\t= K3D.bin.ril(buff, 32);             /* number of triangles */\n    head.num_glcmds\t\t= K3D.bin.ril(buff, 36);             /* number of opengl commands */\n    head.num_frames\t\t= K3D.bin.ril(buff, 40);             /* number of frames */\n\n    head.offset_skins\t= K3D.bin.ril(buff, 44);             /* offset skin data */\n    head.offset_st\t\t= K3D.bin.ril(buff, 48);             /* offset texture coordinate data */\n    head.offset_tris\t= K3D.bin.ril(buff, 52);             /* offset triangle data */\n    head.offset_frames\t= K3D.bin.ril(buff, 56);             /* offset frame data */\n    head.offset_glcmds\t= K3D.bin.ril(buff, 60);             /* offset OpenGL command data */\n    head.offset_end\t\t= K3D.bin.ril(buff, 64);             /* offset end of file */\n\n    var off = head.offset_st;\n    res.c_uvt = [];\n    for(var i=0; i<head.num_st; i++)\n    {\n        var x = K3D.bin.rsl(buff, off  )/head.skinwidth;\n        var y = K3D.bin.rsl(buff, off+2)/head.skinheight;\n        res.c_uvt.push(x,y);  off += 4;\n    }\n\n    var off = head.offset_tris;\n    var vi = [], ti = [];\n    res.i_verts = vi;\n    res.i_uvt = ti;\n    //res.tris = {i_verts : vi, i_uvt : ti};\n    for(var i=0; i<head.num_tris; i++)\n    {\n        vi.push(K3D.bin.rsl(buff, off  ), K3D.bin.rsl(buff, off+2), K3D.bin.rsl(buff, off+4 ));\n        ti.push(K3D.bin.rsl(buff, off+6), K3D.bin.rsl(buff, off+8), K3D.bin.rsl(buff, off+10));\n        off += 12;\n    }\n\n    var off = head.offset_skins;\n    res.skins = [];\n    for(var i=0; i<head.num_skins; i++)\n    {\n        res.skins.push(K3D.bin.rASCII0(buff, off));\n        off += 64;\n    }\n\n    var off = head.offset_frames;\n    res.frames = [];\n    var nms = K3D.parse.fromMD2._normals;\n    for(var i=0; i<head.num_frames; i++)\n    {\n        var fr = {};\n        var sx = K3D.bin.rf(buff, off), sy = K3D.bin.rf(buff, off+4), sz = K3D.bin.rf(buff, off+8);  off += 12;\n        var tx = K3D.bin.rf(buff, off), ty = K3D.bin.rf(buff, off+4), tz = K3D.bin.rf(buff, off+8);  off += 12;\n        fr.name\t\t = K3D.bin.rASCII0(buff, off); off += 16;\n        fr.verts\t = [];\n        fr.norms\t = [];\n\n        for(var j=0; j<head.num_vertices; j++)\n        {\n            fr.verts.push(buff[off]*sx+tx, buff[off+1]*sy+ty, buff[off+2]*sz+tz);\n            fr.norms.push(nms[3*buff[off+3]], nms[3*buff[off+3]+1], nms[3*buff[off+3]+2]);\n            off += 4;\n        }\n        res.frames.push(fr);\n    }\n    return res;\n};\n\n\n\n/*\n static MD2 normals\n */\n\nK3D.parse.fromMD2._normals =\n    [\n        -0.525731,  0.000000,  0.850651,\n        -0.442863,  0.238856,  0.864188,\n        -0.295242,  0.000000,  0.955423,\n        -0.309017,  0.500000,  0.809017,\n        -0.162460,  0.262866,  0.951056,\n        0.000000,  0.000000,  1.000000,\n        0.000000,  0.850651,  0.525731,\n        -0.147621,  0.716567,  0.681718,\n        0.147621,  0.716567,  0.681718,\n        0.000000,  0.525731,  0.850651,\n        0.309017,  0.500000,  0.809017,\n        0.525731,  0.000000,  0.850651,\n        0.295242,  0.000000,  0.955423,\n        0.442863,  0.238856,  0.864188,\n        0.162460,  0.262866,  0.951056,\n        -0.681718,  0.147621,  0.716567,\n        -0.809017,  0.309017,  0.500000,\n        -0.587785,  0.425325,  0.688191,\n        -0.850651,  0.525731,  0.000000,\n        -0.864188,  0.442863,  0.238856,\n        -0.716567,  0.681718,  0.147621,\n        -0.688191,  0.587785,  0.425325,\n        -0.500000,  0.809017,  0.309017,\n        -0.238856,  0.864188,  0.442863,\n        -0.425325,  0.688191,  0.587785,\n        -0.716567,  0.681718, -0.147621,\n        -0.500000,  0.809017, -0.309017,\n        -0.525731,  0.850651,  0.000000,\n        0.000000,  0.850651, -0.525731,\n        -0.238856,  0.864188, -0.442863,\n        0.000000,  0.955423, -0.295242,\n        -0.262866,  0.951056, -0.162460,\n        0.000000,  1.000000,  0.000000,\n        0.000000,  0.955423,  0.295242,\n        -0.262866,  0.951056,  0.162460,\n        0.238856,  0.864188,  0.442863,\n        0.262866,  0.951056,  0.162460,\n        0.500000,  0.809017,  0.309017,\n        0.238856,  0.864188, -0.442863,\n        0.262866,  0.951056, -0.162460,\n        0.500000,  0.809017, -0.309017,\n        0.850651,  0.525731,  0.000000,\n        0.716567,  0.681718,  0.147621,\n        0.716567,  0.681718, -0.147621,\n        0.525731,  0.850651,  0.000000,\n        0.425325,  0.688191,  0.587785,\n        0.864188,  0.442863,  0.238856,\n        0.688191,  0.587785,  0.425325,\n        0.809017,  0.309017,  0.500000,\n        0.681718,  0.147621,  0.716567,\n        0.587785,  0.425325,  0.688191,\n        0.955423,  0.295242,  0.000000,\n        1.000000,  0.000000,  0.000000,\n        0.951056,  0.162460,  0.262866,\n        0.850651, -0.525731,  0.000000,\n        0.955423, -0.295242,  0.000000,\n        0.864188, -0.442863,  0.238856,\n        0.951056, -0.162460,  0.262866,\n        0.809017, -0.309017,  0.500000,\n        0.681718, -0.147621,  0.716567,\n        0.850651,  0.000000,  0.525731,\n        0.864188,  0.442863, -0.238856,\n        0.809017,  0.309017, -0.500000,\n        0.951056,  0.162460, -0.262866,\n        0.525731,  0.000000, -0.850651,\n        0.681718,  0.147621, -0.716567,\n        0.681718, -0.147621, -0.716567,\n        0.850651,  0.000000, -0.525731,\n        0.809017, -0.309017, -0.500000,\n        0.864188, -0.442863, -0.238856,\n        0.951056, -0.162460, -0.262866,\n        0.147621,  0.716567, -0.681718,\n        0.309017,  0.500000, -0.809017,\n        0.425325,  0.688191, -0.587785,\n        0.442863,  0.238856, -0.864188,\n        0.587785,  0.425325, -0.688191,\n        0.688191,  0.587785, -0.425325,\n        -0.147621,  0.716567, -0.681718,\n        -0.309017,  0.500000, -0.809017,\n        0.000000,  0.525731, -0.850651,\n        -0.525731,  0.000000, -0.850651,\n        -0.442863,  0.238856, -0.864188,\n        -0.295242,  0.000000, -0.955423,\n        -0.162460,  0.262866, -0.951056,\n        0.000000,  0.000000, -1.000000,\n        0.295242,  0.000000, -0.955423,\n        0.162460,  0.262866, -0.951056,\n        -0.442863, -0.238856, -0.864188,\n        -0.309017, -0.500000, -0.809017,\n        -0.162460, -0.262866, -0.951056,\n        0.000000, -0.850651, -0.525731,\n        -0.147621, -0.716567, -0.681718,\n        0.147621, -0.716567, -0.681718,\n        0.000000, -0.525731, -0.850651,\n        0.309017, -0.500000, -0.809017,\n        0.442863, -0.238856, -0.864188,\n        0.162460, -0.262866, -0.951056,\n        0.238856, -0.864188, -0.442863,\n        0.500000, -0.809017, -0.309017,\n        0.425325, -0.688191, -0.587785,\n        0.716567, -0.681718, -0.147621,\n        0.688191, -0.587785, -0.425325,\n        0.587785, -0.425325, -0.688191,\n        0.000000, -0.955423, -0.295242,\n        0.000000, -1.000000,  0.000000,\n        0.262866, -0.951056, -0.162460,\n        0.000000, -0.850651,  0.525731,\n        0.000000, -0.955423,  0.295242,\n        0.238856, -0.864188,  0.442863,\n        0.262866, -0.951056,  0.162460,\n        0.500000, -0.809017,  0.309017,\n        0.716567, -0.681718,  0.147621,\n        0.525731, -0.850651,  0.000000,\n        -0.238856, -0.864188, -0.442863,\n        -0.500000, -0.809017, -0.309017,\n        -0.262866, -0.951056, -0.162460,\n        -0.850651, -0.525731,  0.000000,\n        -0.716567, -0.681718, -0.147621,\n        -0.716567, -0.681718,  0.147621,\n        -0.525731, -0.850651,  0.000000,\n        -0.500000, -0.809017,  0.309017,\n        -0.238856, -0.864188,  0.442863,\n        -0.262866, -0.951056,  0.162460,\n        -0.864188, -0.442863,  0.238856,\n        -0.809017, -0.309017,  0.500000,\n        -0.688191, -0.587785,  0.425325,\n        -0.681718, -0.147621,  0.716567,\n        -0.442863, -0.238856,  0.864188,\n        -0.587785, -0.425325,  0.688191,\n        -0.309017, -0.500000,  0.809017,\n        -0.147621, -0.716567,  0.681718,\n        -0.425325, -0.688191,  0.587785,\n        -0.162460, -0.262866,  0.951056,\n        0.442863, -0.238856,  0.864188,\n        0.162460, -0.262866,  0.951056,\n        0.309017, -0.500000,  0.809017,\n        0.147621, -0.716567,  0.681718,\n        0.000000, -0.525731,  0.850651,\n        0.425325, -0.688191,  0.587785,\n        0.587785, -0.425325,  0.688191,\n        0.688191, -0.587785,  0.425325,\n        -0.955423,  0.295242,  0.000000,\n        -0.951056,  0.162460,  0.262866,\n        -1.000000,  0.000000,  0.000000,\n        -0.850651,  0.000000,  0.525731,\n        -0.955423, -0.295242,  0.000000,\n        -0.951056, -0.162460,  0.262866,\n        -0.864188,  0.442863, -0.238856,\n        -0.951056,  0.162460, -0.262866,\n        -0.809017,  0.309017, -0.500000,\n        -0.864188, -0.442863, -0.238856,\n        -0.951056, -0.162460, -0.262866,\n        -0.809017, -0.309017, -0.500000,\n        -0.681718,  0.147621, -0.716567,\n        -0.681718, -0.147621, -0.716567,\n        -0.850651,  0.000000, -0.525731,\n        -0.688191,  0.587785, -0.425325,\n        -0.587785,  0.425325, -0.688191,\n        -0.425325,  0.688191, -0.587785,\n        -0.425325, -0.688191, -0.587785,\n        -0.587785, -0.425325, -0.688191,\n        -0.688191, -0.587785, -0.425325\n    ];\n\nK3D.parse.fromCollada = function(buff)\n{\n    var str = K3D.parse._buffToStr(buff);\n    var xml = new DOMParser().parseFromString(str,\"text/xml\");\n    xml = xml.childNodes[0];\n    var resp = {};\n\n    //console.log(xml);\n\n    var ass = xml.getElementsByTagName(\"asset\"             )[0];\n    var geo = xml.getElementsByTagName(\"library_geometries\")[0];\n    var ima = xml.getElementsByTagName(\"library_images\"    )[0];\n    var mat = xml.getElementsByTagName(\"library_materials\" )[0];\n    var eff = xml.getElementsByTagName(\"library_effects\"   )[0];\n\n    //console.log(xml);\n    if(ass) resp.asset \t\t= K3D.parse.fromCollada._asset        (ass);\n    if(geo) resp.geometries = K3D.parse.fromCollada._libGeometries(geo);\n    if(ima) resp.images     = K3D.parse.fromCollada._libImages    (ima);\n    if(mat) resp.materials  = K3D.parse.fromCollada._libMaterials (mat);\n    if(eff) resp.effects    = K3D.parse.fromCollada._libEffects   (eff);\n    return resp;\n};\n\nK3D.parse.fromCollada._asset = function(xml)\n{\n    //console.log(xml);\n    return {\n        created : xml.getElementsByTagName(\"created\" )[0].textContent,\n        modified: xml.getElementsByTagName(\"modified\")[0].textContent,\n        up_axis : xml.getElementsByTagName(\"up_axis\" )[0].textContent\n    };\n};\n\nK3D.parse.fromCollada._libGeometries = function(xml)\n{\n    xml = xml.getElementsByTagName(\"geometry\");\n    var res = [];\n    for(var i=0; i<xml.length; i++)\n    {\n        var g = xml[i];\n        var o = K3D.parse.fromCollada._getMesh(g.getElementsByTagName(\"mesh\")[0]);\n        res.push(o);\n    }\n    return res;\n};\n\nK3D.parse.fromCollada._getMesh = function(mesh)\n{\n    //console.log(mesh);\n    var res = {};\n    var ss = mesh.getElementsByTagName(\"source\");\n    var sources = res.sources = {};\n    for(var i=0; i<ss.length; i++)\n    {\n        var farr = ss[i].getElementsByTagName(\"float_array\")[0].textContent.split(\" \");\n        var fl = farr.length - (farr[farr.length-1] == \"\" ? 1 : 0);\n        var arr = new Array(fl);\n        for(var j=0; j<fl; j++) arr[j] = parseFloat(farr[j]);\n        sources[ss[i].getAttribute(\"id\")] = arr;\n    }\n\n    res.triangles = [];\n    var tgs = mesh.getElementsByTagName(\"triangles\");\n    if(tgs == null) return res;\n    for(var i=0; i<tgs.length; i++)\n    {\n        var t = {};\n        var tnode = tgs[i];\n        t.material = tnode.getAttribute(\"material\");\n        var inputs = tnode.getElementsByTagName(\"input\");\n        var inds = [];\n        for(var j=0; j<inputs.length; j++)\n        {\n            var inp = inputs[j], arr = [];\n            inds[parseInt(inp.getAttribute(\"offset\"))] = arr;\n            var par = inp.getAttribute(\"semantic\");\n            t[\"s_\"+par] = (par == \"VERTEX\") ?\n                mesh.getElementsByTagName(\"vertices\")[0].getElementsByTagName(\"input\")[0].getAttribute(\"source\").substring(1)\n                : inp.getAttribute(\"source\").substring(1);\n\n            t[\"i_\"+par] = arr;\n            sources[t[\"s_\"+par]];\n        }\n        var indices = tnode.getElementsByTagName(\"p\")[0].textContent.split(\" \");\n        var inum = 3*Math.floor(indices.length/3);\n        for(var j=0; j<inum; j++) inds[j%inputs.length].push(parseInt(indices[j]));\n\n        /*\n         if(t.s_VERTEX  ) t.u_VERTEX   = K3D.edit.unwrap(t.i_VERTEX  , sources[t.s_VERTEX  ], 3);\n         if(t.s_TEXCOORD) t.u_TEXCOORD = K3D.edit.unwrap(t.i_TEXCOORD, sources[t.s_TEXCOORD], 2);\n         if(t.s_NORMAL  ) t.u_NORMAL   = K3D.edit.unwrap(t.i_NORMAL  , sources[t.s_NORMAL  ], 3);\n         //*/\n        //if(t.s_TEXCOORD) for(var j=1; j<t.u_TEXCOORD.length; j+=2) t.u_TEXCOORD[j] = 1 - t.u_TEXCOORD[j];\n\n        /*\n         t.u_INDEX = new Array(t.i_VERTEX.length);\n         for(var j=0; j<t.i_VERTEX.length; j++) t.u_INDEX[j] = j;\n         */\n\n        res.triangles.push(t);\n    }\n    return res;\n};\n\nK3D.parse.fromCollada._libImages = function(xml)\n{\n    xml = xml.getElementsByTagName(\"image\");\n    var res = {};\n    for(var i=0; i<xml.length; i++)\n    {\n        res[xml[i].getAttribute(\"id\")] = xml[i].getElementsByTagName(\"init_from\")[0].textContent;\n    }\n    return res;\n};\n\nK3D.parse.fromCollada._libMaterials = function(xml)\n{\n    xml = xml.getElementsByTagName(\"material\");\n    var res = {};\n    for(var i=0; i<xml.length; i++)\n    {\n        res[xml[i].getAttribute(\"name\")] = xml[i].getElementsByTagName(\"instance_effect\")[0].getAttribute(\"url\").substring(1);\n    }\n    return res;\n};\n\nK3D.parse.fromCollada._libEffects = function(xml)\n{\n    xml = xml.getElementsByTagName(\"effect\");\n    var res = {};\n    for(var i=0; i<xml.length; i++)\n    {\n        var eff = {};\n        var params = xml[i].getElementsByTagName(\"newparam\");\n        for(var j=0; j<params.length; j++)\n        {\n            var srf = params[j].getElementsByTagName(\"surface\")[0];\n            if(srf) eff.surface = srf.getElementsByTagName(\"init_from\")[0].textContent;\n        }\n        res[xml[i].getAttribute(\"id\")] = eff;\n    }\n    return res;\n};\n\n\n\n\n\nK3D.parse.from3DS = function(buff)\n{\n    buff = new Uint8Array(buff);\n    var res = {};\n    if(K3D.bin.rsl(buff, 0) != 0x4d4d) return null;\n    var lim = K3D.bin.ril(buff, 2);\n\n    var off = 6;\n    while(off < lim)\n    {\n        var cid = K3D.bin.rsl(buff, off);\n        var lng = K3D.bin.ril(buff, off+2);\n        //console.log(cid.toString(16), lng);\n\n        if(cid == 0x3d3d) res.edit = K3D.parse.from3DS._edit3ds(buff, off, lng);\n        if(cid == 0xb000) res.keyf = K3D.parse.from3DS._keyf3ds(buff, off, lng);\n\n        off += lng;\n    }\n    return res;\n};\n\nK3D.parse.from3DS._edit3ds = function(buff, coff, clng)\t// buffer, chunk offset, length\n{\n    var res = {};\n    var off = coff+6;\n    while(off < coff+clng)\n    {\n        var cid = K3D.bin.rsl(buff, off);\n        var lng = K3D.bin.ril(buff, off+2);\n        //console.log(\"\\t\", cid.toString(16), lng);\n\n        if(cid == 0x4000) { if(res.objects==null) res.objects = []; res.objects.push(K3D.parse.from3DS._edit_object(buff, off, lng)); }\n        //if(cid == 0xb000) res.KEYF3DS = K3D.parse.from3DS._keyf3ds(buff, off, lng);\n\n        off += lng;\n    }\n    return res;\n};\n\nK3D.parse.from3DS._keyf3ds = function(buff, coff, clng)\n{\n    var res = {};\n    var off = coff+6;\n    while(off < coff+clng)\n    {\n        var cid = K3D.bin.rsl(buff, off);\n        var lng = K3D.bin.ril(buff, off+2);\n        //console.log(\"\\t\\t\", cid.toString(16), lng);\n\n        //if(cid == 0x4000) { res.objects.push(K3D.parse.from3DS._edit_object(buff, off, lng)); }\n        if(cid == 0xb002) { if(res.desc==null) res.desc = []; res.desc.push(K3D.parse.from3DS._keyf_objdes(buff, off, lng)); }\n\n        off += lng;\n    }\n    return res;\n};\n\nK3D.parse.from3DS._keyf_objdes = function(buff, coff, clng)\n{\n    var res = {};\n    var off = coff+6;\n    while(off < coff+clng)\n    {\n        var cid = K3D.bin.rsl(buff, off);\n        var lng = K3D.bin.ril(buff, off+2);\n        //console.log(\"\\t\\t\\t\", cid.toString(16), lng);\n\n        if(cid == 0xb010) res.hierarchy = K3D.parse.from3DS._keyf_objhierarch(buff, off, lng);\n        if(cid == 0xb011) res.dummy_name = K3D.bin.rASCII0(buff, off+6);\n        off += lng;\n    }\n    return res;\n};\n\nK3D.parse.from3DS._keyf_objhierarch = function(buff, coff, clng)\n{\n    var res = {};\n    var off = coff+6;\n    res.name = K3D.bin.rASCII0(buff, off);  off += res.name.length+1;\n    res.hierarchy = K3D.bin.rsl(buff, off+4);\n    return res;\n};\n\nK3D.parse.from3DS._edit_object = function(buff, coff, clng)\t// buffer, chunk offset, length\n{\n    var res = {};\n    var off = coff+6;\n    res.name = K3D.bin.rASCII0(buff, off);  off += res.name.length+1;\n    //console.log(res.name);\n    while(off < coff+clng)\n    {\n        var cid = K3D.bin.rsl(buff, off);\n        var lng = K3D.bin.ril(buff, off+2);\n        //console.log(\"\\t\\t\", cid.toString(16), lng);\n\n        if(cid == 0x4100) res.mesh = K3D.parse.from3DS._obj_trimesh(buff, off, lng);\n        //if(cid == 0xb000) res.KEYF3DS = K3D.parse.from3DS._keyf3ds(buff, off, lng);\n\n        off += lng;\n    }\n    return res;\n};\n\nK3D.parse.from3DS._obj_trimesh = function(buff, coff, clng)\t// buffer, chunk offset, length\n{\n    var res = {};\n    var off = coff+6;\n\n    while(off < coff+clng)\n    {\n        var cid = K3D.bin.rsl(buff, off);\n        var lng = K3D.bin.ril(buff, off+2);\n        //console.log(\"\\t\\t\\t\", cid.toString(16), lng);\n\n        if(cid == 0x4110) res.vertices      = K3D.parse.from3DS._tri_vertexl     (buff, off, lng);\n        if(cid == 0x4120) res.indices       = K3D.parse.from3DS._tri_facel1      (buff, off, lng);\n        if(cid == 0x4140) res.uvt\t\t\t= K3D.parse.from3DS._tri_mappingcoors(buff, off, lng);\n        if(cid == 0x4160) res.local\t\t    = K3D.parse.from3DS._tri_local       (buff, off, lng);\n        off += lng;\n    }\n    return res;\n};\n\nK3D.parse.from3DS._tri_vertexl = function(buff, coff, clng)\t// buffer, chunk offset, length\n{\n    var res = [];\n    var off = coff+6;\n    var n = K3D.bin.rsl(buff, off);  off += 2;\n    for(var i=0; i<n; i++)\n    {\n        res.push(K3D.bin.rf(buff, off  ));\tres.push(K3D.bin.rf(buff, off+4));\tres.push(K3D.bin.rf(buff, off+8));\n        off += 12;\n    }\n    return res;\n};\n\nK3D.parse.from3DS._tri_facel1 = function(buff, coff, clng)\t// buffer, chunk offset, length\n{\n    var res = [];\n    var off = coff+6;\n    var n = K3D.bin.rsl(buff, off);  off += 2;\n    for(var i=0; i<n; i++)\n    {\n        res.push(K3D.bin.rsl(buff, off  ));\n        res.push(K3D.bin.rsl(buff, off+2));\n        res.push(K3D.bin.rsl(buff, off+4));\n        off += 8;\n    }\n    return res;\n};\n\nK3D.parse.from3DS._tri_mappingcoors = function(buff, coff, clng)\t// buffer, chunk offset, length\n{\n    var res = [];\n    var off = coff+6;\n    var n = K3D.bin.rsl(buff, off);  off += 2;\n    for(var i=0; i<n; i++)\n    {\n        res.push(  K3D.bin.rf(buff, off  ));\n        res.push(1-K3D.bin.rf(buff, off+4));\n        off += 8;\n    }\n    return res;\n};\n\nK3D.parse.from3DS._tri_local = function(buff, coff, clng)\t// buffer, chunk offset, length\n{\n    var res = {};\n    var off = coff+6;\n    res.X = [K3D.bin.rf(buff, off), K3D.bin.rf(buff, off+4), K3D.bin.rf(buff, off+8)];  off += 12;\n    res.Y = [K3D.bin.rf(buff, off), K3D.bin.rf(buff, off+4), K3D.bin.rf(buff, off+8)];  off += 12;\n    res.Z = [K3D.bin.rf(buff, off), K3D.bin.rf(buff, off+4), K3D.bin.rf(buff, off+8)];  off += 12;\n    res.C = [K3D.bin.rf(buff, off), K3D.bin.rf(buff, off+4), K3D.bin.rf(buff, off+8)];  off += 12;\n    return res;\n};\n\nK3D.parse.fromBIV = function(buff)\n{\n    buff = new Uint8Array(buff);\n    var res = {};\n\n    var head = {};\n\n    head.id\t\t= K3D.bin.ril(buff,  0);\n\n    head.verS\t= K3D.bin.ril(buff,  4);\n    head.texS\t= K3D.bin.ril(buff,  8);\n    head.indS\t= K3D.bin.ril(buff, 12);\n\n    head.verO\t= K3D.bin.ril(buff, 16);\n    head.verL\t= K3D.bin.ril(buff, 20);\n    head.texO\t= K3D.bin.ril(buff, 24);\n    head.texL\t= K3D.bin.ril(buff, 28);\n    head.indO\t= K3D.bin.ril(buff, 32);\n    head.indL\t= K3D.bin.ril(buff, 36);\n\n    if(head.verO != 0) res.vertices = K3D.parse.fromBIV._readFloats(buff, head.verO, head.verL);\n    if(head.texO != 0) res.uvt      = K3D.parse.fromBIV._readFloats(buff, head.texO, head.texL);\n    if(head.indO != 0) res.indices  = K3D.parse.fromBIV._readInts  (buff, head.indO, head.indL, head.indS);\n\n    return res;\n};\n\nK3D.parse.toBIV = function(obj)\n{\n    var maxi = 0;\n    for(var i=0; i<obj.indices.length; i++)\tmaxi = Math.max(maxi, obj.indices[i]);\n\n    var indS = 32;\n    if(maxi<=0xffff) indS = 16;\n\n    var len = 40;\n    if(obj.vertices) len+=obj.vertices.length*4;\n    if(obj.uvt     ) len+=obj.uvt     .length*4;\n    if(obj.indices ) len+=obj.indices .length*indS/8;\n\n\n    var buff = new Uint8Array(len);\n\n    K3D.bin.wil(buff,  0, 0x6976616e);\n\n    K3D.bin.wil(buff,  4, 32);\n    K3D.bin.wil(buff,  8, 32);\n    K3D.bin.wil(buff, 12, indS);\n\n    var off = 40;\n    if(obj.vertices)\n    {\n        K3D.bin.wil(buff, 16, off);\n        K3D.bin.wil(buff, 20, 4*obj.vertices.length);\n        K3D.parse.fromBIV._writeFloats(buff, off, obj.vertices);\n        off += 4*obj.vertices.length;\n    }\n    if(obj.uvt)\n    {\n        K3D.bin.wil(buff, 24, off);\n        K3D.bin.wil(buff, 28, 4*obj.uvt.length);\n        K3D.parse.fromBIV._writeFloats(buff, off, obj.uvt);\n        off += 4*obj.uvt.length;\n    }\n    if(obj.indices)\n    {\n        K3D.bin.wil(buff, 32, off);\n        K3D.bin.wil(buff, 36, 4*obj.indices.length);\n        K3D.parse.fromBIV._writeInts  (buff, off, obj.indices, indS);\n    }\n    return buff.buffer;\n};\n\nK3D.parse.fromBIV._readFloats = function(buff, off, len)\n{\n    var arr = [];\n    for(var i=0; i<len/4; i++) arr.push( K3D.bin.rf(buff, off+4*i));\n    return arr;\n};\n\nK3D.parse.fromBIV._writeFloats = function(buff, off, arr)\n{\n    for(var i=0; i<arr.length; i++) K3D.bin.wf(buff, off+4*i, arr[i]);\n};\n\nK3D.parse.fromBIV._readInts   = function(buff, off, len, cs)\n{\n    var arr = [];\n    for(var i=0; i<len/4; i++)\n    {\n        if(cs==16) arr.push( K3D.bin.rsl(buff, off+2*i));\n        if(cs==32) arr.push( K3D.bin.ril(buff, off+4*i));\n    }\n    return arr;\n};\n\nK3D.parse.fromBIV._writeInts   = function(buff, off, arr, cs)\n{\n    for(var i=0; i<arr.length; i++)\n    {\n        if(cs==16) K3D.bin.wsl(buff, off+2*i, arr[i]);\n        if(cs==32) K3D.bin.wil(buff, off+4*i, arr[i]);\n    }\n};\nK3D.gen = {};\n\nK3D.gen.Plane = function(sw, sh, tsw, tsh)\n{\n    if(!tsw) tsw = 1;\n    if(!tsh) tsh = 1;\n    var r = {verts:[], inds:[], uvt:[]};\n    var ssw = sw+1, ssh = sh+1;\n    for(var i=0; i<ssh; i++)\n    {\n        for(var j=0; j<ssw; j++)\n        {\n            var x = -1 + j*(2/sw);\n            var y = -1 + i*(2/sh);\n            r.verts.push(x, y, 0);\n            r.uvt.push(tsw*j/sw, tsh*i/sh);\n            if(i<sh && j<sw)\n                r.inds.push(i*ssw+j, i*ssw+j+1, (i+1)*ssw+j,   i*ssw+j+1, (i+1)*ssw+j, (i+1)*ssw+j+1);\n        }\n    }\n    return r;\n};\nK3D.gen.Cube = function()\n{\n    var r = {\n        verts:[\t-1, 1,-1,   1, 1,-1,  -1,-1,-1,   1,-1,-1, // front\n            -1, 1, 1,   1, 1, 1,  -1,-1, 1,   1,-1, 1, // back\n\n            -1, 1, 1,  -1, 1,-1,  -1,-1, 1,  -1,-1,-1, // left\n            1, 1, 1,   1, 1,-1,   1,-1, 1,   1,-1,-1, // right\n\n            -1, 1,-1,   1, 1,-1,  -1, 1, 1,   1, 1, 1, // top\n            -1,-1,-1,   1,-1,-1,  -1,-1, 1,   1,-1, 1  // bottom\n        ],\n        inds:[\t0,1,2, 1,2,3, 4,5,6, 5,6,7,\n            8,9,10, 9,10,11, 12,13,14, 13,14,15,\n            16,17,18, 17,18,19, 20,21,22, 21,22,23\n        ],\n        uvt:[\n            1/4,1/4,  2/4,1/4,  1/4,2/4,  2/4,2/4, // front\n            4/4,1/4,  3/4,1/4,  4/4,2/4,  3/4,2/4, // back\n\n            0/4,1/4,  1/4,1/4,  0/4,2/4,  1/4,2/4, // left\n            3/4,1/4,  2/4,1/4,  3/4,2/4,  2/4,2/4, // right\n\n            1/4,1/4,  2/4,1/4,  1/4,0/4,  2/4,0/4, // top\n            1/4,2/4,  2/4,2/4,  1/4,3/4,  2/4,3/4, // bottom\n        ]\n    };\n    return r;\n};\n\nK3D.gen.Sphere = function(sx, sy){\n    var r = {verts:[], inds:[], uvt:[]};\n    var nx = sx+1, ny = sy+1;\n    for(var i=0; i<ny; i++)\t// rows\n    {\n        for(var j=0; j<nx; j++) // cols\n        {\n            var lat = -Math.PI/2 + i*Math.PI/sy;\n            var lon =  j*2*Math.PI/sx;\n            var x = Math.cos(lat) * Math.cos(lon);\n            var y = Math.sin(lat);\n            var z = Math.cos(lat) * Math.sin(lon);\n\n            r.verts.push(x,y,z);\n            r.uvt.push(j/sx, i/sy);\n            if(i<sy && j<sx)          // 6 indices for 2 triangles\n                r.inds.push(nx*i+j, nx*i+j+1, nx*(i+1)+j, nx*i+j+1, nx*(i+1)+j, nx*(i+1)+j+1);\n        }\n    }\n    return r;\n};\n\nK3D.mat = {};\n\nK3D.mat.scale = function(x,y,z){\n    return [\n        x,0,0,0,\n        0,y,0,0,\n        0,0,z,0,\n        0,0,0,1\n    ];\n};\n\nK3D.mat.translate = function(x,y,z){\n    return [\n        1,0,0,0,\n        0,1,0,0,\n        0,0,1,0,\n        x,y,z,1\n    ];\n};\n\nK3D.mat.rotateDeg = function(x,y,z){\n    var r = Math.PI/180;\n    return K3D.mat.rotate(x*r, y*r, z*r);\n};\n\nK3D.mat.rotate = function(x,y,z){\n    var m = [\n        1,0,0,0,\n        0,1,0,0,\n        0,0,1,0,\n        0,0,0,1\n    ];\n    var a =  x;\t// alpha\n    var b =  y;\t// beta\n    var g =  z;\t// gama\n\n    var ca = Math.cos(a), cb = Math.cos(b), cg = Math.cos(g);\n    var sa = Math.sin(a), sb = Math.sin(b), sg = Math.sin(g);\n\n    m[0] = cb*cg;\t\t\t\tm[1] = -cb*sg;\t\t\t\t\tm[2 ] = sb;\n    m[4] = (ca*sg+sa*sb*cg);\tm[5] = (ca*cg-sa*sb*sg);\t\tm[6 ] = -sa*cb;\n    m[8] = (sa*sg-ca*sb*cg);\tm[9] = (sa*cg+ca*sb*sg);\t\tm[10] = ca*cb;\n\n    return m;\n};\n\n\nK3D.edit = {};\n\nK3D.edit.interpolate = function(a, b, d, t){\n    for(var i=0; i<a.length; i++) d[i] = a[i] + t*(b[i] - a[i]);\n};\n\n\nK3D.edit.transform = function(a, m){\n    for(var i=0; i<a.length; i+=3)    {\n        var x = a[i], y = a[i+1], z = a[i+2];\n        a[i+0] = m[0]*x + m[4]*y + m[8 ]*z + m[12];\n        a[i+1] = m[1]*x + m[5]*y + m[9 ]*z + m[13];\n        a[i+2] = m[2]*x + m[6]*y + m[10]*z + m[14];\n    }\n};\n\n// starting indices, starting coordinates, coordinates per index\n\nK3D.edit.unwrap = function(ind, crd, cpi){\n    var ncrd = new Array(Math.floor(ind.length/3)*cpi);\n    for(var i=0; i<ind.length; i++)\n    {\n        for(var j=0; j<cpi; j++)\n        {\n            ncrd[i*cpi+j] = crd[ind[i]*cpi+j];\n        }\n    }\n    return ncrd;\n};\n\n// current indices, new indices, current array, coordinates per vertex\n\nK3D.edit.remap = function(ind, nind, arr, cpi){\n    var ncrd = new Array(arr.length);\n    for(var i=0; i<ind.length; i++)\n    {\n        for(var j=0; j<cpi; j++)\n        {\n            ncrd[nind[i]*cpi+j] = arr[ind[i]*cpi+j];\n        }\n    }\n    return ncrd;\n};\n\nK3D.utils = {};\n\nK3D.utils.getAABB = function(vts)\n{\n    var minx, miny, minz, maxx, maxy, maxz;\n    minx = miny = minz = 999999999;\n    maxx = maxy = maxz = -minx;\n\n    for(var i=0; i<vts.length; i+=3)\n    {\n        var vx = vts[i+0];\n        var vy = vts[i+1];\n        var vz = vts[i+2];\n        if(vx<minx) minx = vx;  if(vx>maxx) maxx = vx;\n        if(vy<miny) miny = vy;  if(vy>maxy) maxy = vy;\n        if(vz<minz) minz = vz;  if(vy>maxz) maxz = vz;\n    }\n    return {min:{x:minx, y:miny, z:minz}, max:{x:maxx, y:maxy, z:maxz}};\n};\n\n/**\n * @desc Loads {@link Geometry} from 3DS.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with {@link PhongMaterial}, {@link Texture} and a {@link ReadableGeometry} loaded from 3DS.\n *\n * ````javascript\n * import {Viewer, Mesh, load3DSGeometry, ReadableGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [40.04, 23.46, 79.06];\n * viewer.scene.camera.look = [-6.48, 13.92, -0.56];\n * viewer.scene.camera.up = [-0.04, 0.98, -0.08];\n *\n * load3DSGeometry(viewer.scene, {\n *      src: \"models/3ds/lexus.3ds\",\n *      compressGeometry: false\n *\n *  }).then(function (geometryCfg) {\n *\n *      // Success\n *\n *      new Mesh(viewer.scene, {\n *\n *          geometry: new ReadableGeometry(viewer.scene, geometryCfg),\n *\n *          material: new PhongMaterial(viewer.scene, {\n *\n *              emissive: [1, 1, 1],\n *              emissiveMap: new Texture({  // .3DS has no normals so relies on emissive illumination\n *                  src: \"models/3ds/lexus.jpg\"\n *              })\n *          }),\n *\n *          rotation: [-90, 0, 0] // +Z is up for this particular 3DS\n *      });\n *  }, function () {\n *      // Error\n *  });\n * ````\n *\n * @function load3DSGeometry\n * @param {Scene} scene Scene we're loading the geometry for.\n * @param {*} cfg Configs, also added to the result object.\n * @param {String} [cfg.src]  Path to 3DS file.\n * @returns {Object} Configuration to pass into a {@link Geometry} constructor, containing geometry arrays loaded from the OBJ file.\n */\nfunction load3DSGeometry(scene, cfg = {}) {\n\n    return new Promise(function (resolve, reject) {\n\n        if (!cfg.src) {\n            console.error(\"load3DSGeometry: Parameter expected: src\");\n            reject();\n        }\n\n        var spinner = scene.canvas.spinner;\n        spinner.processes++;\n\n        utils.loadArraybuffer(cfg.src, function (data) {\n\n                if (!data.byteLength) {\n                    console.error(\"load3DSGeometry: no data loaded\");\n                    spinner.processes--;\n                    reject();\n                }\n\n                var m = K3D.parse.from3DS(data);\t// done !\n\n                var mesh = m.edit.objects[0].mesh;\n                var positions = mesh.vertices;\n                var uv = mesh.uvt;\n                var indices = mesh.indices;\n\n                spinner.processes--;\n\n                resolve(utils.apply(cfg, {\n                    primitive: \"triangles\",\n                    positions: positions,\n                    normals: null,\n                    uv: uv,\n                    indices: indices\n                }));\n            },\n\n            function (msg) {\n                console.error(\"load3DSGeometry: \" + msg);\n                spinner.processes--;\n                reject();\n            });\n    });\n}\n\n/**\n * @desc Loads {@link Geometry} from OBJ.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with {@link MetallicMaterial} and {@link ReadableGeometry} loaded from OBJ.\n *\n * ````javascript\n * import {Viewer, Mesh, loadOBJGeometry, ReadableGeometry,\n *      MetallicMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [0.57, 1.37, 1.14];\n * viewer.scene.camera.look = [0.04, 0.58, 0.00];\n * viewer.scene.camera.up = [-0.22, 0.84, -0.48];\n *\n * loadOBJGeometry(viewer.scene, {\n *\n *      src: \"models/obj/fireHydrant/FireHydrantMesh.obj\",\n *      compressGeometry: false\n *\n *  }).then(function (geometryCfg) {\n *\n *      // Success\n *\n *      new Mesh(viewer.scene, {\n *\n *          geometry: new ReadableGeometry(viewer.scene, geometryCfg),\n *\n *          material: new MetallicMaterial(viewer.scene, {\n *\n *              baseColor: [1, 1, 1],\n *              metallic: 1.0,\n *              roughness: 1.0,\n * \n *              baseColorMap: new Texture(viewer.scene, {\n *                  src: \"models/obj/fireHydrant/fire_hydrant_Base_Color.png\",\n *                  encoding: \"sRGB\"\n *              }),\n *              normalMap: new Texture(viewer.scene, {\n *                  src: \"models/obj/fireHydrant/fire_hydrant_Normal_OpenGL.png\"\n *              }),\n *              roughnessMap: new Texture(viewer.scene, {\n *                  src: \"models/obj/fireHydrant/fire_hydrant_Roughness.png\"\n *              }),\n *              metallicMap: new Texture(viewer.scene, {\n *                  src: \"models/obj/fireHydrant/fire_hydrant_Metallic.png\"\n *              }),\n *              occlusionMap: new Texture(viewer.scene, {\n *                  src: \"models/obj/fireHydrant/fire_hydrant_Mixed_AO.png\"\n *              }),\n * \n *              specularF0: 0.7\n *          })\n *      });\n *  }, function () {\n *      // Error\n *  });\n * ````\n *\n * @function loadOBJGeometry\n * @param {Scene} scene Scene we're loading the geometry for.\n * @param {*} [cfg] Configs, also added to the result object.\n * @param {String} [cfg.src]  Path to OBJ file.\n * @returns {Object} Configuration to pass into a {@link Geometry} constructor, containing geometry arrays loaded from the OBJ file.\n */\nfunction loadOBJGeometry(scene, cfg = {}) {\n\n    return new Promise(function (resolve, reject) {\n\n        if (!cfg.src) {\n            console.error(\"loadOBJGeometry: Parameter expected: src\");\n            reject();\n        }\n\n        var spinner = scene.canvas.spinner;\n        spinner.processes++;\n\n        utils.loadArraybuffer(cfg.src, function (data) {\n\n                if (!data.byteLength) {\n                    console.error(\"loadOBJGeometry: no data loaded\");\n                    spinner.processes--;\n                    reject();\n                }\n\n                var m = K3D.parse.fromOBJ(data);\t// done !\n\n                // unwrap simply duplicates some values, so they can be indexed with indices [0,1,2,3 ... ]\n                // In some rendering engines, you can have only one index value for vertices, UVs, normals ...,\n                // so \"unwrapping\" is a simple solution.\n\n                var positions = K3D.edit.unwrap(m.i_verts, m.c_verts, 3);\n                var normals = K3D.edit.unwrap(m.i_norms, m.c_norms, 3);\n                var uv = K3D.edit.unwrap(m.i_uvt, m.c_uvt, 2);\n                var indices = new Int32Array(m.i_verts.length);\n\n                for (var i = 0; i < m.i_verts.length; i++) {\n                    indices[i] = i;\n                }\n\n                spinner.processes--;\n\n                resolve(utils.apply(cfg, {\n                    primitive: \"triangles\",\n                    positions: positions,\n                    normals: normals.length > 0 ? normals : null,\n                    autoNormals: normals.length === 0,\n                    uv: uv,\n                    indices: indices\n                }));\n            },\n\n            function (msg) {\n                console.error(\"loadOBJGeometry: \" + msg);\n                spinner.processes--;\n                reject();\n            });\n    });\n}\n\n/**\n * @desc Creates box-shaped {@link Geometry}.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with a box-shaped {@link ReadableGeometry}.\n *\n * [[Run this example](/examples/index.html#geometry_builders_buildBoxGeometry)]\n *\n * ````javascript\n * import {Viewer, Mesh, buildBoxGeometry, ReadableGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *         canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildBoxGeometry({\n *         center: [0,0,0],\n *         xSize: 1,  // Half-size on each axis\n *         ySize: 1,\n *         zSize: 1\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *         diffuseMap: new Texture(viewer.scene, {\n *             src: \"textures/diffuse/uvGrid2.jpg\"\n *         })\n *      })\n * });\n * ````\n *\n * @function buildBoxGeometry\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number[]} [cfg.center]  3D point indicating the center position.\n * @param {Number} [cfg.xSize=1.0]  Half-size on the X-axis.\n * @param {Number} [cfg.ySize=1.0]  Half-size on the Y-axis.\n * @param {Number} [cfg.zSize=1.0]  Half-size on the Z-axis.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildBoxGeometry(cfg = {}) {\n\n    let xSize = cfg.xSize || 1;\n    if (xSize < 0) {\n        console.error(\"negative xSize not allowed - will invert\");\n        xSize *= -1;\n    }\n\n    let ySize = cfg.ySize || 1;\n    if (ySize < 0) {\n        console.error(\"negative ySize not allowed - will invert\");\n        ySize *= -1;\n    }\n\n    let zSize = cfg.zSize || 1;\n    if (zSize < 0) {\n        console.error(\"negative zSize not allowed - will invert\");\n        zSize *= -1;\n    }\n\n    const center = cfg.center;\n    const centerX = center ? center[0] : 0;\n    const centerY = center ? center[1] : 0;\n    const centerZ = center ? center[2] : 0;\n\n    const xmin = -xSize + centerX;\n    const ymin = -ySize + centerY;\n    const zmin = -zSize + centerZ;\n    const xmax = xSize + centerX;\n    const ymax = ySize + centerY;\n    const zmax = zSize + centerZ;\n\n    return utils.apply(cfg, {\n\n        // The vertices - eight for our cube, each\n        // one spanning three array elements for X,Y and Z\n        positions: [\n\n            // v0-v1-v2-v3 front\n            xmax, ymax, zmax,\n            xmin, ymax, zmax,\n            xmin, ymin, zmax,\n            xmax, ymin, zmax,\n\n            // v0-v3-v4-v1 right\n            xmax, ymax, zmax,\n            xmax, ymin, zmax,\n            xmax, ymin, zmin,\n            xmax, ymax, zmin,\n\n            // v0-v1-v6-v1 top\n            xmax, ymax, zmax,\n            xmax, ymax, zmin,\n            xmin, ymax, zmin,\n            xmin, ymax, zmax,\n\n            // v1-v6-v7-v2 left\n            xmin, ymax, zmax,\n            xmin, ymax, zmin,\n            xmin, ymin, zmin,\n            xmin, ymin, zmax,\n\n            // v7-v4-v3-v2 bottom\n            xmin, ymin, zmin,\n            xmax, ymin, zmin,\n            xmax, ymin, zmax,\n            xmin, ymin, zmax,\n\n            // v4-v7-v6-v1 back\n            xmax, ymin, zmin,\n            xmin, ymin, zmin,\n            xmin, ymax, zmin,\n            xmax, ymax, zmin\n        ],\n\n        // Normal vectors, one for each vertex\n        normals: [\n\n            // v0-v1-v2-v3 front\n            0, 0, 1,\n            0, 0, 1,\n            0, 0, 1,\n            0, 0, 1,\n\n            // v0-v3-v4-v5 right\n            1, 0, 0,\n            1, 0, 0,\n            1, 0, 0,\n            1, 0, 0,\n\n            // v0-v5-v6-v1 top\n            0, 1, 0,\n            0, 1, 0,\n            0, 1, 0,\n            0, 1, 0,\n\n            // v1-v6-v7-v2 left\n            -1, 0, 0,\n            -1, 0, 0,\n            -1, 0, 0,\n            -1, 0, 0,\n\n            // v7-v4-v3-v2 bottom\n            0, -1, 0,\n            0, -1, 0,\n            0, -1, 0,\n            0, -1, 0,\n\n            // v4-v7-v6-v5 back\n            0, 0, -1,\n            0, 0, -1,\n            0, 0, -1,\n            0, 0, -1\n        ],\n\n        // UV coords\n        uv: [\n\n            // v0-v1-v2-v3 front\n            1, 0,\n            0, 0,\n            0, 1,\n            1, 1,\n\n            // v0-v3-v4-v1 right\n            0, 0,\n            0, 1,\n            1, 1,\n            1, 0,\n\n            // v0-v1-v6-v1 top\n            1, 1,\n            1, 0,\n            0, 0,\n            0, 1,\n\n            // v1-v6-v7-v2 left\n            1, 0,\n            0, 0,\n            0, 1,\n            1, 1,\n\n            // v7-v4-v3-v2 bottom\n            0, 1,\n            1, 1,\n            1, 0,\n            0, 0,\n\n            // v4-v7-v6-v1 back\n            0, 1,\n            1, 1,\n            1, 0,\n            0, 0\n        ],\n\n        // Indices - these organise the\n        // positions and uv texture coordinates\n        // into geometric primitives in accordance\n        // with the \"primitive\" parameter,\n        // in this case a set of three indices\n        // for each triangle.\n        //\n        // Note that each triangle is specified\n        // in counter-clockwise winding order.\n        //\n        // You can specify them in clockwise\n        // order if you configure the Modes\n        // node's frontFace flag as \"cw\", instead of\n        // the default \"ccw\".\n        indices: [\n            0, 1, 2,\n            0, 2, 3,\n            // front\n            4, 5, 6,\n            4, 6, 7,\n            // right\n            8, 9, 10,\n            8, 10, 11,\n            // top\n            12, 13, 14,\n            12, 14, 15,\n            // left\n            16, 17, 18,\n            16, 18, 19,\n            // bottom\n            20, 21, 22,\n            20, 22, 23\n        ]\n    });\n}\n\n/**\n * @desc Creates a box-shaped lines {@link Geometry}.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with a box-shaped {@link ReadableGeometry} that has lines primitives.\n *\n * [[Run this example](/examples/index.html#geometry_builders_buildBoxLinesGeometry)]\n *\n * ````javascript\n * import {Viewer, Mesh, buildBoxLinesGeometry, ReadableGeometry, PhongMaterial} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *         canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildBoxLinesGeometry({\n *         center: [0,0,0],\n *         xSize: 1,  // Half-size on each axis\n *         ySize: 1,\n *         zSize: 1\n *      })),\n *      material: new PhongMaterial(viewer.scene, {\n *         emissive: [0,1,0]\n *      })\n * });\n * ````\n *\n * @function buildBoxLinesGeometry\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number[]} [cfg.center]  3D point indicating the center position.\n * @param {Number} [cfg.xSize=1.0]  Half-size on the X-axis.\n * @param {Number} [cfg.ySize=1.0]  Half-size on the Y-axis.\n * @param {Number} [cfg.zSize=1.0]  Half-size on the Z-axis.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildBoxLinesGeometry(cfg = {}) {\n\n    let xSize = cfg.xSize || 1;\n    if (xSize < 0) {\n        console.error(\"negative xSize not allowed - will invert\");\n        xSize *= -1;\n    }\n\n    let ySize = cfg.ySize || 1;\n    if (ySize < 0) {\n        console.error(\"negative ySize not allowed - will invert\");\n        ySize *= -1;\n    }\n\n    let zSize = cfg.zSize || 1;\n    if (zSize < 0) {\n        console.error(\"negative zSize not allowed - will invert\");\n        zSize *= -1;\n    }\n\n    const center = cfg.center;\n    const centerX = center ? center[0] : 0;\n    const centerY = center ? center[1] : 0;\n    const centerZ = center ? center[2] : 0;\n\n    const xmin = -xSize + centerX;\n    const ymin = -ySize + centerY;\n    const zmin = -zSize + centerZ;\n    const xmax = xSize + centerX;\n    const ymax = ySize + centerY;\n    const zmax = zSize + centerZ;\n\n    return utils.apply(cfg, {\n        primitive: \"lines\",\n        positions: [\n            xmin, ymin, zmin,\n            xmin, ymin, zmax,\n            xmin, ymax, zmin,\n            xmin, ymax, zmax,\n            xmax, ymin, zmin,\n            xmax, ymin, zmax,\n            xmax, ymax, zmin,\n            xmax, ymax, zmax\n        ],\n        indices: [\n            0, 1,\n            1, 3,\n            3, 2,\n            2, 0,\n            4, 5,\n            5, 7,\n            7, 6,\n            6, 4,\n            0, 4,\n            1, 5,\n            2, 6,\n            3, 7\n        ]\n    });\n}\n\n/**\n * @desc Creates a box-shaped lines {@link Geometry} from AABB.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with a box-shaped {@link ReadableGeometry} that has lines primitives.\n * This box will be created from AABB of a model.\n *\n * [[Run this example](/examples/index.html#geometry_builders_buildBoxLinesGeometryFromAABB)]\n *\n * ````javascript\n *     import {Viewer, Mesh, Node, buildBoxGeometry, buildBoxLinesGeometryFromAABB, ReadableGeometry, PhongMaterial} from \"../../dist/xeokit-sdk.min.es.js\";\n *\n *     const viewer = new Viewer({\n *         canvasId: \"myCanvas\"\n *     });\n *\n *     viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n *     viewer.scene.camera.look = [0, -5.75, 0];\n *     viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n *     const boxGeometry = new ReadableGeometry(viewer.scene, buildBoxGeometry({\n *         xSize: 1,\n *         ySize: 1,\n *         zSize: 1\n *     }));\n *\n *     new Node(viewer.scene, {\n *         id: \"table\",\n *         isModel: true, // <--------------------- Node represents a model\n *         rotation: [0, 50, 0],\n *         position: [0, 0, 0],\n *         scale: [1, 1, 1],\n *\n *         children: [\n *\n *             new Mesh(viewer.scene, { // Red table leg\n *                 id: \"redLeg\",\n *                 isObject: true, // <---------- Node represents an object\n *                 position: [-4, -6, -4],\n *                 scale: [1, 3, 1],\n *                 rotation: [0, 0, 0],\n *                 geometry: boxGeometry,\n *                 material: new PhongMaterial(viewer.scene, {\n *                     diffuse: [1, 0.3, 0.3]\n *                 })\n *             }),\n *\n *             new Mesh(viewer.scene, { // Green table leg\n *                 id: \"greenLeg\",\n *                 isObject: true, // <---------- Node represents an object\n *                 position: [4, -6, -4],\n *                 scale: [1, 3, 1],\n *                 rotation: [0, 0, 0],\n *                 geometry: boxGeometry,\n *                 material: new PhongMaterial(viewer.scene, {\n *                     diffuse: [0.3, 1.0, 0.3]\n *                 })\n *             }),\n *\n *             new Mesh(viewer.scene, {// Blue table leg\n *                 id: \"blueLeg\",\n *                 isObject: true, // <---------- Node represents an object\n *                 position: [4, -6, 4],\n *                 scale: [1, 3, 1],\n *                 rotation: [0, 0, 0],\n *                 geometry: boxGeometry,\n *                 material: new PhongMaterial(viewer.scene, {\n *                     diffuse: [0.3, 0.3, 1.0]\n *                 })\n *             }),\n *\n *             new Mesh(viewer.scene, {  // Yellow table leg\n *                 id: \"yellowLeg\",\n *                 isObject: true, // <---------- Node represents an object\n *                 position: [-4, -6, 4],\n *                 scale: [1, 3, 1],\n *                 rotation: [0, 0, 0],\n *                 geometry: boxGeometry,\n *                 material: new PhongMaterial(viewer.scene, {\n *                     diffuse: [1.0, 1.0, 0.0]\n *                 })\n *             }),\n *\n *             new Mesh(viewer.scene, { // Purple table top\n *                 id: \"tableTop\",\n *                 isObject: true, // <---------- Node represents an object\n *                 position: [0, -3, 0],\n *                 scale: [6, 0.5, 6],\n *                 rotation: [0, 0, 0],\n *                 geometry: boxGeometry,\n *                 material: new PhongMaterial(viewer.scene, {\n *                     diffuse: [1.0, 0.3, 1.0]\n *                 })\n *             })\n *         ]\n *     });\n *\n *     let aabb = viewer.scene.aabb;\n *     console.log(aabb);\n *\n *     new Mesh(viewer.scene, {\n *         geometry: new ReadableGeometry(viewer.scene, buildBoxLinesGeometryFromAABB({\n *             id: \"aabb\",\n *             aabb: aabb,\n *         })),\n *         material: new PhongMaterial(viewer.scene, {\n *             emissive: [0, 1,]\n *         })\n *     });\n * ````\n *\n * @function buildBoxLinesGeometryFromAABB\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number[]} [cfg.aabb]  AABB for which box will be created.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildBoxLinesGeometryFromAABB(cfg = {}){\n    return buildBoxLinesGeometry({\n        id: cfg.id,\n        center: [\n            (cfg.aabb[0] + cfg.aabb[3]) / 2.0,\n            (cfg.aabb[1] + cfg.aabb[4]) / 2.0,\n            (cfg.aabb[2] + cfg.aabb[5]) / 2.0,\n        ],\n        xSize: (Math.abs(cfg.aabb[3] - cfg.aabb[0])) / 2.0,\n        ySize: (Math.abs(cfg.aabb[4] - cfg.aabb[1])) / 2.0,\n        zSize: (Math.abs(cfg.aabb[5] - cfg.aabb[2])) / 2.0,\n    });\n}\n\n/**\n * @desc Creates a cylinder-shaped {@link Geometry}.\n *\n * ## Usage\n *\n * Creating a {@link Mesh} with a cylinder-shaped {@link ReadableGeometry} :\n *\n * [[Run this example](/examples/index.html#geometry_builders_buildCylinderGeometry)]\n *\n * ````javascript\n *\n * import {Viewer, Mesh, buildCylinderGeometry, ReadableGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n *  });\n *\n * viewer.camera.eye = [0, 0, 5];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildCylinderGeometry({\n *          center: [0,0,0],\n *          radiusTop: 2.0,\n *          radiusBottom: 2.0,\n *          height: 5.0,\n *          radialSegments: 20,\n *          heightSegments: 1,\n *          openEnded: false\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *         diffuseMap: new Texture(viewer.scene, {\n *             src: \"textures/diffuse/uvGrid2.jpg\"\n *         })\n *      })\n * });\n * ````\n *\n * @function buildCylinderGeometry\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID for the {@link Geometry}, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number[]} [cfg.center]  3D point indicating the center position.\n * @param {Number} [cfg.radiusTop=1]  Radius of top.\n * @param {Number} [cfg.radiusBottom=1]  Radius of bottom.\n * @param {Number} [cfg.height=1] Height.\n * @param {Number} [cfg.radialSegments=60]  Number of horizontal segments.\n * @param {Number} [cfg.heightSegments=1]  Number of vertical segments.\n * @param {Boolean} [cfg.openEnded=false]  Whether or not the cylinder has solid caps on the ends.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildCylinderGeometry(cfg = {}) {\n\n    let radiusTop = cfg.radiusTop || 1;\n    if (radiusTop < 0) {\n        console.error(\"negative radiusTop not allowed - will invert\");\n        radiusTop *= -1;\n    }\n\n    let radiusBottom = cfg.radiusBottom || 1;\n    if (radiusBottom < 0) {\n        console.error(\"negative radiusBottom not allowed - will invert\");\n        radiusBottom *= -1;\n    }\n\n    let height = cfg.height || 1;\n    if (height < 0) {\n        console.error(\"negative height not allowed - will invert\");\n        height *= -1;\n    }\n\n    let radialSegments = cfg.radialSegments || 32;\n    if (radialSegments < 0) {\n        console.error(\"negative radialSegments not allowed - will invert\");\n        radialSegments *= -1;\n    }\n    if (radialSegments < 3) {\n        radialSegments = 3;\n    }\n\n    let heightSegments = cfg.heightSegments || 1;\n    if (heightSegments < 0) {\n        console.error(\"negative heightSegments not allowed - will invert\");\n        heightSegments *= -1;\n    }\n    if (heightSegments < 1) {\n        heightSegments = 1;\n    }\n\n    const openEnded = !!cfg.openEnded;\n\n    let center = cfg.center;\n    const centerX = center ? center[0] : 0;\n    const centerY = center ? center[1] : 0;\n    const centerZ = center ? center[2] : 0;\n\n    const heightHalf = height / 2;\n    const heightLength = height / heightSegments;\n    const radialAngle = (2.0 * Math.PI / radialSegments);\n    const radialLength = 1.0 / radialSegments;\n    //var nextRadius = this._radiusBottom;\n    const radiusChange = (radiusTop - radiusBottom) / heightSegments;\n\n    const positions = [];\n    const normals = [];\n    const uvs = [];\n    const indices = [];\n\n    let h;\n    let i;\n\n    let x;\n    let z;\n\n    let currentRadius;\n    let currentHeight;\n\n    let first;\n    let second;\n\n    let startIndex;\n    let tu;\n    let tv;\n\n    // create vertices\n    const normalY = (90.0 - (Math.atan(height / (radiusBottom - radiusTop))) * 180 / Math.PI) / 90.0;\n\n    for (h = 0; h <= heightSegments; h++) {\n        currentRadius = radiusTop - h * radiusChange;\n        currentHeight = heightHalf - h * heightLength;\n\n        for (i = 0; i <= radialSegments; i++) {\n            x = Math.sin(i * radialAngle);\n            z = Math.cos(i * radialAngle);\n\n            normals.push(currentRadius * x);\n            normals.push(normalY); //todo\n            normals.push(currentRadius * z);\n\n            uvs.push((i * radialLength));\n            uvs.push(h * 1 / heightSegments);\n\n            positions.push((currentRadius * x) + centerX);\n            positions.push((currentHeight) + centerY);\n            positions.push((currentRadius * z) + centerZ);\n        }\n    }\n\n    // create faces\n    for (h = 0; h < heightSegments; h++) {\n        for (i = 0; i <= radialSegments; i++) {\n\n            first = h * (radialSegments + 1) + i;\n            second = first + radialSegments;\n\n            indices.push(first);\n            indices.push(second);\n            indices.push(second + 1);\n\n            indices.push(first);\n            indices.push(second + 1);\n            indices.push(first + 1);\n        }\n    }\n\n    // create top cap\n    if (!openEnded && radiusTop > 0) {\n        startIndex = (positions.length / 3);\n\n        // top center\n        normals.push(0.0);\n        normals.push(1.0);\n        normals.push(0.0);\n\n        uvs.push(0.5);\n        uvs.push(0.5);\n\n        positions.push(0 + centerX);\n        positions.push(heightHalf + centerY);\n        positions.push(0 + centerZ);\n\n        // top triangle fan\n        for (i = 0; i <= radialSegments; i++) {\n            x = Math.sin(i * radialAngle);\n            z = Math.cos(i * radialAngle);\n            tu = (0.5 * Math.sin(i * radialAngle)) + 0.5;\n            tv = (0.5 * Math.cos(i * radialAngle)) + 0.5;\n\n            normals.push(radiusTop * x);\n            normals.push(1.0);\n            normals.push(radiusTop * z);\n\n            uvs.push(tu);\n            uvs.push(tv);\n\n            positions.push((radiusTop * x) + centerX);\n            positions.push((heightHalf) + centerY);\n            positions.push((radiusTop * z) + centerZ);\n        }\n\n        for (i = 0; i < radialSegments; i++) {\n            center = startIndex;\n            first = startIndex + 1 + i;\n\n            indices.push(first);\n            indices.push(first + 1);\n            indices.push(center);\n        }\n    }\n\n    // create bottom cap\n    if (!openEnded && radiusBottom > 0) {\n\n        startIndex = (positions.length / 3);\n\n        // top center\n        normals.push(0.0);\n        normals.push(-1.0);\n        normals.push(0.0);\n\n        uvs.push(0.5);\n        uvs.push(0.5);\n\n        positions.push(0 + centerX);\n        positions.push(0 - heightHalf + centerY);\n        positions.push(0 + centerZ);\n\n        // top triangle fan\n        for (i = 0; i <= radialSegments; i++) {\n\n            x = Math.sin(i * radialAngle);\n            z = Math.cos(i * radialAngle);\n\n            tu = (0.5 * Math.sin(i * radialAngle)) + 0.5;\n            tv = (0.5 * Math.cos(i * radialAngle)) + 0.5;\n\n            normals.push(radiusBottom * x);\n            normals.push(-1.0);\n            normals.push(radiusBottom * z);\n\n            uvs.push(tu);\n            uvs.push(tv);\n\n            positions.push((radiusBottom * x) + centerX);\n            positions.push((0 - heightHalf) + centerY);\n            positions.push((radiusBottom * z) + centerZ);\n        }\n\n        for (i = 0; i < radialSegments; i++) {\n\n            center = startIndex;\n            first = startIndex + 1 + i;\n\n            indices.push(center);\n            indices.push(first + 1);\n            indices.push(first);\n        }\n    }\n\n    return utils.apply(cfg, {\n        positions: positions,\n        normals: normals,\n        uv: uvs,\n        indices: indices\n    });\n}\n\n/**\n * @desc Creates a grid-shaped {@link Geometry}.\n *\n * ## Usage\n *\n * Creating a {@link Mesh} with a GridGeometry and a {@link PhongMaterial}:\n *\n * [[Run this example](/examples/index.html#geometry_builders_buildGridGeometry)]\n *\n * ````javascript\n * import {Viewer, Mesh, buildGridGeometry, VBOGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [0, 0, 5];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new VBOGeometry(viewer.scene, buildGridGeometry({\n *          size: 1000,\n *          divisions: 500\n *      })),\n *      material: new PhongMaterial(viewer.scene, {\n *          color: [0.0, 0.0, 0.0],\n *          emissive: [0.4, 0.4, 0.4]\n *      }),\n *      position: [0, -1.6, 0]\n * });\n * ````\n *\n * @function buildGridGeometry\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID for the {@link Geometry}, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number} [cfg.size=1] Dimension on the X and Z-axis.\n * @param {Number} [cfg.divisions=1] Number of divisions on X and Z axis..\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildGridGeometry(cfg = {}) {\n\n    let size = cfg.size || 1;\n    if (size < 0) {\n        console.error(\"negative size not allowed - will invert\");\n        size *= -1;\n    }\n\n    let divisions = cfg.divisions || 1;\n    if (divisions < 0) {\n        console.error(\"negative divisions not allowed - will invert\");\n        divisions *= -1;\n    }\n    if (divisions < 1) {\n        divisions = 1;\n    }\n\n    size = size || 10;\n    divisions = divisions || 10;\n\n    const step = size / divisions;\n    const halfSize = size / 2;\n\n    const positions = [];\n    const indices = [];\n    let l = 0;\n\n    for (let i = 0, k = -halfSize; i <= divisions; i++, k += step) {\n\n        positions.push(-halfSize);\n        positions.push(0);\n        positions.push(k);\n\n        positions.push(halfSize);\n        positions.push(0);\n        positions.push(k);\n\n        positions.push(k);\n        positions.push(0);\n        positions.push(-halfSize);\n\n        positions.push(k);\n        positions.push(0);\n        positions.push(halfSize);\n\n        indices.push(l++);\n        indices.push(l++);\n        indices.push(l++);\n        indices.push(l++);\n    }\n\n    return utils.apply(cfg, {\n        primitive: \"lines\",\n        positions: positions,\n        indices: indices\n    });\n}\n\n/**\n * @desc Creates a plane-shaped {@link Geometry}.\n *\n * ## Usage\n *\n * Creating a {@link Mesh} with a PlaneGeometry and a {@link PhongMaterial} with diffuse {@link Texture}:\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#buildPlaneGeometry)]\n *\n * ````javascript\n * import {Viewer, Mesh, buildPlaneGeometry, ReadableGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [0, 0, 5];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildPlaneGeometry({\n *          center: [0,0,0],\n *          xSize: 2,\n *          zSize: 2,\n *          xSegments: 10,\n *          zSegments: 10\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse/uvGrid2.jpg\"\n *          })\n *      })\n *  });\n * ````\n *\n * @function buildPlaneGeometry\n * @param {*} [cfg] Configs\n * @param {Number[]} [cfg.center]  3D point indicating the center position.\n * @param {String} [cfg.id] Optional ID for the {@link Geometry}, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number} [cfg.xSize=1] Dimension on the X-axis.\n * @param {Number} [cfg.zSize=1] Dimension on the Z-axis.\n * @param {Number} [cfg.xSegments=1] Number of segments on the X-axis.\n * @param {Number} [cfg.zSegments=1] Number of segments on the Z-axis.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildPlaneGeometry(cfg = {}) {\n\n    let xSize = cfg.xSize || 1;\n    if (xSize < 0) {\n        console.error(\"negative xSize not allowed - will invert\");\n        xSize *= -1;\n    }\n\n    let zSize = cfg.zSize || 1;\n    if (zSize < 0) {\n        console.error(\"negative zSize not allowed - will invert\");\n        zSize *= -1;\n    }\n\n    let xSegments = cfg.xSegments || 1;\n    if (xSegments < 0) {\n        console.error(\"negative xSegments not allowed - will invert\");\n        xSegments *= -1;\n    }\n    if (xSegments < 1) {\n        xSegments = 1;\n    }\n\n    let zSegments = cfg.xSegments || 1;\n    if (zSegments < 0) {\n        console.error(\"negative zSegments not allowed - will invert\");\n        zSegments *= -1;\n    }\n    if (zSegments < 1) {\n        zSegments = 1;\n    }\n\n    const center = cfg.center;\n    const centerX = center ? center[0] : 0;\n    const centerY = center ? center[1] : 0;\n    const centerZ = center ? center[2] : 0;\n\n    const halfWidth = xSize / 2;\n    const halfHeight = zSize / 2;\n\n    const planeX = Math.floor(xSegments) || 1;\n    const planeZ = Math.floor(zSegments) || 1;\n\n    const planeX1 = planeX + 1;\n    const planeZ1 = planeZ + 1;\n\n    const segmentWidth = xSize / planeX;\n    const segmentHeight = zSize / planeZ;\n\n    const positions = new Float32Array(planeX1 * planeZ1 * 3);\n    const normals = new Float32Array(planeX1 * planeZ1 * 3);\n    const uvs = new Float32Array(planeX1 * planeZ1 * 2);\n\n    let offset = 0;\n    let offset2 = 0;\n\n    let iz;\n    let ix;\n    let x;\n    let a;\n    let b;\n    let c;\n    let d;\n\n    for (iz = 0; iz < planeZ1; iz++) {\n\n        const z = iz * segmentHeight - halfHeight;\n\n        for (ix = 0; ix < planeX1; ix++) {\n\n            x = ix * segmentWidth - halfWidth;\n\n            positions[offset] = x + centerX;\n            positions[offset + 1] = centerY;\n            positions[offset + 2] = -z + centerZ;\n\n            normals[offset + 1] = 1;\n\n            uvs[offset2] = (ix) / planeX;\n            uvs[offset2 + 1] = ((planeZ - iz) / planeZ);\n\n            offset += 3;\n            offset2 += 2;\n        }\n    }\n\n    offset = 0;\n\n    const indices = new ((positions.length / 3) > 65535 ? Uint32Array : Uint16Array)(planeX * planeZ * 6);\n\n    for (iz = 0; iz < planeZ; iz++) {\n\n        for (ix = 0; ix < planeX; ix++) {\n\n            a = ix + planeX1 * iz;\n            b = ix + planeX1 * (iz + 1);\n            c = (ix + 1) + planeX1 * (iz + 1);\n            d = (ix + 1) + planeX1 * iz;\n\n            indices[offset] = d;\n            indices[offset + 1] = b;\n            indices[offset + 2] = a;\n\n            indices[offset + 3] = d;\n            indices[offset + 4] = c;\n            indices[offset + 5] = b;\n\n            offset += 6;\n        }\n    }\n\n    return utils.apply(cfg, {\n        positions: positions,\n        normals: normals,\n        uv: uvs,\n        indices: indices\n    });\n}\n\n/**\n * @desc Creates a sphere-shaped {@link Geometry}.\n *\n * ## Usage\n *\n * Creating a {@link Mesh} with a sphere-shaped {@link ReadableGeometry} :\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#buildSphereGeometry)]\n *\n * ````javascript\n * import {Viewer, Mesh, buildSphereGeometry, ReadableGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [0, 0, 5];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildSphereGeometry({\n *          center: [0,0,0],\n *          radius: 1.5,\n *          heightSegments: 60,\n *          widthSegments: 60\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *         diffuseMap: new Texture(viewer.scene, {\n *             src: \"textures/diffuse/uvGrid2.jpg\"\n *         })\n *      })\n * });\n * ````\n *\n * @function buildSphereGeometry\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID for the {@link Geometry}, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number[]} [cfg.center]  3D point indicating the center position.\n * @param {Number} [cfg.radius=1]  Radius.\n * @param {Number} [cfg.heightSegments=24] Number of latitudinal bands.\n * @param  {Number} [cfg.widthSegments=18] Number of longitudinal bands.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildSphereGeometry(cfg = {}) {\n\n    const lod = cfg.lod || 1;\n\n    const centerX = cfg.center ? cfg.center[0] : 0;\n    const centerY = cfg.center ? cfg.center[1] : 0;\n    const centerZ = cfg.center ? cfg.center[2] : 0;\n\n    let radius = cfg.radius || 1;\n    if (radius < 0) {\n        console.error(\"negative radius not allowed - will invert\");\n        radius *= -1;\n    }\n\n    let heightSegments = cfg.heightSegments || 18;\n    if (heightSegments < 0) {\n        console.error(\"negative heightSegments not allowed - will invert\");\n        heightSegments *= -1;\n    }\n    heightSegments = Math.floor(lod * heightSegments);\n    if (heightSegments < 18) {\n        heightSegments = 18;\n    }\n\n    let widthSegments = cfg.widthSegments || 18;\n    if (widthSegments < 0) {\n        console.error(\"negative widthSegments not allowed - will invert\");\n        widthSegments *= -1;\n    }\n    widthSegments = Math.floor(lod * widthSegments);\n    if (widthSegments < 18) {\n        widthSegments = 18;\n    }\n\n    const positions = [];\n    const normals = [];\n    const uvs = [];\n    const indices = [];\n\n    let i;\n    let j;\n\n    let theta;\n    let sinTheta;\n    let cosTheta;\n\n    let phi;\n    let sinPhi;\n    let cosPhi;\n\n    let x;\n    let y;\n    let z;\n\n    let u;\n    let v;\n\n    let first;\n    let second;\n\n    for (i = 0; i <= heightSegments; i++) {\n\n        theta = i * Math.PI / heightSegments;\n        sinTheta = Math.sin(theta);\n        cosTheta = Math.cos(theta);\n\n        for (j = 0; j <= widthSegments; j++) {\n\n            phi = j * 2 * Math.PI / widthSegments;\n            sinPhi = Math.sin(phi);\n            cosPhi = Math.cos(phi);\n\n            x = cosPhi * sinTheta;\n            y = cosTheta;\n            z = sinPhi * sinTheta;\n            u = 1.0 - j / widthSegments;\n            v = i / heightSegments;\n\n            normals.push(x);\n            normals.push(y);\n            normals.push(z);\n\n            uvs.push(u);\n            uvs.push(v);\n\n            positions.push(centerX + radius * x);\n            positions.push(centerY + radius * y);\n            positions.push(centerZ + radius * z);\n        }\n    }\n\n    for (i = 0; i < heightSegments; i++) {\n        for (j = 0; j < widthSegments; j++) {\n\n            first = (i * (widthSegments + 1)) + j;\n            second = first + widthSegments + 1;\n\n            indices.push(first + 1);\n            indices.push(second + 1);\n            indices.push(second);\n            indices.push(first + 1);\n            indices.push(second);\n            indices.push(first);\n        }\n    }\n\n    return utils.apply(cfg, {\n        positions: positions,\n        normals: normals,\n        uv: uvs,\n        indices: indices\n    });\n}\n\n/**\n * @desc Creates a torus-shaped {@link Geometry}.\n *\n * ## Usage\n * Creating a {@link Mesh} with a torus-shaped {@link ReadableGeometry} :\n *\n * [[Run this example](/examples/index.html#geometry_builders_buildTorusGeometry)]\n * \n * ````javascript\n * import {Viewer, Mesh, buildTorusGeometry, ReadableGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [0, 0, 5];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry({\n *          center: [0,0,0],\n *          radius: 1.0,\n *          tube: 0.5,\n *          radialSegments: 32,\n *          tubeSegments: 24,\n *          arc: Math.PI * 2.0\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *         diffuseMap: new Texture(viewer.scene, {\n *             src: \"textures/diffuse/uvGrid2.jpg\"\n *         })\n *      })\n * });\n * ````\n *\n * @function buildTorusGeometry\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID for the {@link Geometry}, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number[]} [cfg.center] 3D point indicating the center position.\n * @param {Number} [cfg.radius=1] The overall radius.\n * @param {Number} [cfg.tube=0.3] The tube radius.\n * @param {Number} [cfg.radialSegments=32] The number of radial segments.\n * @param {Number} [cfg.tubeSegments=24] The number of tubular segments.\n * @param {Number} [cfg.arc=Math.PI*0.5] The length of the arc in radians, where Math.PI*2 is a closed torus.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildTorusGeometry(cfg = {}) {\n\n    let radius = cfg.radius || 1;\n    if (radius < 0) {\n        console.error(\"negative radius not allowed - will invert\");\n        radius *= -1;\n    }\n    radius *= 0.5;\n\n    let tube = cfg.tube || 0.3;\n    if (tube < 0) {\n        console.error(\"negative tube not allowed - will invert\");\n        tube *= -1;\n    }\n\n    let radialSegments = cfg.radialSegments || 32;\n    if (radialSegments < 0) {\n        console.error(\"negative radialSegments not allowed - will invert\");\n        radialSegments *= -1;\n    }\n    if (radialSegments < 4) {\n        radialSegments = 4;\n    }\n\n    let tubeSegments = cfg.tubeSegments || 24;\n    if (tubeSegments < 0) {\n        console.error(\"negative tubeSegments not allowed - will invert\");\n        tubeSegments *= -1;\n    }\n    if (tubeSegments < 4) {\n        tubeSegments = 4;\n    }\n\n    let arc = cfg.arc || Math.PI * 2;\n    if (arc < 0) {\n        console.warn(\"negative arc not allowed - will invert\");\n        arc *= -1;\n    }\n    if (arc > 360) {\n        arc = 360;\n    }\n\n    const center = cfg.center;\n    let centerX = center ? center[0] : 0;\n    let centerY = center ? center[1] : 0;\n    const centerZ = center ? center[2] : 0;\n\n    const positions = [];\n    const normals = [];\n    const uvs = [];\n    const indices = [];\n\n    let u;\n    let v;\n    let x;\n    let y;\n    let z;\n    let vec;\n\n    let i;\n    let j;\n\n    for (j = 0; j <= tubeSegments; j++) {\n        for (i = 0; i <= radialSegments; i++) {\n\n            u = i / radialSegments * arc;\n            v = 0.785398 + (j / tubeSegments * Math.PI * 2);\n\n            centerX = radius * Math.cos(u);\n            centerY = radius * Math.sin(u);\n\n            x = (radius + tube * Math.cos(v)) * Math.cos(u);\n            y = (radius + tube * Math.cos(v)) * Math.sin(u);\n            z = tube * Math.sin(v);\n\n            positions.push(x + centerX);\n            positions.push(y + centerY);\n            positions.push(z + centerZ);\n\n            uvs.push(1 - (i / radialSegments));\n            uvs.push((j / tubeSegments));\n\n            vec = math.normalizeVec3(math.subVec3([x, y, z], [centerX, centerY, centerZ], []), []);\n\n            normals.push(vec[0]);\n            normals.push(vec[1]);\n            normals.push(vec[2]);\n        }\n    }\n\n    let a;\n    let b;\n    let c;\n    let d;\n\n    for (j = 1; j <= tubeSegments; j++) {\n        for (i = 1; i <= radialSegments; i++) {\n\n            a = (radialSegments + 1) * j + i - 1;\n            b = (radialSegments + 1) * (j - 1) + i - 1;\n            c = (radialSegments + 1) * (j - 1) + i;\n            d = (radialSegments + 1) * j + i;\n\n            indices.push(a);\n            indices.push(b);\n            indices.push(c);\n\n            indices.push(c);\n            indices.push(d);\n            indices.push(a);\n        }\n    }\n\n    return utils.apply(cfg, {\n        positions: positions,\n        normals: normals,\n        uv: uvs,\n        indices: indices\n    });\n}\n\nconst letters = {\n    ' ': {width: 16, points: []},\n    '!': {\n        width: 10, points: [\n            [5, 21],\n            [5, 7],\n            [-1, -1],\n            [5, 2],\n            [4, 1],\n            [5, 0],\n            [6, 1],\n            [5, 2]\n        ]\n    },\n    '\"': {\n        width: 16, points: [\n            [4, 21],\n            [4, 14],\n            [-1, -1],\n            [12, 21],\n            [12, 14]\n        ]\n    },\n    '#': {\n        width: 21, points: [\n            [11, 25],\n            [4, -7],\n            [-1, -1],\n            [17, 25],\n            [10, -7],\n            [-1, -1],\n            [4, 12],\n            [18, 12],\n            [-1, -1],\n            [3, 6],\n            [17, 6]\n        ]\n    },\n    '$': {\n        width: 20, points: [\n            [8, 25],\n            [8, -4],\n            [-1, -1],\n            [12, 25],\n            [12, -4],\n            [-1, -1],\n            [17, 18],\n            [15, 20],\n            [12, 21],\n            [8, 21],\n            [5, 20],\n            [3, 18],\n            [3, 16],\n            [4, 14],\n            [5, 13],\n            [7, 12],\n            [13, 10],\n            [15, 9],\n            [16, 8],\n            [17, 6],\n            [17, 3],\n            [15, 1],\n            [12, 0],\n            [8, 0],\n            [5, 1],\n            [3, 3]\n        ]\n    },\n    '%': {\n        width: 24, points: [\n            [21, 21],\n            [3, 0],\n            [-1, -1],\n            [8, 21],\n            [10, 19],\n            [10, 17],\n            [9, 15],\n            [7, 14],\n            [5, 14],\n            [3, 16],\n            [3, 18],\n            [4, 20],\n            [6, 21],\n            [8, 21],\n            [10, 20],\n            [13, 19],\n            [16, 19],\n            [19, 20],\n            [21, 21],\n            [-1, -1],\n            [17, 7],\n            [15, 6],\n            [14, 4],\n            [14, 2],\n            [16, 0],\n            [18, 0],\n            [20, 1],\n            [21, 3],\n            [21, 5],\n            [19, 7],\n            [17, 7]\n        ]\n    },\n    '&': {\n        width: 26, points: [\n            [23, 12],\n            [23, 13],\n            [22, 14],\n            [21, 14],\n            [20, 13],\n            [19, 11],\n            [17, 6],\n            [15, 3],\n            [13, 1],\n            [11, 0],\n            [7, 0],\n            [5, 1],\n            [4, 2],\n            [3, 4],\n            [3, 6],\n            [4, 8],\n            [5, 9],\n            [12, 13],\n            [13, 14],\n            [14, 16],\n            [14, 18],\n            [13, 20],\n            [11, 21],\n            [9, 20],\n            [8, 18],\n            [8, 16],\n            [9, 13],\n            [11, 10],\n            [16, 3],\n            [18, 1],\n            [20, 0],\n            [22, 0],\n            [23, 1],\n            [23, 2]\n        ]\n    },\n    '\\'': {\n        width: 10, points: [\n            [5, 19],\n            [4, 20],\n            [5, 21],\n            [6, 20],\n            [6, 18],\n            [5, 16],\n            [4, 15]\n        ]\n    },\n    '(': {\n        width: 14, points: [\n            [11, 25],\n            [9, 23],\n            [7, 20],\n            [5, 16],\n            [4, 11],\n            [4, 7],\n            [5, 2],\n            [7, -2],\n            [9, -5],\n            [11, -7]\n        ]\n    },\n    ')': {\n        width: 14, points: [\n            [3, 25],\n            [5, 23],\n            [7, 20],\n            [9, 16],\n            [10, 11],\n            [10, 7],\n            [9, 2],\n            [7, -2],\n            [5, -5],\n            [3, -7]\n        ]\n    },\n    '*': {\n        width: 16, points: [\n            [8, 21],\n            [8, 9],\n            [-1, -1],\n            [3, 18],\n            [13, 12],\n            [-1, -1],\n            [13, 18],\n            [3, 12]\n        ]\n    },\n    '+': {\n        width: 26, points: [\n            [13, 18],\n            [13, 0],\n            [-1, -1],\n            [4, 9],\n            [22, 9]\n        ]\n    },\n    ',': {\n        width: 10, points: [\n            [6, 1],\n            [5, 0],\n            [4, 1],\n            [5, 2],\n            [6, 1],\n            [6, -1],\n            [5, -3],\n            [4, -4]\n        ]\n    },\n    '-': {\n        width: 26, points: [\n            [4, 9],\n            [22, 9]\n        ]\n    },\n    '.': {\n        width: 10, points: [\n            [5, 2],\n            [4, 1],\n            [5, 0],\n            [6, 1],\n            [5, 2]\n        ]\n    },\n    '/': {\n        width: 22, points: [\n            [20, 25],\n            [2, -7]\n        ]\n    },\n    '0': {\n        width: 20, points: [\n            [9, 21],\n            [6, 20],\n            [4, 17],\n            [3, 12],\n            [3, 9],\n            [4, 4],\n            [6, 1],\n            [9, 0],\n            [11, 0],\n            [14, 1],\n            [16, 4],\n            [17, 9],\n            [17, 12],\n            [16, 17],\n            [14, 20],\n            [11, 21],\n            [9, 21]\n        ]\n    },\n    '1': {\n        width: 20, points: [\n            [6, 17],\n            [8, 18],\n            [11, 21],\n            [11, 0]\n        ]\n    },\n    '2': {\n        width: 20, points: [\n            [4, 16],\n            [4, 17],\n            [5, 19],\n            [6, 20],\n            [8, 21],\n            [12, 21],\n            [14, 20],\n            [15, 19],\n            [16, 17],\n            [16, 15],\n            [15, 13],\n            [13, 10],\n            [3, 0],\n            [17, 0]\n        ]\n    },\n    '3': {\n        width: 20, points: [\n            [5, 21],\n            [16, 21],\n            [10, 13],\n            [13, 13],\n            [15, 12],\n            [16, 11],\n            [17, 8],\n            [17, 6],\n            [16, 3],\n            [14, 1],\n            [11, 0],\n            [8, 0],\n            [5, 1],\n            [4, 2],\n            [3, 4]\n        ]\n    },\n    '4': {\n        width: 20, points: [\n            [13, 21],\n            [3, 7],\n            [18, 7],\n            [-1, -1],\n            [13, 21],\n            [13, 0]\n        ]\n    },\n    '5': {\n        width: 20, points: [\n            [15, 21],\n            [5, 21],\n            [4, 12],\n            [5, 13],\n            [8, 14],\n            [11, 14],\n            [14, 13],\n            [16, 11],\n            [17, 8],\n            [17, 6],\n            [16, 3],\n            [14, 1],\n            [11, 0],\n            [8, 0],\n            [5, 1],\n            [4, 2],\n            [3, 4]\n        ]\n    },\n    '6': {\n        width: 20, points: [\n            [16, 18],\n            [15, 20],\n            [12, 21],\n            [10, 21],\n            [7, 20],\n            [5, 17],\n            [4, 12],\n            [4, 7],\n            [5, 3],\n            [7, 1],\n            [10, 0],\n            [11, 0],\n            [14, 1],\n            [16, 3],\n            [17, 6],\n            [17, 7],\n            [16, 10],\n            [14, 12],\n            [11, 13],\n            [10, 13],\n            [7, 12],\n            [5, 10],\n            [4, 7]\n        ]\n    },\n    '7': {\n        width: 20, points: [\n            [17, 21],\n            [7, 0],\n            [-1, -1],\n            [3, 21],\n            [17, 21]\n        ]\n    },\n    '8': {\n        width: 20, points: [\n            [8, 21],\n            [5, 20],\n            [4, 18],\n            [4, 16],\n            [5, 14],\n            [7, 13],\n            [11, 12],\n            [14, 11],\n            [16, 9],\n            [17, 7],\n            [17, 4],\n            [16, 2],\n            [15, 1],\n            [12, 0],\n            [8, 0],\n            [5, 1],\n            [4, 2],\n            [3, 4],\n            [3, 7],\n            [4, 9],\n            [6, 11],\n            [9, 12],\n            [13, 13],\n            [15, 14],\n            [16, 16],\n            [16, 18],\n            [15, 20],\n            [12, 21],\n            [8, 21]\n        ]\n    },\n    '9': {\n        width: 20, points: [\n            [16, 14],\n            [15, 11],\n            [13, 9],\n            [10, 8],\n            [9, 8],\n            [6, 9],\n            [4, 11],\n            [3, 14],\n            [3, 15],\n            [4, 18],\n            [6, 20],\n            [9, 21],\n            [10, 21],\n            [13, 20],\n            [15, 18],\n            [16, 14],\n            [16, 9],\n            [15, 4],\n            [13, 1],\n            [10, 0],\n            [8, 0],\n            [5, 1],\n            [4, 3]\n        ]\n    },\n    ':': {\n        width: 10, points: [\n            [5, 14],\n            [4, 13],\n            [5, 12],\n            [6, 13],\n            [5, 14],\n            [-1, -1],\n            [5, 2],\n            [4, 1],\n            [5, 0],\n            [6, 1],\n            [5, 2]\n        ]\n    },\n    ';': {\n        width: 10, points: [\n            [5, 14],\n            [4, 13],\n            [5, 12],\n            [6, 13],\n            [5, 14],\n            [-1, -1],\n            [6, 1],\n            [5, 0],\n            [4, 1],\n            [5, 2],\n            [6, 1],\n            [6, -1],\n            [5, -3],\n            [4, -4]\n        ]\n    },\n    '<': {\n        width: 24, points: [\n            [20, 18],\n            [4, 9],\n            [20, 0]\n        ]\n    },\n    '=': {\n        width: 26, points: [\n            [4, 12],\n            [22, 12],\n            [-1, -1],\n            [4, 6],\n            [22, 6]\n        ]\n    },\n    '>': {\n        width: 24, points: [\n            [4, 18],\n            [20, 9],\n            [4, 0]\n        ]\n    },\n    '?': {\n        width: 18, points: [\n            [3, 16],\n            [3, 17],\n            [4, 19],\n            [5, 20],\n            [7, 21],\n            [11, 21],\n            [13, 20],\n            [14, 19],\n            [15, 17],\n            [15, 15],\n            [14, 13],\n            [13, 12],\n            [9, 10],\n            [9, 7],\n            [-1, -1],\n            [9, 2],\n            [8, 1],\n            [9, 0],\n            [10, 1],\n            [9, 2]\n        ]\n    },\n    '@': {\n        width: 27, points: [\n            [18, 13],\n            [17, 15],\n            [15, 16],\n            [12, 16],\n            [10, 15],\n            [9, 14],\n            [8, 11],\n            [8, 8],\n            [9, 6],\n            [11, 5],\n            [14, 5],\n            [16, 6],\n            [17, 8],\n            [-1, -1],\n            [12, 16],\n            [10, 14],\n            [9, 11],\n            [9, 8],\n            [10, 6],\n            [11, 5],\n            [-1, -1],\n            [18, 16],\n            [17, 8],\n            [17, 6],\n            [19, 5],\n            [21, 5],\n            [23, 7],\n            [24, 10],\n            [24, 12],\n            [23, 15],\n            [22, 17],\n            [20, 19],\n            [18, 20],\n            [15, 21],\n            [12, 21],\n            [9, 20],\n            [7, 19],\n            [5, 17],\n            [4, 15],\n            [3, 12],\n            [3, 9],\n            [4, 6],\n            [5, 4],\n            [7, 2],\n            [9, 1],\n            [12, 0],\n            [15, 0],\n            [18, 1],\n            [20, 2],\n            [21, 3],\n            [-1, -1],\n            [19, 16],\n            [18, 8],\n            [18, 6],\n            [19, 5]\n        ]\n    },\n    'A': {\n        width: 18, points: [\n            [9, 21],\n            [1, 0],\n            [-1, -1],\n            [9, 21],\n            [17, 0],\n            [-1, -1],\n            [4, 7],\n            [14, 7]\n        ]\n    },\n    'B': {\n        width: 21, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 21],\n            [13, 21],\n            [16, 20],\n            [17, 19],\n            [18, 17],\n            [18, 15],\n            [17, 13],\n            [16, 12],\n            [13, 11],\n            [-1, -1],\n            [4, 11],\n            [13, 11],\n            [16, 10],\n            [17, 9],\n            [18, 7],\n            [18, 4],\n            [17, 2],\n            [16, 1],\n            [13, 0],\n            [4, 0]\n        ]\n    },\n    'C': {\n        width: 21, points: [\n            [18, 16],\n            [17, 18],\n            [15, 20],\n            [13, 21],\n            [9, 21],\n            [7, 20],\n            [5, 18],\n            [4, 16],\n            [3, 13],\n            [3, 8],\n            [4, 5],\n            [5, 3],\n            [7, 1],\n            [9, 0],\n            [13, 0],\n            [15, 1],\n            [17, 3],\n            [18, 5]\n        ]\n    },\n    'D': {\n        width: 21, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 21],\n            [11, 21],\n            [14, 20],\n            [16, 18],\n            [17, 16],\n            [18, 13],\n            [18, 8],\n            [17, 5],\n            [16, 3],\n            [14, 1],\n            [11, 0],\n            [4, 0]\n        ]\n    },\n    'E': {\n        width: 19, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 21],\n            [17, 21],\n            [-1, -1],\n            [4, 11],\n            [12, 11],\n            [-1, -1],\n            [4, 0],\n            [17, 0]\n        ]\n    },\n    'F': {\n        width: 18, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 21],\n            [17, 21],\n            [-1, -1],\n            [4, 11],\n            [12, 11]\n        ]\n    },\n    'G': {\n        width: 21, points: [\n            [18, 16],\n            [17, 18],\n            [15, 20],\n            [13, 21],\n            [9, 21],\n            [7, 20],\n            [5, 18],\n            [4, 16],\n            [3, 13],\n            [3, 8],\n            [4, 5],\n            [5, 3],\n            [7, 1],\n            [9, 0],\n            [13, 0],\n            [15, 1],\n            [17, 3],\n            [18, 5],\n            [18, 8],\n            [-1, -1],\n            [13, 8],\n            [18, 8]\n        ]\n    },\n    'H': {\n        width: 22, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [18, 21],\n            [18, 0],\n            [-1, -1],\n            [4, 11],\n            [18, 11]\n        ]\n    },\n    'I': {\n        width: 8, points: [\n            [4, 21],\n            [4, 0]\n        ]\n    },\n    'J': {\n        width: 16, points: [\n            [12, 21],\n            [12, 5],\n            [11, 2],\n            [10, 1],\n            [8, 0],\n            [6, 0],\n            [4, 1],\n            [3, 2],\n            [2, 5],\n            [2, 7]\n        ]\n    },\n    'K': {\n        width: 21, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [18, 21],\n            [4, 7],\n            [-1, -1],\n            [9, 12],\n            [18, 0]\n        ]\n    },\n    'L': {\n        width: 17, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 0],\n            [16, 0]\n        ]\n    },\n    'M': {\n        width: 24, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 21],\n            [12, 0],\n            [-1, -1],\n            [20, 21],\n            [12, 0],\n            [-1, -1],\n            [20, 21],\n            [20, 0]\n        ]\n    },\n    'N': {\n        width: 22, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 21],\n            [18, 0],\n            [-1, -1],\n            [18, 21],\n            [18, 0]\n        ]\n    },\n    'O': {\n        width: 22, points: [\n            [9, 21],\n            [7, 20],\n            [5, 18],\n            [4, 16],\n            [3, 13],\n            [3, 8],\n            [4, 5],\n            [5, 3],\n            [7, 1],\n            [9, 0],\n            [13, 0],\n            [15, 1],\n            [17, 3],\n            [18, 5],\n            [19, 8],\n            [19, 13],\n            [18, 16],\n            [17, 18],\n            [15, 20],\n            [13, 21],\n            [9, 21]\n        ]\n    },\n    'P': {\n        width: 21, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 21],\n            [13, 21],\n            [16, 20],\n            [17, 19],\n            [18, 17],\n            [18, 14],\n            [17, 12],\n            [16, 11],\n            [13, 10],\n            [4, 10]\n        ]\n    },\n    'Q': {\n        width: 22, points: [\n            [9, 21],\n            [7, 20],\n            [5, 18],\n            [4, 16],\n            [3, 13],\n            [3, 8],\n            [4, 5],\n            [5, 3],\n            [7, 1],\n            [9, 0],\n            [13, 0],\n            [15, 1],\n            [17, 3],\n            [18, 5],\n            [19, 8],\n            [19, 13],\n            [18, 16],\n            [17, 18],\n            [15, 20],\n            [13, 21],\n            [9, 21],\n            [-1, -1],\n            [12, 4],\n            [18, -2]\n        ]\n    },\n    'R': {\n        width: 21, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 21],\n            [13, 21],\n            [16, 20],\n            [17, 19],\n            [18, 17],\n            [18, 15],\n            [17, 13],\n            [16, 12],\n            [13, 11],\n            [4, 11],\n            [-1, -1],\n            [11, 11],\n            [18, 0]\n        ]\n    },\n    'S': {\n        width: 20, points: [\n            [17, 18],\n            [15, 20],\n            [12, 21],\n            [8, 21],\n            [5, 20],\n            [3, 18],\n            [3, 16],\n            [4, 14],\n            [5, 13],\n            [7, 12],\n            [13, 10],\n            [15, 9],\n            [16, 8],\n            [17, 6],\n            [17, 3],\n            [15, 1],\n            [12, 0],\n            [8, 0],\n            [5, 1],\n            [3, 3]\n        ]\n    },\n    'T': {\n        width: 16, points: [\n            [8, 21],\n            [8, 0],\n            [-1, -1],\n            [1, 21],\n            [15, 21]\n        ]\n    },\n    'U': {\n        width: 22, points: [\n            [4, 21],\n            [4, 6],\n            [5, 3],\n            [7, 1],\n            [10, 0],\n            [12, 0],\n            [15, 1],\n            [17, 3],\n            [18, 6],\n            [18, 21]\n        ]\n    },\n    'V': {\n        width: 18, points: [\n            [1, 21],\n            [9, 0],\n            [-1, -1],\n            [17, 21],\n            [9, 0]\n        ]\n    },\n    'W': {\n        width: 24, points: [\n            [2, 21],\n            [7, 0],\n            [-1, -1],\n            [12, 21],\n            [7, 0],\n            [-1, -1],\n            [12, 21],\n            [17, 0],\n            [-1, -1],\n            [22, 21],\n            [17, 0]\n        ]\n    },\n    'X': {\n        width: 20, points: [\n            [3, 21],\n            [17, 0],\n            [-1, -1],\n            [17, 21],\n            [3, 0]\n        ]\n    },\n    'Y': {\n        width: 18, points: [\n            [1, 21],\n            [9, 11],\n            [9, 0],\n            [-1, -1],\n            [17, 21],\n            [9, 11]\n        ]\n    },\n    'Z': {\n        width: 20, points: [\n            [17, 21],\n            [3, 0],\n            [-1, -1],\n            [3, 21],\n            [17, 21],\n            [-1, -1],\n            [3, 0],\n            [17, 0]\n        ]\n    },\n    '[': {\n        width: 14, points: [\n            [4, 25],\n            [4, -7],\n            [-1, -1],\n            [5, 25],\n            [5, -7],\n            [-1, -1],\n            [4, 25],\n            [11, 25],\n            [-1, -1],\n            [4, -7],\n            [11, -7]\n        ]\n    },\n    '\\\\': {\n        width: 14, points: [\n            [0, 21],\n            [14, -3]\n        ]\n    },\n    ']': {\n        width: 14, points: [\n            [9, 25],\n            [9, -7],\n            [-1, -1],\n            [10, 25],\n            [10, -7],\n            [-1, -1],\n            [3, 25],\n            [10, 25],\n            [-1, -1],\n            [3, -7],\n            [10, -7]\n        ]\n    },\n    '^': {\n        width: 16, points: [\n            [6, 15],\n            [8, 18],\n            [10, 15],\n            [-1, -1],\n            [3, 12],\n            [8, 17],\n            [13, 12],\n            [-1, -1],\n            [8, 17],\n            [8, 0]\n        ]\n    },\n    '_': {\n        width: 16, points: [\n            [0, -2],\n            [16, -2]\n        ]\n    },\n    '`': {\n        width: 10, points: [\n            [6, 21],\n            [5, 20],\n            [4, 18],\n            [4, 16],\n            [5, 15],\n            [6, 16],\n            [5, 17]\n        ]\n    },\n    'a': {\n        width: 19, points: [\n            [15, 14],\n            [15, 0],\n            [-1, -1],\n            [15, 11],\n            [13, 13],\n            [11, 14],\n            [8, 14],\n            [6, 13],\n            [4, 11],\n            [3, 8],\n            [3, 6],\n            [4, 3],\n            [6, 1],\n            [8, 0],\n            [11, 0],\n            [13, 1],\n            [15, 3]\n        ]\n    },\n    'b': {\n        width: 19, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 11],\n            [6, 13],\n            [8, 14],\n            [11, 14],\n            [13, 13],\n            [15, 11],\n            [16, 8],\n            [16, 6],\n            [15, 3],\n            [13, 1],\n            [11, 0],\n            [8, 0],\n            [6, 1],\n            [4, 3]\n        ]\n    },\n    'c': {\n        width: 18, points: [\n            [15, 11],\n            [13, 13],\n            [11, 14],\n            [8, 14],\n            [6, 13],\n            [4, 11],\n            [3, 8],\n            [3, 6],\n            [4, 3],\n            [6, 1],\n            [8, 0],\n            [11, 0],\n            [13, 1],\n            [15, 3]\n        ]\n    },\n    'd': {\n        width: 19, points: [\n            [15, 21],\n            [15, 0],\n            [-1, -1],\n            [15, 11],\n            [13, 13],\n            [11, 14],\n            [8, 14],\n            [6, 13],\n            [4, 11],\n            [3, 8],\n            [3, 6],\n            [4, 3],\n            [6, 1],\n            [8, 0],\n            [11, 0],\n            [13, 1],\n            [15, 3]\n        ]\n    },\n    'e': {\n        width: 18, points: [\n            [3, 8],\n            [15, 8],\n            [15, 10],\n            [14, 12],\n            [13, 13],\n            [11, 14],\n            [8, 14],\n            [6, 13],\n            [4, 11],\n            [3, 8],\n            [3, 6],\n            [4, 3],\n            [6, 1],\n            [8, 0],\n            [11, 0],\n            [13, 1],\n            [15, 3]\n        ]\n    },\n    'f': {\n        width: 12, points: [\n            [10, 21],\n            [8, 21],\n            [6, 20],\n            [5, 17],\n            [5, 0],\n            [-1, -1],\n            [2, 14],\n            [9, 14]\n        ]\n    },\n    'g': {\n        width: 19, points: [\n            [15, 14],\n            [15, -2],\n            [14, -5],\n            [13, -6],\n            [11, -7],\n            [8, -7],\n            [6, -6],\n            [-1, -1],\n            [15, 11],\n            [13, 13],\n            [11, 14],\n            [8, 14],\n            [6, 13],\n            [4, 11],\n            [3, 8],\n            [3, 6],\n            [4, 3],\n            [6, 1],\n            [8, 0],\n            [11, 0],\n            [13, 1],\n            [15, 3]\n        ]\n    },\n    'h': {\n        width: 19, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [4, 10],\n            [7, 13],\n            [9, 14],\n            [12, 14],\n            [14, 13],\n            [15, 10],\n            [15, 0]\n        ]\n    },\n    'i': {\n        width: 8, points: [\n            [3, 21],\n            [4, 20],\n            [5, 21],\n            [4, 22],\n            [3, 21],\n            [-1, -1],\n            [4, 14],\n            [4, 0]\n        ]\n    },\n    'j': {\n        width: 10, points: [\n            [5, 21],\n            [6, 20],\n            [7, 21],\n            [6, 22],\n            [5, 21],\n            [-1, -1],\n            [6, 14],\n            [6, -3],\n            [5, -6],\n            [3, -7],\n            [1, -7]\n        ]\n    },\n    'k': {\n        width: 17, points: [\n            [4, 21],\n            [4, 0],\n            [-1, -1],\n            [14, 14],\n            [4, 4],\n            [-1, -1],\n            [8, 8],\n            [15, 0]\n        ]\n    },\n    'l': {\n        width: 8, points: [\n            [4, 21],\n            [4, 0]\n        ]\n    },\n    'm': {\n        width: 30, points: [\n            [4, 14],\n            [4, 0],\n            [-1, -1],\n            [4, 10],\n            [7, 13],\n            [9, 14],\n            [12, 14],\n            [14, 13],\n            [15, 10],\n            [15, 0],\n            [-1, -1],\n            [15, 10],\n            [18, 13],\n            [20, 14],\n            [23, 14],\n            [25, 13],\n            [26, 10],\n            [26, 0]\n        ]\n    },\n    'n': {\n        width: 19, points: [\n            [4, 14],\n            [4, 0],\n            [-1, -1],\n            [4, 10],\n            [7, 13],\n            [9, 14],\n            [12, 14],\n            [14, 13],\n            [15, 10],\n            [15, 0]\n        ]\n    },\n    'o': {\n        width: 19, points: [\n            [8, 14],\n            [6, 13],\n            [4, 11],\n            [3, 8],\n            [3, 6],\n            [4, 3],\n            [6, 1],\n            [8, 0],\n            [11, 0],\n            [13, 1],\n            [15, 3],\n            [16, 6],\n            [16, 8],\n            [15, 11],\n            [13, 13],\n            [11, 14],\n            [8, 14]\n        ]\n    },\n    'p': {\n        width: 19, points: [\n            [4, 14],\n            [4, -7],\n            [-1, -1],\n            [4, 11],\n            [6, 13],\n            [8, 14],\n            [11, 14],\n            [13, 13],\n            [15, 11],\n            [16, 8],\n            [16, 6],\n            [15, 3],\n            [13, 1],\n            [11, 0],\n            [8, 0],\n            [6, 1],\n            [4, 3]\n        ]\n    },\n    'q': {\n        width: 19, points: [\n            [15, 14],\n            [15, -7],\n            [-1, -1],\n            [15, 11],\n            [13, 13],\n            [11, 14],\n            [8, 14],\n            [6, 13],\n            [4, 11],\n            [3, 8],\n            [3, 6],\n            [4, 3],\n            [6, 1],\n            [8, 0],\n            [11, 0],\n            [13, 1],\n            [15, 3]\n        ]\n    },\n    'r': {\n        width: 13, points: [\n            [4, 14],\n            [4, 0],\n            [-1, -1],\n            [4, 8],\n            [5, 11],\n            [7, 13],\n            [9, 14],\n            [12, 14]\n        ]\n    },\n    's': {\n        width: 17, points: [\n            [14, 11],\n            [13, 13],\n            [10, 14],\n            [7, 14],\n            [4, 13],\n            [3, 11],\n            [4, 9],\n            [6, 8],\n            [11, 7],\n            [13, 6],\n            [14, 4],\n            [14, 3],\n            [13, 1],\n            [10, 0],\n            [7, 0],\n            [4, 1],\n            [3, 3]\n        ]\n    },\n    't': {\n        width: 12, points: [\n            [5, 21],\n            [5, 4],\n            [6, 1],\n            [8, 0],\n            [10, 0],\n            [-1, -1],\n            [2, 14],\n            [9, 14]\n        ]\n    },\n    'u': {\n        width: 19, points: [\n            [4, 14],\n            [4, 4],\n            [5, 1],\n            [7, 0],\n            [10, 0],\n            [12, 1],\n            [15, 4],\n            [-1, -1],\n            [15, 14],\n            [15, 0]\n        ]\n    },\n    'v': {\n        width: 16, points: [\n            [2, 14],\n            [8, 0],\n            [-1, -1],\n            [14, 14],\n            [8, 0]\n        ]\n    },\n    'w': {\n        width: 22, points: [\n            [3, 14],\n            [7, 0],\n            [-1, -1],\n            [11, 14],\n            [7, 0],\n            [-1, -1],\n            [11, 14],\n            [15, 0],\n            [-1, -1],\n            [19, 14],\n            [15, 0]\n        ]\n    },\n    'x': {\n        width: 17, points: [\n            [3, 14],\n            [14, 0],\n            [-1, -1],\n            [14, 14],\n            [3, 0]\n        ]\n    },\n    'y': {\n        width: 16, points: [\n            [2, 14],\n            [8, 0],\n            [-1, -1],\n            [14, 14],\n            [8, 0],\n            [6, -4],\n            [4, -6],\n            [2, -7],\n            [1, -7]\n        ]\n    },\n    'z': {\n        width: 17, points: [\n            [14, 14],\n            [3, 0],\n            [-1, -1],\n            [3, 14],\n            [14, 14],\n            [-1, -1],\n            [3, 0],\n            [14, 0]\n        ]\n    },\n    '{': {\n        width: 14, points: [\n            [9, 25],\n            [7, 24],\n            [6, 23],\n            [5, 21],\n            [5, 19],\n            [6, 17],\n            [7, 16],\n            [8, 14],\n            [8, 12],\n            [6, 10],\n            [-1, -1],\n            [7, 24],\n            [6, 22],\n            [6, 20],\n            [7, 18],\n            [8, 17],\n            [9, 15],\n            [9, 13],\n            [8, 11],\n            [4, 9],\n            [8, 7],\n            [9, 5],\n            [9, 3],\n            [8, 1],\n            [7, 0],\n            [6, -2],\n            [6, -4],\n            [7, -6],\n            [-1, -1],\n            [6, 8],\n            [8, 6],\n            [8, 4],\n            [7, 2],\n            [6, 1],\n            [5, -1],\n            [5, -3],\n            [6, -5],\n            [7, -6],\n            [9, -7]\n        ]\n    },\n    '|': {\n        width: 8, points: [\n            [4, 25],\n            [4, -7]\n        ]\n    },\n    '}': {\n        width: 14, points: [\n            [5, 25],\n            [7, 24],\n            [8, 23],\n            [9, 21],\n            [9, 19],\n            [8, 17],\n            [7, 16],\n            [6, 14],\n            [6, 12],\n            [8, 10],\n            [-1, -1],\n            [7, 24],\n            [8, 22],\n            [8, 20],\n            [7, 18],\n            [6, 17],\n            [5, 15],\n            [5, 13],\n            [6, 11],\n            [10, 9],\n            [6, 7],\n            [5, 5],\n            [5, 3],\n            [6, 1],\n            [7, 0],\n            [8, -2],\n            [8, -4],\n            [7, -6],\n            [-1, -1],\n            [8, 8],\n            [6, 6],\n            [6, 4],\n            [7, 2],\n            [8, 1],\n            [9, -1],\n            [9, -3],\n            [8, -5],\n            [7, -6],\n            [5, -7]\n        ]\n    },\n    '~': {\n        width: 24, points: [\n            [3, 6],\n            [3, 8],\n            [4, 11],\n            [6, 12],\n            [8, 12],\n            [10, 11],\n            [14, 8],\n            [16, 7],\n            [18, 7],\n            [20, 8],\n            [21, 10],\n            [-1, -1],\n            [3, 8],\n            [4, 10],\n            [6, 11],\n            [8, 11],\n            [10, 10],\n            [14, 7],\n            [16, 6],\n            [18, 6],\n            [20, 7],\n            [21, 10],\n            [21, 12]\n        ]\n    }\n};\n\n/**\n * @desc Creates wireframe vector text {@link Geometry}.\n *\n * ## Usage\n *\n * Creating a {@link Mesh} with vector text {@link ReadableGeometry} :\n *\n * [[Run this example](/examples/index.html#geometry_builders_buildVectorTextGeometry)]\n *\n * ````javascript\n *\n * import {Viewer, Mesh, buildVectorTextGeometry, ReadableGeometry, PhongMaterial} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [0, 0, 100];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildVectorTextGeometry({\n *          origin: [0,0,0],\n *          text: \"On the other side of the screen, it all looked so easy\"\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *         diffuseMap: new Texture(viewer.scene, {\n *             src: \"textures/diffuse/uvGrid2.jpg\"\n *         })\n *      })\n * });\n * ````\n *\n * @function buildVectorTextGeometry\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number[]} [cfg.center]  3D point indicating the center position.\n * @param {Number[]} [cfg.origin] 3D point indicating the top left corner.\n * @param {Number} [cfg.size=1] Size of each character.\n * @param {String} [cfg.text=\"\"] The text.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildVectorTextGeometry(cfg = {}) {\n\n    var origin = cfg.origin || [0, 0, 0];\n    var xOrigin = origin[0];\n    var yOrigin = origin[1];\n    var zOrigin = origin[2];\n    var size = cfg.size || 1;\n\n    var positions = [];\n    var indices = [];\n    var text = cfg.text;\n    if (utils.isNumeric(text)) {\n        text = \"\" + text;\n    }\n    var lines = (text || \"\").split(\"\\n\");\n    var countVerts = 0;\n    var y = 0;\n    var x;\n    var str;\n    var len;\n    var c;\n    var mag = 1.0 / 25.0;\n    var penUp;\n    var p1;\n    var p2;\n    var pointsLen;\n    var a;\n\n    for (var iLine = 0; iLine < lines.length; iLine++) {\n\n        x = 0;\n        str = lines[iLine];\n        len = str.length;\n\n        for (var i = 0; i < len; i++) {\n\n            c = letters[str.charAt(i)];\n\n            if (!c) {\n                continue;\n            }\n\n            penUp = 1;\n            p1 = -1;\n            p2 = -1;\n\n            pointsLen = c.points.length;\n\n            for (var j = 0; j < pointsLen; j++) {\n                a = c.points[j];\n\n                if (a[0] === -1 && a[1] === -1) {\n                    penUp = 1;\n                    continue;\n                }\n\n                positions.push((x + (a[0] * size) * mag) + xOrigin);\n                positions.push((y + (a[1] * size) * mag) + yOrigin);\n                positions.push(0 + zOrigin);\n\n                if (p1 === -1) {\n                    p1 = countVerts;\n                } else if (p2 === -1) {\n                    p2 = countVerts;\n                } else {\n                    p1 = p2;\n                    p2 = countVerts;\n                }\n                countVerts++;\n\n                if (penUp) {\n                    penUp = false;\n\n                } else {\n                    indices.push(p1);\n                    indices.push(p2);\n                }\n            }\n            x += c.width * mag * size;\n\n        }\n        y -= 35 * mag * size;\n    }\n\n    return utils.apply(cfg, {\n        primitive: \"lines\",\n        positions: positions,\n        indices: indices\n    });\n}\n\n/**\n * @desc Creates a 3D polyline {@link Geometry}.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with a polyline {@link ReadableGeometry} that has lines primitives.\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#buildPolylineGeometry)]\n *\n * ````javascript\n * //------------------------------------------------------------------------------------------------------------------\n * // Import the modules we need for this example\n * //------------------------------------------------------------------------------------------------------------------\n *\n * import {buildPolylineGeometry, Viewer, Mesh, ReadableGeometry, PhongMaterial} from \"../../dist/xeokit-sdk.min.es.js\";\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a Viewer and arrange the camera\n * //------------------------------------------------------------------------------------------------------------------\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [0, 0, 8];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with polyline shape\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildPolylineGeometry({\n *         points: [\n *             0, 2.83654, 0,\n *             -0.665144, 1.152063, 0,\n *             -2.456516, 1.41827, 0,\n *             -1.330288, 0, 0,\n *             -2.456516, -1.41827, 0,\n *             -0.665144, -1.152063, 0,\n *             0, -2.83654, 0,\n *             0.665144, -1.152063, 0,\n *             2.456516, -1.41827, 0,\n *             1.330288, 0, 0,\n *             2.456516, 1.41827, 0,\n *             0.665144, 1.152063, 0,\n *             0, 2.83654, 0,\n *         ]\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 1,]\n *     })\n * });\n * ````\n *\n * @function buildPolylineGeometry\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number[]} [cfg.points]  3D points indicating vertices position.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildPolylineGeometry(cfg = {}) {\n\n    if (cfg.points.length % 3 !== 0) {\n        throw \"Size of points array for given polyline should be divisible by 3\";\n    }\n    let numberOfPoints = cfg.points.length / 3;\n    if (numberOfPoints < 2) {\n        throw \"There should be at least 2 points to create a polyline\";\n    }\n    let indices = [];\n    for (let i = 0; i < numberOfPoints - 1; i++) {\n        indices.push(i);\n        indices.push(i + 1);\n    }\n\n    return utils.apply(cfg, {\n        primitive: \"lines\",\n        positions: cfg.points,\n        indices: indices,\n    });\n}\n\n/**\n * @desc Creates a 3D polyline from curve {@link Geometry}.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with a polyline {@link ReadableGeometry} created from curves.\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#buildPolylineGeometryFromCurve)]\n *\n * ````javascript\n * //------------------------------------------------------------------------------------------------------------------\n * // Import the modules we need for this example\n * //------------------------------------------------------------------------------------------------------------------\n *\n * import {buildPolylineGeometryFromCurve, Viewer, Mesh, PhongMaterial, NavCubePlugin, CubicBezierCurve, SplineCurve, QuadraticBezierCurve, ReadableGeometry} from \"../../dist/xeokit-sdk.min.es.js\";\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a Viewer and arrange the camera\n * //------------------------------------------------------------------------------------------------------------------\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * new NavCubePlugin(viewer, {\n *     canvasId: \"myNavCubeCanvas\",\n *     visible: true,\n *     size: 250,\n *     alignment: \"bottomRight\",\n *     bottomMargin: 100,\n *     rightMargin: 10\n * });\n *\n * viewer.camera.eye = [0, -250, 1];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with polyline shape from Spline\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildPolylineGeometryFromCurve({\n *         id: \"SplineCurve\",\n *         curve: new SplineCurve(viewer.scene, {\n *             points: [\n *                 [-65.77614, 0, -88.881992],\n *                 [90.020852, 0, -61.589088],\n *                 [-67.766247, 0, -22.071238],\n *                 [93.148164, 0, -13.826507],\n *                 [-14.033343, 0, 3.231558],\n *                 [32.592034, 0, 9.20188],\n *                 [3.309023, 0, 22.848332],\n *                 [23.210098, 0, 28.818655],\n *             ],\n *         }),\n *         divisions: 100,\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [1, 0, 0]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with polyline shape from CubicBezier\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildPolylineGeometryFromCurve({\n *         id: \"CubicBezierCurve\",\n *         curve: new CubicBezierCurve(viewer.scene, {\n *             v0: [120, 0, 100],\n *             v1: [120, 0, 0],\n *             v2: [80, 0, 100],\n *             v3: [80, 0, 0],\n *         }),\n *         divisions: 50,\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 1, 0]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with polyline shape from QuadraticBezier\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildPolylineGeometryFromCurve({\n *         id: \"QuadraticBezierCurve\",\n *         curve: new QuadraticBezierCurve(viewer.scene, {\n *             v0: [-100, 0, 100],\n *             v1: [-50, 0, 150],\n *             v2: [-50, 0, 0],\n *         }),\n *         divisions: 20,\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 0, 1]\n *     })\n * });\n * ````\n *\n * @function buildPolylineGeometryFromCurve\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Object} [cfg.curve]  Curve for which polyline will be created.\n * @param {Number} [cfg.divisions]  The number of divisions.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildPolylineGeometryFromCurve(cfg = {}) {\n\n    let polylinePoints = cfg.curve.getPoints(cfg.divisions).map(a => [...a]).flat();\n    return buildPolylineGeometry({\n        id: cfg.id,\n        points: polylinePoints\n    });\n}\n\n/**\n * @desc Creates a 3D line {@link Geometry}.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with a line {@link ReadableGeometry}.\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#buildLineGeometry)]\n *\n * ````javascript\n * //------------------------------------------------------------------------------------------------------------------\n * // Import the modules we need for this example\n * //------------------------------------------------------------------------------------------------------------------\n *\n * import {buildLineGeometry, Viewer, Mesh, ReadableGeometry, PhongMaterial} from \"../../dist/xeokit-sdk.min.es.js\";\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a Viewer and arrange the camera\n * //------------------------------------------------------------------------------------------------------------------\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [0, 0, 8];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with simple 2d line shape\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildLineGeometry({\n *         startPoint: [-5,-2,0],\n *         endPoint: [-5,2,0],\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 1,]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with simple 2d line shape with black color\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildLineGeometry({\n *         startPoint: [-4,-2,0],\n *         endPoint: [-4,2,0],\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 0, 0]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with simple 2d line shape with black color and simple pattern\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildLineGeometry({\n *         startPoint: [-3,-2,0],\n *         endPoint: [-3,2,0],\n *         pattern: [0.10],\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 0, 0]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with simple 2d line shape with blue color and simple pattern extended to end\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildLineGeometry({\n *         startPoint: [-2,-2,0],\n *         endPoint: [-2,2,0],\n *         pattern: [0.10],\n *         extendToEnd: true,\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 0, 1]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with simple 2d line shape with black color and more complex pattern\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildLineGeometry({\n *         startPoint: [-1,-2,0],\n *         endPoint: [-1,2,0],\n *         pattern: [0.15, 0.05],\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 0, 0]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with simple 2d line shape with blue color and more complex pattern extended to end\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildLineGeometry({\n *         startPoint: [0,-2,0],\n *         endPoint: [0,2,0],\n *         pattern: [0.15, 0.05],\n *         extendToEnd: true,\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 0, 1]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with simple 2d line shape with black color and complex pattern\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildLineGeometry({\n *         startPoint: [1,-2,0],\n *         endPoint: [1,2,0],\n *         pattern: [0.15, 0.05, 0.50],\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 0, 0]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with simple 2d line shape with blue color and complex pattern extended to end\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildLineGeometry({\n *         startPoint: [2,-2,0],\n *         endPoint: [2,2,0],\n *         pattern: [0.15, 0.05, 0.50],\n *         extendToEnd: true,\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 0, 1]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with simple 3d line shape with white color and simple pattern\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildLineGeometry({\n *         startPoint: [3,-2,-1],\n *         endPoint: [5,2,1],\n *         pattern: [0.10],\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [1, 1, 1]\n *     })\n * });\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a mesh with simple 3d line shape with black color and simple dot pattern\n * //------------------------------------------------------------------------------------------------------------------\n *\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildLineGeometry({\n *         startPoint: [5,-2,-1],\n *         endPoint: [7,2,1],\n *         pattern: [0.03],\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *         emissive: [0, 0, 0]\n *     })\n * });\n * ````\n *\n * @function buildLineGeometry\n * @param {*} [cfg] Configs\n * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n * @param {Number[]} [cfg.startPoint]  3D start point (x0, y0, z0).\n * @param {Number[]} [cfg.endPoint]  3D end point (x1, y1, z1).\n * @param {Number[]} [cfg.pattern] Lengths of segments that describe a pattern.\n * @param {Bool} [cfg.extendToEnd] If true: it will try to make sure the line doesn't end up with a gap, as it will\n * extend the last segment.\n * @returns {Object} Configuration for a {@link Geometry} subtype.\n */\nfunction buildLineGeometry(cfg = {}) {\n\n    if (cfg.startPoint.length !== 3) {\n        throw \"Start point should contain 3 elements in array: x, y and z\";\n    }\n    if (cfg.endPoint.length !== 3) {\n        throw \"End point should contain 3 elements in array: x, y and z\";\n    }\n    let indices = [];\n    let points = [];\n    let x0 = cfg.startPoint[0]; let y0 = cfg.startPoint[1]; let z0 = cfg.startPoint[2];\n    let x1 = cfg.endPoint[0]; let y1 = cfg.endPoint[1]; let z1 = cfg.endPoint[2];\n    let lineLength = Math.sqrt((x1- x0)**2 + (y1 - y0)**2 + (z1 - z0)**2);\n    let normalizedDirectionVectorOfLine = [(x1-x0)/lineLength, (y1-y0)/lineLength, (z1-z0)/lineLength];\n\n    if (!cfg.pattern) {\n        indices.push(0);\n        indices.push(1);\n        points.push(x0, y0, z0, x1, y1, z1);\n    }\n    else {\n        let patternsNumber = cfg.pattern.length;\n        let gap = false;\n        let segmentFilled = 0.0;\n        let idOfCurrentPatternLength = 0;\n        let pointIndicesCounter = 0;\n        let currentStartPoint = [x0, y0, z0];\n        let currentPatternLength = cfg.pattern[idOfCurrentPatternLength];\n        points.push(currentStartPoint[0], currentStartPoint[1], currentStartPoint[2]);\n\n        while (currentPatternLength <= (lineLength - segmentFilled)) {\n            let vectorFromCurrentStartPointToCurrentEndPoint = [\n                normalizedDirectionVectorOfLine[0] * currentPatternLength,\n                normalizedDirectionVectorOfLine[1] * currentPatternLength,\n                normalizedDirectionVectorOfLine[2] * currentPatternLength,\n            ];\n            let currentEndPoint = [\n                currentStartPoint[0] + vectorFromCurrentStartPointToCurrentEndPoint[0],\n                currentStartPoint[1] + vectorFromCurrentStartPointToCurrentEndPoint[1],\n                currentStartPoint[2] + vectorFromCurrentStartPointToCurrentEndPoint[2],\n            ];\n\n            points.push(currentEndPoint[0], currentEndPoint[1], currentEndPoint[2]);\n\n            if (!gap) {\n                indices.push(pointIndicesCounter);\n                indices.push(pointIndicesCounter + 1);\n            }\n            gap = !gap;\n\n            pointIndicesCounter += 1;\n            currentStartPoint = currentEndPoint;\n            idOfCurrentPatternLength += 1;\n            if (idOfCurrentPatternLength >= patternsNumber) {\n                idOfCurrentPatternLength = 0;\n            }\n            segmentFilled += currentPatternLength;\n            currentPatternLength = cfg.pattern[idOfCurrentPatternLength];\n        }\n\n        if (cfg.extendToEnd) {\n            points.push(x1, y1, z1);\n            indices.push(indices.length - 2);\n            indices.push(indices.length - 1);\n        }\n    }\n\n    return utils.apply(cfg, {\n        primitive: \"lines\",\n        positions: points,\n        indices: indices,\n    });\n}\n\nconst angleAxis$2 = math.vec4(4);\nconst q1$2 = math.vec4();\nconst q2$2 = math.vec4();\nconst xAxis$2 = math.vec3([1, 0, 0]);\nconst yAxis$2 = math.vec3([0, 1, 0]);\nconst zAxis$2 = math.vec3([0, 0, 1]);\n\nconst veca$1 = math.vec3(3);\nconst vecb$1 = math.vec3(3);\n\nconst identityMat$2 = math.identityMat4();\n\n/**\n * @desc An {@link Entity} that is a scene graph node that can have child Nodes and {@link Mesh}es.\n *\n * ## Usage\n *\n * The example below is the same as the one given for {@link Mesh}, since the two classes work together. In this example,\n * we'll create a scene graph in which a root Node represents a group and the {@link Mesh}s are leaves. Since Node\n * implements {@link Entity}, we can designate the root Node as a model, causing it to be registered by its ID in {@link Scene#models}.\n *\n * Since {@link Mesh} also implements {@link Entity}, we can designate the leaf {@link Mesh}es as objects, causing them to\n * be registered by their IDs in {@link Scene#objects}.\n *\n * We can then find those {@link Entity} types in {@link Scene#models} and {@link Scene#objects}.\n *\n * We can also update properties of our object-Meshes via calls to {@link Scene#setObjectsHighlighted} etc.\n *\n * [[Run this example](/examples/index.html#sceneRepresentation_SceneGraph)]\n *\n * ````javascript\n * import {Viewer, Mesh, Node, PhongMaterial} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * new Node(viewer.scene, {\n *      id: \"table\",\n *      isModel: true, // <---------- Node represents a model, so is registered by ID in viewer.scene.models\n *      rotation: [0, 50, 0],\n *      position: [0, 0, 0],\n *      scale: [1, 1, 1],\n *\n *      children: [\n *\n *          new Mesh(viewer.scene, { // Red table leg\n *              id: \"redLeg\",\n *              isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n *              position: [-4, -6, -4],\n *              scale: [1, 3, 1],\n *              rotation: [0, 0, 0],\n *              material: new PhongMaterial(viewer.scene, {\n *                  diffuse: [1, 0.3, 0.3]\n *              })\n *          }),\n *\n *          new Mesh(viewer.scene, { // Green table leg\n *              id: \"greenLeg\",\n *              isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n *              position: [4, -6, -4],\n *              scale: [1, 3, 1],\n *              rotation: [0, 0, 0],\n *              material: new PhongMaterial(viewer.scene, {\n *                  diffuse: [0.3, 1.0, 0.3]\n *              })\n *          }),\n *\n *          new Mesh(viewer.scene, {// Blue table leg\n *              id: \"blueLeg\",\n *              isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n *              position: [4, -6, 4],\n *              scale: [1, 3, 1],\n *              rotation: [0, 0, 0],\n *              material: new PhongMaterial(viewer.scene, {\n *                  diffuse: [0.3, 0.3, 1.0]\n *              })\n *          }),\n *\n *          new Mesh(viewer.scene, {  // Yellow table leg\n *              id: \"yellowLeg\",\n *              isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n *              position: [-4, -6, 4],\n *              scale: [1, 3, 1],\n *              rotation: [0, 0, 0],\n *              material: new PhongMaterial(viewer.scene, {\n *                   diffuse: [1.0, 1.0, 0.0]\n *              })\n *          }),\n *\n *          new Mesh(viewer.scene, { // Purple table top\n *              id: \"tableTop\",\n *              isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n *              position: [0, -3, 0],\n *              scale: [6, 0.5, 6],\n *              rotation: [0, 0, 0],\n *              material: new PhongMaterial(viewer.scene, {\n *                  diffuse: [1.0, 0.3, 1.0]\n *              })\n *          })\n *      ]\n *  });\n *\n * // Find Nodes and Meshes by their IDs\n *\n * var table = viewer.scene.models[\"table\"];                // Since table Node has isModel == true\n *\n * var redLeg = viewer.scene.objects[\"redLeg\"];             // Since the Meshes have isObject == true\n * var greenLeg = viewer.scene.objects[\"greenLeg\"];\n * var blueLeg = viewer.scene.objects[\"blueLeg\"];\n *\n * // Highlight one of the table leg Meshes\n *\n * viewer.scene.setObjectsHighlighted([\"redLeg\"], true);    // Since the Meshes have isObject == true\n *\n * // Periodically update transforms on our Nodes and Meshes\n *\n * viewer.scene.on(\"tick\", function () {\n *\n *       // Rotate legs\n *       redLeg.rotateY(0.5);\n *       greenLeg.rotateY(0.5);\n *       blueLeg.rotateY(0.5);\n *\n *       // Rotate table\n *       table.rotateY(0.5);\n *       table.rotateX(0.3);\n *   });\n * ````\n *\n * ## Metadata\n *\n * As mentioned, we can also associate {@link MetaModel}s and {@link MetaObject}s with our Nodes and {@link Mesh}es,\n * within a {@link MetaScene}. See {@link MetaScene} for an example.\n *\n * @implements {Entity}\n */\nclass Node$1 extends Component {\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent scene, generated automatically when omitted.\n     * @param {Boolean} [cfg.isModel] Specify ````true```` if this Mesh represents a model, in which case the Mesh will be registered by {@link Mesh#id} in {@link Scene#models} and may also have a corresponding {@link MetaModel} with matching {@link MetaModel#id}, registered by that ID in {@link MetaScene#metaModels}.\n     * @param {Boolean} [cfg.isObject] Specify ````true```` if this Mesh represents an object, in which case the Mesh will be registered by {@link Mesh#id} in {@link Scene#objects} and may also have a corresponding {@link MetaObject} with matching {@link MetaObject#id}, registered by that ID in {@link MetaScene#metaObjects}.\n     * @param {Node} [cfg.parent] The parent Node.\n     * @param {Number[]} [cfg.origin] World-space origin for this Node.\n     * @param {Number[]} [cfg.rtcCenter] Deprecated - renamed to ````origin````.\n     * @param {Number[]} [cfg.position=[0,0,0]] Local 3D position.\n     * @param {Number[]} [cfg.scale=[1,1,1]] Local scale.\n     * @param {Number[]} [cfg.rotation=[0,0,0]] Local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] Local modelling transform matrix. Overrides the position, scale and rotation parameters.\n     * @param {Number[]} [cfg.offset=[0,0,0]] World-space 3D translation offset. Translates the Node in World space, after modelling transforms.\n     * @param {Boolean} [cfg.visible=true] Indicates if the Node is initially visible.\n     * @param {Boolean} [cfg.culled=false] Indicates if the Node is initially culled from view.\n     * @param {Boolean} [cfg.pickable=true] Indicates if the Node is initially pickable.\n     * @param {Boolean} [cfg.clippable=true] Indicates if the Node is initially clippable.\n     * @param {Boolean} [cfg.collidable=true] Indicates if the Node is initially included in boundary calculations.\n     * @param {Boolean} [cfg.castsShadow=true] Indicates if the Node initially casts shadows.\n     * @param {Boolean} [cfg.receivesShadow=true]  Indicates if the Node initially receives shadows.\n     * @param {Boolean} [cfg.xrayed=false] Indicates if the Node is initially xrayed.\n     * @param {Boolean} [cfg.highlighted=false] Indicates if the Node is initially highlighted.\n     * @param {Boolean} [cfg.selected=false] Indicates if the Mesh is initially selected.\n     * @param {Boolean} [cfg.edges=false] Indicates if the Node's edges are initially emphasized.\n     * @param {Number[]} [cfg.colorize=[1.0,1.0,1.0]] Node's initial RGB colorize color, multiplies by the rendered fragment colors.\n     * @param {Number} [cfg.opacity=1.0] Node's initial opacity factor, multiplies by the rendered fragment alpha.\n     * @param {Array} [cfg.children] Child Nodes or {@link Mesh}es to add initially. Children must be in the same {@link Scene} and will be removed first from whatever parents they may already have.\n     * @param {Boolean} [cfg.inheritStates=true] Indicates if children given to this constructor should inherit rendering state from this parent as they are added. Rendering state includes {@link Node#visible}, {@link Node#culled}, {@link Node#pickable}, {@link Node#clippable}, {@link Node#castsShadow}, {@link Node#receivesShadow}, {@link Node#selected}, {@link Node#highlighted}, {@link Node#colorize} and {@link Node#opacity}.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._parentNode = null;\n        this._children = [];\n\n        this._aabb = null;\n        this._aabbDirty = true;\n\n        this.scene._aabbDirty = true;\n\n        this._numTriangles = 0;\n\n        this._scale = math.vec3();\n        this._quaternion = math.identityQuaternion();\n        this._rotation = math.vec3();\n        this._position = math.vec3();\n        this._offset = math.vec3();\n\n        this._localMatrix = math.identityMat4();\n        this._worldMatrix = math.identityMat4();\n\n        this._localMatrixDirty = true;\n        this._worldMatrixDirty = true;\n\n        if (cfg.matrix) {\n            this.matrix = cfg.matrix;\n        } else {\n            this.scale = cfg.scale;\n            this.position = cfg.position;\n            if (cfg.quaternion) ; else {\n                this.rotation = cfg.rotation;\n            }\n        }\n\n        this._isModel = cfg.isModel;\n        if (this._isModel) {\n            this.scene._registerModel(this);\n        }\n\n        this._isObject = cfg.isObject;\n        if (this._isObject) {\n            this.scene._registerObject(this);\n        }\n\n        this.origin = cfg.origin;\n        this.visible = cfg.visible;\n        this.culled = cfg.culled;\n        this.pickable = cfg.pickable;\n        this.clippable = cfg.clippable;\n        this.collidable = cfg.collidable;\n        this.castsShadow = cfg.castsShadow;\n        this.receivesShadow = cfg.receivesShadow;\n        this.xrayed = cfg.xrayed;\n        this.highlighted = cfg.highlighted;\n        this.selected = cfg.selected;\n        this.edges = cfg.edges;\n        this.colorize = cfg.colorize;\n        this.opacity = cfg.opacity;\n        this.offset = cfg.offset;\n\n        // Add children, which inherit state from this Node\n\n        if (cfg.children) {\n            const children = cfg.children;\n            for (let i = 0, len = children.length; i < len; i++) {\n                this.addChild(children[i], cfg.inheritStates);\n            }\n        }\n\n        if (cfg.parentId) {\n            const parentNode = this.scene.components[cfg.parentId];\n            if (!parentNode) {\n                this.error(\"Parent not found: '\" + cfg.parentId + \"'\");\n            } else if (!parentNode.isNode) {\n                this.error(\"Parent is not a Node: '\" + cfg.parentId + \"'\");\n            } else {\n                parentNode.addChild(this);\n            }\n        } else if (cfg.parent) {\n            if (!cfg.parent.isNode) {\n                this.error(\"Parent is not a Node\");\n            }\n            cfg.parent.addChild(this);\n        }\n    }\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Entity members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns true to indicate that this Component is an Entity.\n     * @type {Boolean}\n     */\n    get isEntity() {\n        return true;\n    }\n\n    /**\n     * Returns ````true```` if this Mesh represents a model.\n     *\n     * When this returns ````true````, the Mesh will be registered by {@link Mesh#id} in {@link Scene#models} and\n     * may also have a corresponding {@link MetaModel}.\n     *\n     * @type {Boolean}\n     */\n    get isModel() {\n        return this._isModel;\n    }\n\n    /**\n     * Returns ````true```` if this Node represents an object.\n     *\n     * When ````true```` the Node will be registered by {@link Node#id} in\n     * {@link Scene#objects} and may also have a {@link MetaObject} with matching {@link MetaObject#id}.\n     *\n     * @type {Boolean}\n     * @abstract\n     */\n    get isObject() {\n        return this._isObject;\n    }\n\n    /**\n     * Gets the Node's World-space 3D axis-aligned bounding box.\n     *\n     * Represented by a six-element Float64Array containing the min/max extents of the\n     * axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n     *\n     * @type {Number[]}\n     */\n    get aabb() {\n        if (this._aabbDirty) {\n            this._updateAABB();\n        }\n        return this._aabb;\n    }\n\n    /**\n     * Sets the World-space origin for this Node.\n     *\n     * @type {Float64Array}\n     */\n    set origin(origin) {\n        if (origin) {\n            if (!this._origin) {\n                this._origin = math.vec3();\n            }\n            this._origin.set(origin);\n        } else {\n            if (this._origin) {\n                this._origin = null;\n            }\n        }\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].origin = origin;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     *  Gets the World-space origin for this Node.\n     *\n     * @type {Float64Array}\n     */\n    get origin() {\n        return this._origin;\n    }\n\n    /**\n     * Sets the World-space origin for this Node.\n     *\n     * Deprecated and replaced by {@link Node#origin}.\n     *\n     * @deprecated\n     * @type {Float64Array}\n     */\n    set rtcCenter(rtcCenter) {\n        this.origin = rtcCenter;\n    }\n\n    /**\n     * Gets the World-space origin for this Node.\n     *\n     * Deprecated and replaced by {@link Node#origin}.\n     *\n     * @deprecated\n     * @type {Float64Array}\n     */\n    get rtcCenter() {\n        return this.origin;\n    }\n\n    /**\n     * The number of triangles in this Node.\n     *\n     * @type {Number}\n     */\n    get numTriangles() {\n        return this._numTriangles;\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es are visible.\n     *\n     * Only rendered both {@link Node#visible} is ````true```` and {@link Node#culled} is ````false````.\n     *\n     * When {@link Node#isObject} and {@link Node#visible} are both ````true```` the Node will be\n     * registered by {@link Node#id} in {@link Scene#visibleObjects}.\n     *\n     * @type {Boolean}\n     */\n    set visible(visible) {\n        visible = visible !== false;\n        this._visible = visible;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].visible = visible;\n        }\n        if (this._isObject) {\n            this.scene._objectVisibilityUpdated(this, visible);\n        }\n    }\n\n    /**\n     * Gets if this Node is visible.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * When {@link Node#isObject} and {@link Node#visible} are both ````true```` the Node will be\n     * registered by {@link Node#id} in {@link Scene#visibleObjects}.\n     *\n     * @type {Boolean}\n     */\n    get visible() {\n        return this._visible;\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es are xrayed.\n     *\n     * When {@link Node#isObject} and {@link Node#xrayed} are both ````true```` the Node will be\n     * registered by {@link Node#id} in {@link Scene#xrayedObjects}.\n     *\n     * @type {Boolean}\n     */\n    set xrayed(xrayed) {\n        xrayed = !!xrayed;\n        this._xrayed = xrayed;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].xrayed = xrayed;\n        }\n        if (this._isObject) {\n            this.scene._objectXRayedUpdated(this, xrayed);\n        }\n    }\n\n    /**\n     * Gets if this Node is xrayed.\n     *\n     * When {@link Node#isObject} and {@link Node#xrayed} are both ````true```` the Node will be\n     * registered by {@link Node#id} in {@link Scene#xrayedObjects}.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Boolean}\n     */\n    get xrayed() {\n        return this._xrayed;\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es are highlighted.\n     *\n     * When {@link Node#isObject} and {@link Node#highlighted} are both ````true```` the Node will be\n     * registered by {@link Node#id} in {@link Scene#highlightedObjects}.\n     *\n     * @type {Boolean}\n     */\n    set highlighted(highlighted) {\n        highlighted = !!highlighted;\n        this._highlighted = highlighted;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].highlighted = highlighted;\n        }\n        if (this._isObject) {\n            this.scene._objectHighlightedUpdated(this, highlighted);\n        }\n    }\n\n    /**\n     * Gets if this Node is highlighted.\n     *\n     * When {@link Node#isObject} and {@link Node#highlighted} are both ````true```` the Node will be\n     * registered by {@link Node#id} in {@link Scene#highlightedObjects}.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Boolean}\n     */\n    get highlighted() {\n        return this._highlighted;\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es are selected.\n     *\n     * When {@link Node#isObject} and {@link Node#selected} are both ````true```` the Node will be\n     * registered by {@link Node#id} in {@link Scene#selectedObjects}.\n     *\n     * @type {Boolean}\n     */\n    set selected(selected) {\n        selected = !!selected;\n        this._selected = selected;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].selected = selected;\n        }\n        if (this._isObject) {\n            this.scene._objectSelectedUpdated(this, selected);\n        }\n    }\n\n    /**\n     * Gets if this Node is selected.\n     *\n     * When {@link Node#isObject} and {@link Node#selected} are both ````true```` the Node will be\n     * registered by {@link Node#id} in {@link Scene#selectedObjects}.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Boolean}\n     */\n    get selected() {\n        return this._selected;\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es are edge-enhanced.\n     *\n     * @type {Boolean}\n     */\n    set edges(edges) {\n        edges = !!edges;\n        this._edges = edges;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].edges = edges;\n        }\n    }\n\n    /**\n     * Gets if this Node's edges are enhanced.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Boolean}\n     */\n    get edges() {\n        return this._edges;\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es are culled.\n     *\n     * @type {Boolean}\n     */\n    set culled(culled) {\n        culled = !!culled;\n        this._culled = culled;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].culled = culled;\n        }\n    }\n\n    /**\n     * Gets if this Node is culled.\n     *\n     * @type {Boolean}\n     */\n    get culled() {\n        return this._culled;\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es are clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#clips}.\n     *\n     * @type {Boolean}\n     */\n    set clippable(clippable) {\n        clippable = clippable !== false;\n        this._clippable = clippable;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].clippable = clippable;\n        }\n    }\n\n    /**\n     * Gets if this Node is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#clips}.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Boolean}\n     */\n    get clippable() {\n        return this._clippable;\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es are included in boundary calculations.\n     *\n     * @type {Boolean}\n     */\n    set collidable(collidable) {\n        collidable = collidable !== false;\n        this._collidable = collidable;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].collidable = collidable;\n        }\n    }\n\n    /**\n     * Gets if this Node is included in boundary calculations.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Boolean}\n     */\n    get collidable() {\n        return this._collidable;\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es are pickable.\n     *\n     * Picking is done via calls to {@link Scene#pick}.\n     *\n     * @type {Boolean}\n     */\n    set pickable(pickable) {\n        pickable = pickable !== false;\n        this._pickable = pickable;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].pickable = pickable;\n        }\n    }\n\n    /**\n     * Gets if to this Node is pickable.\n     *\n     * Picking is done via calls to {@link Scene#pick}.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Boolean}\n     */\n    get pickable() {\n        return this._pickable;\n    }\n\n    /**\n     * Sets the RGB colorize color for this Node and all child Nodes and {@link Mesh}es}.\n     *\n     * Multiplies by rendered fragment colors.\n     *\n     * Each element of the color is in range ````[0..1]````.\n     *\n     * @type {Number[]}\n     */\n    set colorize(rgb) {\n        let colorize = this._colorize;\n        if (!colorize) {\n            colorize = this._colorize = new Float32Array(4);\n            colorize[3] = 1.0;\n        }\n        if (rgb) {\n            colorize[0] = rgb[0];\n            colorize[1] = rgb[1];\n            colorize[2] = rgb[2];\n        } else {\n            colorize[0] = 1;\n            colorize[1] = 1;\n            colorize[2] = 1;\n        }\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].colorize = colorize;\n        }\n        if (this._isObject) {\n            const colorized = (!!rgb);\n            this.scene._objectColorizeUpdated(this, colorized);\n        }\n    }\n\n    /**\n     * Gets the RGB colorize color for this Node.\n     *\n     * Each element of the color is in range ````[0..1]````.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Number[]}\n     */\n    get colorize() {\n        return this._colorize.slice(0, 3);\n    }\n\n    /**\n     * Sets the opacity factor for this Node and all child Nodes and {@link Mesh}es.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    set opacity(opacity) {\n        let colorize = this._colorize;\n        if (!colorize) {\n            colorize = this._colorize = new Float32Array(4);\n            colorize[0] = 1;\n            colorize[1] = 1;\n            colorize[2] = 1;\n        }\n        colorize[3] = opacity !== null && opacity !== undefined ? opacity : 1.0;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].opacity = opacity;\n        }\n        if (this._isObject) {\n            const opacityUpdated = (opacity !== null && opacity !== undefined);\n            this.scene._objectOpacityUpdated(this, opacityUpdated);\n        }\n    }\n\n    /**\n     * Gets this Node's opacity factor.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Number}\n     */\n    get opacity() {\n        return this._colorize[3];\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es cast shadows.\n     *\n     * @type {Boolean}\n     */\n    set castsShadow(castsShadow) {\n        castsShadow = !!castsShadow;\n        this._castsShadow = castsShadow;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].castsShadow = castsShadow;\n        }\n    }\n\n    /**\n     * Gets if this Node casts shadows.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Boolean}\n     */\n    get castsShadow() {\n        return this._castsShadow;\n    }\n\n    /**\n     * Sets if this Node and all child Nodes and {@link Mesh}es can have shadows cast upon them.\n     *\n     * @type {Boolean}\n     */\n    set receivesShadow(receivesShadow) {\n        receivesShadow = !!receivesShadow;\n        this._receivesShadow = receivesShadow;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].receivesShadow = receivesShadow;\n        }\n    }\n\n    /**\n     * Whether or not to this Node can have shadows cast upon it.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Boolean}\n     */\n    get receivesShadow() {\n        return this._receivesShadow;\n    }\n\n    /**\n     * Gets if this Node can have Scalable Ambient Obscurance (SAO) applied to it.\n     *\n     * SAO is configured by {@link SAO}.\n     *\n     * @type {Boolean}\n     * @abstract\n     */\n    get saoEnabled() {\n        return false; // TODO: Support SAO on Nodes\n    }\n\n\n    /**\n     * Sets the 3D World-space offset for this Node and all child Nodes and {@link Mesh}es}.\n     *\n     * The offset dynamically translates those components in World-space.\n     *\n     * Default value is ````[0, 0, 0]````.\n     *\n     * Note that child Nodes and {@link Mesh}es may subsequently be given different values for this property.\n     *\n     * @type {Number[]}\n     */\n    set offset(offset) {\n        if (offset) {\n            this._offset[0] = offset[0];\n            this._offset[1] = offset[1];\n            this._offset[2] = offset[2];\n        } else {\n            this._offset[0] = 0;\n            this._offset[1] = 0;\n            this._offset[2] = 0;\n        }\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i].offset = this._offset;\n        }\n        if (this._isObject) {\n            this.scene._objectOffsetUpdated(this, offset);\n        }\n    }\n\n    /**\n     * Gets the Node's 3D World-space offset.\n     *\n     * Default value is ````[0, 0, 0]````.\n     *\n     * Child Nodes and {@link Mesh}es may have different values for this property.\n     *\n     * @type {Number[]}\n     */\n    get offset() {\n        return this._offset;\n    }\n\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Node members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns true to indicate that this Component is a Node.\n     * @type {Boolean}\n     */\n    get isNode() {\n        return true;\n    }\n\n    _setLocalMatrixDirty() {\n        this._localMatrixDirty = true;\n        this._setWorldMatrixDirty();\n    }\n\n    _setWorldMatrixDirty() {\n        this._worldMatrixDirty = true;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            this._children[i]._setWorldMatrixDirty();\n        }\n    }\n\n    _buildWorldMatrix() {\n        const localMatrix = this.matrix;\n        if (!this._parentNode) {\n            for (let i = 0, len = localMatrix.length; i < len; i++) {\n                this._worldMatrix[i] = localMatrix[i];\n            }\n        } else {\n            math.mulMat4(this._parentNode.worldMatrix, localMatrix, this._worldMatrix);\n        }\n        this._worldMatrixDirty = false;\n    }\n\n    _setSubtreeAABBsDirty(node) {\n        node._aabbDirty = true;\n        if (node._children) {\n            for (let i = 0, len = node._children.length; i < len; i++) {\n                this._setSubtreeAABBsDirty(node._children[i]);\n            }\n        }\n    }\n\n    _setAABBDirty() {\n        this._setSubtreeAABBsDirty(this);\n        if (this.collidable) {\n            for (let node = this; node; node = node._parentNode) {\n                node._aabbDirty = true;\n            }\n        }\n    }\n\n    _updateAABB() {\n        this.scene._aabbDirty = true;\n        if (!this._aabb) {\n            this._aabb = math.AABB3();\n        }\n        if (this._buildAABB) {\n            this._buildAABB(this.worldMatrix, this._aabb); // Mesh or VBOSceneModel\n        } else { // Node | Node | Model\n            math.collapseAABB3(this._aabb);\n            let node;\n            for (let i = 0, len = this._children.length; i < len; i++) {\n                node = this._children[i];\n                if (!node.collidable) {\n                    continue;\n                }\n                math.expandAABB3(this._aabb, node.aabb);\n            }\n        }\n        this._aabbDirty = false;\n    }\n\n    /**\n     * Adds a child Node or {@link Mesh}.\n     *\n     * The child must be a Node or {@link Mesh} in the same {@link Scene}.\n     *\n     * If the child already has a parent, will be removed from that parent first.\n     *\n     * Does nothing if already a child.\n     *\n     * @param {Node|Mesh|String} child Instance or ID of the child to add.\n     * @param [inheritStates=false] Indicates if the child should inherit rendering states from this parent as it is added. Rendering state includes {@link Node#visible}, {@link Node#culled}, {@link Node#pickable}, {@link Node#clippable}, {@link Node#castsShadow}, {@link Node#receivesShadow}, {@link Node#selected}, {@link Node#highlighted}, {@link Node#colorize} and {@link Node#opacity}.\n     * @returns {Node|Mesh} The child.\n     */\n    addChild(child, inheritStates) {\n        if (utils.isNumeric(child) || utils.isString(child)) {\n            const nodeId = child;\n            child = this.scene.component[nodeId];\n            if (!child) {\n                this.warn(\"Component not found: \" + utils.inQuotes(nodeId));\n                return;\n            }\n            if (!child.isNode && !child.isMesh) {\n                this.error(\"Not a Node or Mesh: \" + nodeId);\n                return;\n            }\n        } else {\n            if (!child.isNode && !child.isMesh) {\n                this.error(\"Not a Node or Mesh: \" + child.id);\n                return;\n            }\n            if (child._parentNode) {\n                if (child._parentNode.id === this.id) {\n                    this.warn(\"Already a child: \" + child.id);\n                    return;\n                }\n                child._parentNode.removeChild(child);\n            }\n        }\n        child.id;\n        if (child.scene.id !== this.scene.id) {\n            this.error(\"Child not in same Scene: \" + child.id);\n            return;\n        }\n        this._children.push(child);\n        child._parentNode = this;\n        if (!!inheritStates) {\n            child.visible = this.visible;\n            child.culled = this.culled;\n            child.xrayed = this.xrayed;\n            child.highlited = this.highlighted;\n            child.selected = this.selected;\n            child.edges = this.edges;\n            child.clippable = this.clippable;\n            child.pickable = this.pickable;\n            child.collidable = this.collidable;\n            child.castsShadow = this.castsShadow;\n            child.receivesShadow = this.receivesShadow;\n            child.colorize = this.colorize;\n            child.opacity = this.opacity;\n            child.offset = this.offset;\n        }\n        child._setWorldMatrixDirty();\n        child._setAABBDirty();\n        this._numTriangles += child.numTriangles;\n        return child;\n    }\n\n    /**\n     * Removes the given child Node or {@link Mesh}.\n     *\n     * @param {Node|Mesh} child Child to remove.\n     */\n    removeChild(child) {\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            if (this._children[i].id === child.id) {\n                child._parentNode = null;\n                this._children = this._children.splice(i, 1);\n                child._setWorldMatrixDirty();\n                child._setAABBDirty();\n                this._setAABBDirty();\n                this._numTriangles -= child.numTriangles;\n                return;\n            }\n        }\n    }\n\n    /**\n     * Removes all child Nodes and {@link Mesh}es.\n     */\n    removeChildren() {\n        let child;\n        for (let i = 0, len = this._children.length; i < len; i++) {\n            child = this._children[i];\n            child._parentNode = null;\n            child._setWorldMatrixDirty();\n            child._setAABBDirty();\n            this._numTriangles -= child.numTriangles;\n        }\n        this._children = [];\n        this._setAABBDirty();\n    }\n\n    /**\n     * Number of child Nodes or {@link Mesh}es.\n     *\n     * @type {Number}\n     */\n    get numChildren() {\n        return this._children.length;\n    }\n\n    /**\n     * Array of child Nodes or {@link Mesh}es.\n     *\n     * @type {Array}\n     */\n    get children() {\n        return this._children;\n    }\n\n    /**\n     * The parent Node.\n     *\n     * The parent Node may also be set by passing the Node to the parent's {@link Node#addChild} method.\n     *\n     * @type {Node}\n     */\n    set parent(node) {\n        if (utils.isNumeric(node) || utils.isString(node)) {\n            const nodeId = node;\n            node = this.scene.components[nodeId];\n            if (!node) {\n                this.warn(\"Node not found: \" + utils.inQuotes(nodeId));\n                return;\n            }\n            if (!node.isNode) {\n                this.error(\"Not a Node: \" + node.id);\n                return;\n            }\n        }\n        if (node.scene.id !== this.scene.id) {\n            this.error(\"Node not in same Scene: \" + node.id);\n            return;\n        }\n        if (this._parentNode && this._parentNode.id === node.id) {\n            this.warn(\"Already a child of Node: \" + node.id);\n            return;\n        }\n        node.addChild(this);\n    }\n\n    /**\n     * The parent Node.\n     *\n     * @type {Node}\n     */\n    get parent() {\n        return this._parentNode;\n    }\n\n    /**\n     * Sets the Node's local translation.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    set position(value) {\n        this._position.set(value || [0, 0, 0]);\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Node's local translation.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    get position() {\n        return this._position;\n    }\n\n    /**\n     * Sets the Node's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    set rotation(value) {\n        this._rotation.set(value || [0, 0, 0]);\n        math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Node's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    get rotation() {\n        return this._rotation;\n    }\n\n    /**\n     * Sets the Node's local rotation quaternion.\n     *\n     * Default value is ````[0,0,0,1]````.\n     *\n     * @type {Number[]}\n     */\n    set quaternion(value) {\n        this._quaternion.set(value || [0, 0, 0, 1]);\n        math.quaternionToEuler(this._quaternion, \"XYZ\", this._rotation);\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Node's local rotation quaternion.\n     *\n     * Default value is ````[0,0,0,1]````.\n     *\n     * @type {Number[]}\n     */\n    get quaternion() {\n        return this._quaternion;\n    }\n\n    /**\n     * Sets the Node's local scale.\n     *\n     * Default value is ````[1,1,1]````.\n     *\n     * @type {Number[]}\n     */\n    set scale(value) {\n        this._scale.set(value || [1, 1, 1]);\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Node's local scale.\n     *\n     * Default value is ````[1,1,1]````.\n     *\n     * @type {Number[]}\n     */\n    get scale() {\n        return this._scale;\n    }\n\n    /**\n     * Sets the Node's local modeling transform matrix.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @type {Number[]}\n     */\n    set matrix(value) {\n        if (!this._localMatrix) {\n            this._localMatrix = math.identityMat4();\n        }\n        this._localMatrix.set(value || identityMat$2);\n        math.decomposeMat4(this._localMatrix, this._position, this._quaternion, this._scale);\n        this._localMatrixDirty = false;\n        this._setWorldMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Node's local modeling transform matrix.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @type {Number[]}\n     */\n    get matrix() {\n        if (this._localMatrixDirty) {\n            if (!this._localMatrix) {\n                this._localMatrix = math.identityMat4();\n            }\n            math.composeMat4(this._position, this._quaternion, this._scale, this._localMatrix);\n            this._localMatrixDirty = false;\n        }\n        return this._localMatrix;\n    }\n\n    /**\n     * Gets the Node's World matrix.\n     *\n     * @property worldMatrix\n     * @type {Number[]}\n     */\n    get worldMatrix() {\n        if (this._worldMatrixDirty) {\n            this._buildWorldMatrix();\n        }\n        return this._worldMatrix;\n    }\n\n    /**\n     * Rotates the Node about the given local axis by the given increment.\n     *\n     * @param {Number[]} axis Local axis about which to rotate.\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotate(axis, angle) {\n        angleAxis$2[0] = axis[0];\n        angleAxis$2[1] = axis[1];\n        angleAxis$2[2] = axis[2];\n        angleAxis$2[3] = angle * math.DEGTORAD;\n        math.angleAxisToQuaternion(angleAxis$2, q1$2);\n        math.mulQuaternions(this.quaternion, q1$2, q2$2);\n        this.quaternion = q2$2;\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n        return this;\n    }\n\n    /**\n     * Rotates the Node about the given World-space axis by the given increment.\n     *\n     * @param {Number[]} axis Local axis about which to rotate.\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateOnWorldAxis(axis, angle) {\n        angleAxis$2[0] = axis[0];\n        angleAxis$2[1] = axis[1];\n        angleAxis$2[2] = axis[2];\n        angleAxis$2[3] = angle * math.DEGTORAD;\n        math.angleAxisToQuaternion(angleAxis$2, q1$2);\n        math.mulQuaternions(q1$2, this.quaternion, q1$2);\n        //this.quaternion.premultiply(q1);\n        return this;\n    }\n\n    /**\n     * Rotates the Node about the local X-axis by the given increment.\n     *\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateX(angle) {\n        return this.rotate(xAxis$2, angle);\n    }\n\n    /**\n     * Rotates the Node about the local Y-axis by the given increment.\n     *\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateY(angle) {\n        return this.rotate(yAxis$2, angle);\n    }\n\n    /**\n     * Rotates the Node about the local Z-axis by the given increment.\n     *\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateZ(angle) {\n        return this.rotate(zAxis$2, angle);\n    }\n\n    /**\n     * Translates the Node along local space vector by the given increment.\n     *\n     * @param {Number[]} axis Normalized local space 3D vector along which to translate.\n     * @param {Number} distance Distance to translate along  the vector.\n     */\n    translate(axis, distance) {\n        math.vec3ApplyQuaternion(this.quaternion, axis, veca$1);\n        math.mulVec3Scalar(veca$1, distance, vecb$1);\n        math.addVec3(this.position, vecb$1, this.position);\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n        return this;\n    }\n\n    /**\n     * Translates the Node along the local X-axis by the given increment.\n     *\n     * @param {Number} distance Distance to translate along  the X-axis.\n     */\n    translateX(distance) {\n        return this.translate(xAxis$2, distance);\n    }\n\n    /**\n     * Translates the Node along the local Y-axis by the given increment.\n     *\n     * @param {Number} distance Distance to translate along  the Y-axis.\n     */\n    translateY(distance) {\n        return this.translate(yAxis$2, distance);\n    }\n\n    /**\n     * Translates the Node along the local Z-axis by the given increment.\n     *\n     * @param {Number} distance Distance to translate along  the Z-axis.\n     */\n    translateZ(distance) {\n        return this.translate(zAxis$2, distance);\n    }\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Component members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Node\";\n    }\n\n    /**\n     * Destroys this Node.\n     */\n    destroy() {\n        super.destroy();\n        if (this._parentNode) {\n            this._parentNode.removeChild(this);\n        }\n        if (this._isObject) {\n            this.scene._deregisterObject(this);\n            if (this._visible) {\n                this.scene._objectVisibilityUpdated(this, false, false);\n            }\n            if (this._xrayed) {\n                this.scene._objectXRayedUpdated(this, false, false);\n            }\n            if (this._selected) {\n                this.scene._objectSelectedUpdated(this, false, false);\n            }\n            if (this._highlighted) {\n                this.scene._objectHighlightedUpdated(this, false, false);\n            }\n            this.scene._objectColorizeUpdated(this, false);\n            this.scene._objectOpacityUpdated(this, false);\n            if (this.offset.some((v) => v !== 0))\n                this.scene._objectOffsetUpdated(this, false);\n        }\n        if (this._isModel) {\n            this.scene._deregisterModel(this);\n        }\n        if (this._children.length) {\n            // Clone the _children before iterating, so our children don't mess us up when calling removeChild().\n            const tempChildList = this._children.splice(0);\n            let child;\n            for (let i = 0, len = tempChildList.length; i < len; i++) {\n                child = tempChildList[i];\n                child.destroy();\n            }\n        }\n        this._children = [];\n        this._setAABBDirty();\n        this.scene._aabbDirty = true;\n    }\n\n}\n\nconst tempVec3a$g = math.vec3();\n\n/**\n * Given a view matrix and a relative-to-center (RTC) coordinate origin, returns a view matrix\n * to transform RTC coordinates to View-space.\n *\n * The returned view matrix is\n *\n * @private\n */\nconst createRTCViewMat = (function () {\n\n    const tempMat = new Float64Array(16);\n    const rtcCenterWorld = new Float64Array(4);\n    const rtcCenterView = new Float64Array(4);\n\n    return function (viewMat, rtcCenter, rtcViewMat) {\n        rtcViewMat = rtcViewMat || tempMat;\n        rtcCenterWorld[0] = rtcCenter[0];\n        rtcCenterWorld[1] = rtcCenter[1];\n        rtcCenterWorld[2] = rtcCenter[2];\n        rtcCenterWorld[3] = 1;\n        math.transformVec4(viewMat, rtcCenterWorld, rtcCenterView);\n        math.setMat4Translation(viewMat, rtcCenterView, rtcViewMat);\n        return rtcViewMat.slice ();\n    }\n}());\n\n/**\n * Converts a World-space 3D position to RTC.\n *\n * Given a double-precision World-space position, returns a double-precision relative-to-center (RTC) center pos\n * and a single-precision offset fom that center.\n * @private\n * @param {Float64Array} worldPos The World-space position.\n * @param {Float64Array} rtcCenter Double-precision relative-to-center (RTC) center pos.\n * @param {Float32Array} rtcPos Single-precision offset fom that center.\n */\nfunction worldToRTCPos(worldPos, rtcCenter, rtcPos) {\n\n    const xHigh = Float32Array.from([worldPos[0]])[0];\n    const xLow = worldPos[0] - xHigh;\n\n    const yHigh = Float32Array.from([worldPos[1]])[0];\n    const yLow = worldPos[1] - yHigh;\n\n    const zHigh = Float32Array.from([worldPos[2]])[0];\n    const zLow = worldPos[2] - zHigh;\n\n    rtcCenter[0] = xHigh;\n    rtcCenter[1] = yHigh;\n    rtcCenter[2] = zHigh;\n\n    rtcPos[0] = xLow;\n    rtcPos[1] = yLow;\n    rtcPos[2] = zLow;\n}\n\n\n/**\n * Converts a flat array of double-precision positions to RTC positions, if necessary.\n *\n * Conversion is necessary if the coordinates have values larger than can be expressed at single-precision. When\n * that's the case, then this function will compute the RTC coordinates and RTC center and return true. Otherwise\n * this function does nothing and returns false.\n *\n * When computing the RTC position, this function uses a modulus operation to ensure that, whenever possible,\n * identical RTC centers are reused for different positions arrays.\n *\n * @private\n * @param {Float64Array} worldPositions Flat array of World-space 3D positions.\n * @param {Float64Array} rtcPositions Outputs the computed flat array of 3D RTC positions.\n * @param {Float64Array} rtcCenter Outputs the computed double-precision relative-to-center (RTC) center pos.\n * @param {Number} [cellSize=10000000] The size of each coordinate cell within the RTC coordinate system.\n * @returns {Boolean} ````True```` if the positions actually needed conversion to RTC, else ````false````. When\n * ````false````, we can safely ignore the data returned in ````rtcPositions```` and ````rtcCenter````,\n * since ````rtcCenter```` will equal ````[0,0,0]````, and ````rtcPositions```` will contain identical values to ````positions````.\n */\nfunction worldToRTCPositions(worldPositions, rtcPositions, rtcCenter, cellSize = 1000) {\n\n    const center = math.getPositionsCenter(worldPositions, tempVec3a$g);\n\n    const rtcCenterX = Math.round(center[0] / cellSize) * cellSize;\n    const rtcCenterY = Math.round(center[1] / cellSize) * cellSize;\n    const rtcCenterZ = Math.round(center[2] / cellSize) * cellSize;\n\n    rtcCenter[0] = rtcCenterX;\n    rtcCenter[1] = rtcCenterY;\n    rtcCenter[2] = rtcCenterZ;\n\n    const rtcNeeded = (rtcCenter[0] !== 0 || rtcCenter[1] !== 0 || rtcCenter[2] !== 0);\n\n    if (rtcNeeded) {\n        for (let i = 0, len = worldPositions.length; i < len; i += 3) {\n            rtcPositions[i + 0] = worldPositions[i + 0] - rtcCenterX;\n            rtcPositions[i + 1] = worldPositions[i + 1] - rtcCenterY;\n            rtcPositions[i + 2] = worldPositions[i + 2] - rtcCenterZ;\n        }\n    }\n\n    return rtcNeeded;\n}\n\n/**\n * Texture wrapping mode in which the texture repeats to infinity.\n */\nconst RepeatWrapping = 1000;\n\n/**\n * Texture wrapping mode in which the last pixel of the texture stretches to the edge of the mesh.\n */\nconst ClampToEdgeWrapping = 1001;\n\n/**\n * Texture wrapping mode in which the texture repeats to infinity, mirroring on each repeat.\n */\nconst MirroredRepeatWrapping = 1002;\n\n/**\n * Texture magnification and minification filter that returns the nearest texel to the given sample coordinates.\n */\nconst NearestFilter = 1003;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and returns the nearest texel to the given sample coordinates.\n */\nconst NearestMipMapNearestFilter = 1004;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured\n * and returns the nearest texel to the given sample coordinates.\n */\nconst NearestMipmapNearestFilter = 1004;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\n */\nconst NearestMipmapLinearFilter = 1005;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured\n * and returns the nearest texel to the center of the pixel at the given sample coordinates.\n */\nconst NearestMipMapLinearFilter = 1005;\n\n/**\n * Texture magnification and minification filter that returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nconst LinearFilter = 1006;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\n * returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nconst LinearMipmapNearestFilter = 1007;\n\n/**\n * Texture minification filter that chooses the mipmap that most closely matches the size of the pixel being textured and\n * returns the weighted average of the four nearest texels to the given sample coordinates.\n */\nconst LinearMipMapNearestFilter = 1007;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\n * weighted average of those two values.\n */\nconst LinearMipmapLinearFilter = 1008;\n\n/**\n * Texture minification filter that chooses two mipmaps that most closely match the size of the pixel being textured,\n * finds within each mipmap the weighted average of the nearest texel to the center of the pixel, then returns the\n * weighted average of those two values.\n */\nconst LinearMipMapLinearFilter = 1008;\n\n/**\n * Unsigned 8-bit integer type.\n */\nconst UnsignedByteType = 1009;\n\n/**\n * Signed 8-bit integer type.\n */\nconst ByteType = 1010;\n\n/**\n * Signed 16-bit integer type.\n */\nconst ShortType = 1011;\n\n/**\n * Unsigned 16-bit integer type.\n */\nconst UnsignedShortType = 1012;\n\n/**\n * Signed 32-bit integer type.\n */\nconst IntType = 1013;\n\n/**\n * Unsigned 32-bit integer type.\n */\nconst UnsignedIntType = 1014;\n\n/**\n * Signed 32-bit floating-point type.\n */\nconst FloatType = 1015;\n\n/**\n * Signed 16-bit half-precision floating-point type.\n */\nconst HalfFloatType = 1016;\n\n/**\n * Texture packing mode in which each ````RGBA```` channel is packed into 4 bits, for a combined total of 16 bits.\n */\nconst UnsignedShort4444Type = 1017;\n\n/**\n * Texture packing mode in which the ````RGB```` channels are each packed into 5 bits, and the ````A```` channel is packed into 1 bit, for a combined total of 16 bits.\n */\nconst UnsignedShort5551Type = 1018;\n\n/**\n * Unsigned integer type for 24-bit depth texture data.\n */\nconst UnsignedInt248Type = 1020;\n\n/**\n * Texture sampling mode that discards the ````RGBA```` components and just reads the ````A```` component.\n */\nconst AlphaFormat = 1021;\n\n/**\n * Texture sampling mode that discards the ````A```` component and reads the ````RGB```` components.\n */\nconst RGBFormat = 1022;\n\n/**\n * Texture sampling mode that reads the ````RGBA```` components.\n */\nconst RGBAFormat = 1023;\n\n/**\n * Texture sampling mode that reads each ````RGB```` texture component as a luminance value, converted to a float and clamped\n * to ````[0,1]````, while always reading the ````A```` channel as ````1.0````.\n */\nconst LuminanceFormat = 1024;\n\n/**\n * Texture sampling mode that reads each of the ````RGBA```` texture components as a luminance/alpha value, converted to a float and clamped to ````[0,1]````.\n */\nconst LuminanceAlphaFormat = 1025;\n\n/**\n * Texture sampling mode that reads each element as a single depth value, converts it to a float and clamps to ````[0,1]````.\n */\nconst DepthFormat = 1026;\n\n/**\n * Texture sampling mode that\n */\nconst DepthStencilFormat = 1027;\n\n/**\n * Texture sampling mode that discards the ````GBA```` components and just reads the ````R```` component.\n */\nconst RedFormat = 1028;\n\n/**\n * Texture sampling mode that discards the ````GBA```` components and just reads the ````R```` component, as an integer instead of as a float.\n */\nconst RedIntegerFormat = 1029;\n\n/**\n * Texture sampling mode that discards the ````A```` and ````B```` components and just reads the ````R```` and ````G```` components.\n */\nconst RGFormat = 1030;\n\n/**\n * Texture sampling mode that discards the ````A```` and ````B```` components and just reads the ````R```` and ````G```` components, as integers instead of floats.\n */\nconst RGIntegerFormat = 1031;\n\n/**\n * Texture sampling mode that reads the ````RGBA```` components as integers instead of floats.\n */\nconst RGBAIntegerFormat = 1033;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT1 compressed</a> ````RGB```` image.\n */\nconst RGB_S3TC_DXT1_Format = 33776;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT1 compressed</a> ````RGBA```` image.\n */\nconst RGBA_S3TC_DXT1_Format = 33777;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT3 compressed</a> ````RGBA```` image.\n */\nconst RGBA_S3TC_DXT3_Format = 33778;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/S3_Texture_Compression\">DXT5 compressed</a> ````RGBA```` image.\n */\nconst RGBA_S3TC_DXT5_Format = 33779;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\n * image, with ````RGB```` compression in 4-bit mode and one block for each 4×4 pixels.\n */\nconst RGB_PVRTC_4BPPV1_Format = 35840;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\n * image, with ````RGB```` compression in 2-bit mode and one block for each 8×4 pixels.\n */\nconst RGB_PVRTC_2BPPV1_Format = 35841;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\n * image, with ````RGBA```` compression in 4-bit mode and one block for each 4×4 pixels.\n */\nconst RGBA_PVRTC_4BPPV1_Format = 35842;\n\n/**\n * Texture format mode in which the texture is formatted as a <a href=\"https://en.wikipedia.org/wiki/PVRTC\">PVRTC compressed</a>\n * image, with ````RGBA```` compression in 2-bit mode and one block for each 8×4 pixels.\n */\nconst RGBA_PVRTC_2BPPV1_Format = 35843;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc1/\">ETC1 compressed</a>\n * ````RGB```` image.\n */\nconst RGB_ETC1_Format = 36196;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc2/\">ETC2 compressed</a>\n * ````RGB```` image.\n */\nconst RGB_ETC2_Format = 37492;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc2/\">ETC2 compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ETC2_EAC_Format = 37496;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_4x4_Format = 37808;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_5x4_Format = 37809;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_5x5_Format = 37810;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_6x5_Format = 37811;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_6x6_Format = 37812;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_8x5_Format = 37813;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_8x6_Format = 37814;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_8x8_Format = 37815;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_10x5_Format = 37816;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_10x6_Format = 37817;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_10x8_Format = 37818;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_10x10_Format = 37819;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_12x10_Format = 37820;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/\">ATSC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_ASTC_12x12_Format = 37821;\n\n/**\n * Texture format mode in which the texture is formatted as an <a href=\"https://www.khronos.org/opengl/wiki/BPTC_Texture_Compression\">BPTC compressed</a>\n * ````RGBA```` image.\n */\nconst RGBA_BPTC_Format = 36492;\n\n/**\n * Texture encoding mode in which the texture image is in linear color space.\n */\nconst LinearEncoding = 3000;\n\n/**\n * Texture encoding mode in which the texture image is in sRGB color space.\n */\nconst sRGBEncoding = 3001;\n\n/**\n * Media type for GIF images.\n */\nconst GIFMediaType = 10000;\n\n/**\n * Media type for JPEG images.\n */\nconst JPEGMediaType = 10001;\n\n/**\n * Media type for PNG images.\n */\nconst PNGMediaType = 10002;\n\n/**\n * Media type for compressed texture data.\n */\nconst CompressedMediaType = 10003;\n\nconst ids$1 = new Map$1({});\nconst tempVec3a$f = math.vec3();\nconst tempVec4$3 = math.vec4();\nconst TEXTURE_DECODE_FUNCS = { [sRGBEncoding]: \"sRGBToLinear\" };\n\nconst iota$3 = function(n) {\n    const ret = [ ];\n    for (let i = 0; i < n; ++i) ret.push(i);\n    return ret;\n};\n\nconst createProgramVariablesState = function() {\n    const vertAppenders = [ ];\n    const vOutAppenders = [ ];\n    const fragAppenders = [ ];\n    const fragDefAppenders = [ ];\n    const attrSetters = [ ];\n    const attrHahes = [ ];\n    const unifSetters = [ ];\n    const createVertexDefinition = (name, appendDefinition) => {\n        let needed = false;\n        vertAppenders.push((src) => needed && appendDefinition(name, src));\n        return {\n            toString: () => {\n                needed = true;\n                return name;\n            }\n        };\n    };\n    const programVariables = {\n            createAttribute: function(type, name) {\n                let needed = false;\n                vertAppenders.push((src) => needed && src.push(`in ${type} ${name};`));\n                const ret = {\n                    toString: () => {\n                        needed = true;\n                        return name;\n                    }\n                };\n                attrSetters.push((getInputSetter) => {\n                    const setValue = needed && getInputSetter(name);\n                    setValue && attrHahes.push(setValue.attributeHash);\n                    ret.setInputValue = setValue;\n                    return null;\n                });\n                return ret;\n            },\n            createFragmentDefinition: (name, appendDefinition) => {\n                let needed = false;\n                fragDefAppenders.push((src) => needed && appendDefinition(name, src));\n                return {\n                    toString: () => {\n                        needed = true;\n                        return name;\n                    }\n                };\n            },\n            createOutput: (type, name, location) => {\n                let needed = false;\n                fragAppenders.push((src) => needed && src.push(`layout(location = ${location || 0}) out ${type} ${name};`));\n                return {\n                    toString: () => {\n                        needed = true;\n                        return name;\n                    }\n                };\n            },\n            createUniform: (type, name, valueSetter) => {\n                let needed = false;\n                const append = (src) => needed && src.push(`uniform ${type} ${name};`);\n                vertAppenders.push(append);\n                fragAppenders.push(append);\n                const ret = {\n                    toString: () => {\n                        needed = true;\n                        return name;\n                    }\n                };\n                unifSetters.push((getInputSetter) => {\n                    const setValue = needed && getInputSetter(name);\n                    if (valueSetter) {\n                        return setValue && ((state) => valueSetter(setValue, state));\n                    } else {\n                        ret.setInputValue = setValue;\n                        return null;\n                    }\n                });\n                return ret;\n            },\n            createUniformArray: (type, name, length) => {\n                let needed = false;\n                const append = (src) => needed && src.push(`uniform ${type} ${name}[${length}];`);\n                vertAppenders.push(append);\n                fragAppenders.push(append);\n                const ret = {\n                    toString: () => {\n                        needed = true;\n                        return name;\n                    }\n                };\n                unifSetters.push((getInputSetter) => {\n                    ret.setInputValue = needed && getInputSetter(name);\n                    return null;\n                });\n                return ret;\n            },\n            createUniformBlock: (name, types, valueSetter) => {\n                let needed = false;\n                const keys = Object.keys(types);\n                const append = (src) => {\n                    if (needed) {\n                        src.push(`uniform ${name} {`);\n                        keys.forEach(k => src.push(`    ${types[k]} ${k};`));\n                        src.push(`};`);\n                    }\n                };\n                vertAppenders.push(append);\n                fragAppenders.push(append);\n                const ret = { };\n                keys.forEach(k => ret[k] = {\n                    toString: () => {\n                        needed = true;\n                        return k;\n                    }\n                });\n                unifSetters.push((getInputSetter) => {\n                    const setValue = needed && getInputSetter(name);\n                    if (valueSetter) {\n                        return setValue && ((state) => valueSetter(setValue, state));\n                    } else {\n                        ret.setInputValue = setValue;\n                        return null;\n                    }\n                });\n                return ret;\n            },\n            createVarying: (type, name, genValueCode, interpolationQualifier) => {\n                let needed = false;\n                const intp = interpolationQualifier ? (interpolationQualifier + \" \") : \"\";\n                vertAppenders.push((src) => needed && src.push(`${intp}out ${type} ${name};`));\n                vOutAppenders.push((src) => needed && src.push(`${name} = ${genValueCode()};`));\n                fragAppenders.push((src) => needed && src.push(`${intp}in  ${type} ${name};`));\n                return {\n                    toString: () => {\n                        needed = true;\n                        return name;\n                    }\n                };\n            },\n        createVertexDefinition: createVertexDefinition,\n        commonLibrary: {\n            octDecode: createVertexDefinition(\n                \"octDecode\",\n                (name, src) => {\n                    src.push(`vec3 ${name}(vec2 oct) {`);\n                    src.push(\"    vec3 v = vec3(oct.xy, 1.0 - abs(oct.x) - abs(oct.y));\");\n                    src.push(\"    if (v.z < 0.0) {\");\n                    src.push(\"        v.xy = (1.0 - abs(v.yx)) * vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0);\");\n                    src.push(\"    }\");\n                    src.push(\"    return normalize(v);\");\n                    src.push(\"}\");\n                })\n        }\n    };\n    return {\n        programVariables: programVariables,\n        buildProgram: (gl, programName, cfg) => {\n            const getLogDepth = cfg.getLogDepth;\n\n            const clipPos = cfg.clipPos;\n            const clipTransformSetup = cfg.usePickClipPos && (function() {\n                const pickClipPos    = programVariables.createUniform(\"vec2\", \"pickClipPos\");\n                const pickClipPosInv = programVariables.createUniform(\"vec2\", \"pickClipPosInv\");\n                return {\n                    setClipPosInputValue: frameCtx => {\n                        pickClipPos.setInputValue(frameCtx.pickClipPos);\n                        pickClipPosInv.setInputValue(frameCtx.pickClipPosInv);\n                    },\n                    transformedClipPos: () => `vec4((${clipPos}.xy / ${clipPos}.w - ${pickClipPos}) * ${pickClipPosInv} * ${clipPos}.w, ${clipPos}.zw)`\n                };\n            })();\n\n            const vertexClipPosition = clipTransformSetup ? clipTransformSetup.transformedClipPos() : clipPos;\n\n            const fragmentOutputs = [ ];\n            const isPerspective = programVariables.createVarying(\"float\", \"isPerspective\", () => `(${cfg.projMatrix}[2][3] == -1.0) ? 1.0 : 0.0`);\n            const logDepthBufFC = programVariables.createUniform(\"float\", \"logDepthBufFC\", (set, state) => set(2.0 / (Math.log(state.view.far + 1.0) / Math.LN2)));\n            const vFragDepth    = programVariables.createVarying(\"float\", \"vFragDepth\",    () => \"1.0 + clipPos.w\");\n            if (getLogDepth) {\n                fragmentOutputs.push(`gl_FragDepth = ${cfg.testPerspectiveForGl_FragDepth ? `${isPerspective} == 0.0 ? gl_FragCoord.z : ` : \"\"}log2(${getLogDepth(vFragDepth)}) * ${logDepthBufFC} * 0.5;`);\n            } else if (cfg.cleanerEdges) {\n                fragmentOutputs.push(`gl_FragDepth = gl_FragCoord.z + length(vec2(dFdx(gl_FragCoord.z), dFdy(gl_FragCoord.z)));`);\n            }\n\n            const linearToGamma = programVariables.createFragmentDefinition(\n                \"linearToGamma\",\n                (name, src) => {\n                    src.push(`vec4 ${name}(in vec4 value, in float gammaFactor) {`);\n                    src.push(\"  return vec4(pow(value.xyz, vec3(1.0 / gammaFactor)), value.w);\");\n                    src.push(\"}\");\n                });\n\n            const sectionPlanesState = cfg.sectionPlanesState;\n            const getClippingDistance = sectionPlanesState && (function() {\n                const allocatedUniforms = iota$3(sectionPlanesState.getNumAllocatedSectionPlanes()).map(i => {\n                    const sectionPlaneUniform = (type, postfix, getValue) => {\n                        return programVariables.createUniform(type, `sectionPlane${postfix}${i}`, (set, state) => {\n                            const sectionPlanes = sectionPlanesState.sectionPlanes;\n                            const numSectionPlanes = sectionPlanes.length;\n                            const baseIndex = (state.mesh.layerIndex || 0) * numSectionPlanes;\n                            const active = (i < numSectionPlanes) && state.mesh.renderFlags.sectionPlanesActivePerLayer[baseIndex + i];\n                            return getValue(set, active, sectionPlanes[i], state.mesh.origin);\n                        });\n                    };\n                    return {\n                        act: sectionPlaneUniform(\"bool\", \"Active\", (set, active) => set(active ? 1 : 0)),\n                        dir: sectionPlaneUniform(\"vec3\", \"Dir\",    (set, active, plane) => active && set(plane.dir)),\n                        pos: sectionPlaneUniform(\"vec3\", \"Pos\",    (set, active, plane, orig) => {\n                            return active && set(orig\n                                                 ? math.mulVec3Scalar(math.normalizeVec3(plane.dir, tempVec3a$f), -(math.dotVec3(plane.dir, orig) + plane.dist), tempVec3a$f) // getPlaneRTCPos\n                                                 : plane.pos);\n                        })\n                    };\n                });\n                return (allocatedUniforms.length > 0) && ((worldPosition) => allocatedUniforms.map(a => `(${a.act} ? clamp(dot(-${a.dir}, ${worldPosition} - ${a.pos}), 0.0, 1000.0) : 0.0)`).join(\" + \"));\n            })();\n\n            const crossSections = cfg.crossSections;\n            const sliceColorOr = (getClippingDistance\n                                  ? (function() {\n                                      const sliceColor = programVariables.createUniform(\"vec4\", \"sliceColor\", (set) => set(crossSections.sliceColor));\n                                      const sliceColorOr = color => {\n                                          sliceColorOr.needed = true;\n                                          return `(sliced ? ${sliceColor} : ${color})`;\n                                      };\n                                      return sliceColorOr;\n                                  })()\n                                  : (color => color));\n\n            const getGammaFactor = cfg.getGammaFactor;\n            const gammaFactor = programVariables.createUniform(\"float\", \"gammaFactor\", (set) => set(getGammaFactor()));\n            cfg.appendFragmentOutputs(fragmentOutputs, getGammaFactor && ((color) => `${linearToGamma}(${color}, ${gammaFactor})`), \"gl_FragCoord\", sliceColorOr);\n\n            const fragmentClippingLines = (function() {\n                const src = [ ];\n                const sliceThickness = programVariables.createUniform(\"float\", \"sliceThickness\", (set) => set(crossSections.sliceThickness));\n\n                if (getClippingDistance) {\n                    if (sliceColorOr.needed) {\n                        src.push(\"  bool sliced = false;\");\n                    }\n                    src.push(`  if (${cfg.clippableTest()}) {`);\n                    const fragWorldPosition = programVariables.createVarying(\"highp vec3\", \"vHighpWorldPosition\", () => `${cfg.worldPositionAttribute}.xyz`);\n                    src.push(`    float dist = ${getClippingDistance(fragWorldPosition)};`);\n                    if (cfg.clippingCaps) {\n                        const vClipPositionW = programVariables.createVarying(\"float\", \"vClipPositionW\", () => \"gl_Position.w\");\n                        src.push(`    if (dist > (0.002 * ${vClipPositionW})) { discard; }`);\n                        src.push(\"    if (dist > 0.0) { \");\n                        src.push(`      ${cfg.clippingCaps} = vec4(1.0, 0.0, 0.0, 1.0);`);\n                        getLogDepth && src.push(`      gl_FragDepth = log2(${getLogDepth(vFragDepth)}) * ${logDepthBufFC} * 0.5;`);\n                        src.push(\"      return;\");\n                        src.push(\"    }\");\n                    } else {\n                        src.push(`    if (dist > ${sliceColorOr.needed ? sliceThickness : \"0.0\"}) { discard; }`);\n                    }\n                    if (sliceColorOr.needed) {\n                        src.push(\"    sliced = dist > 0.0;\");\n                    }\n                    src.push(\"  }\");\n                }\n\n                return src;\n            })();\n\n            const fragDefinitions = (function() { const src = [ ]; fragDefAppenders.forEach(a => a(src)); return src; })();\n            const fragmentShader = [\n                ...(function() { const src = [ ]; fragAppenders.forEach(a => a(src)); return src; })(),\n                ...fragDefinitions,\n                \"void main(void) {\",\n                ...(cfg.discardPoints\n                    ? [\n                        \"  vec2 cxy = 2.0 * gl_PointCoord - 1.0;\",\n                        \"  if (dot(cxy, cxy) > 1.0) { discard; }\"\n                    ]\n                    : [ ]),\n                ...fragmentClippingLines,\n                ...fragmentOutputs,\n                \"}\"\n            ];\n\n            const vertexOutputs = [\n                `gl_Position = ${vertexClipPosition};`,\n                ...(cfg.getPointSize ? [ `gl_PointSize = ${cfg.getPointSize()};` ] : [ ]),\n                ...(function() { const src = [ ]; vOutAppenders.forEach(a => a(src)); return src; })()\n            ];\n\n            const vertexData = cfg.getVertexData ? cfg.getVertexData() : [ ];\n\n            const vertexShader = [\n                ...(function() { const src = [ ]; vertAppenders.forEach(a => a(src)); return src; })(),\n                \"void main(void) {\",\n                ...vertexData,\n                ...vertexOutputs,\n                \"}\"\n            ];\n\n            const preamble = (type) => [\n                \"#version 300 es\",\n                \"// \" + programName + \" \" + type + \" shader\",\n                \"#ifdef GL_FRAGMENT_PRECISION_HIGH\",\n                \"precision highp float;\",\n                \"precision highp int;\",\n                \"precision highp usampler2D;\",\n                \"precision highp isampler2D;\",\n                \"precision highp sampler2D;\",\n                \"#else\",\n                \"precision mediump float;\",\n                \"precision mediump int;\",\n                \"precision mediump usampler2D;\",\n                \"precision mediump isampler2D;\",\n                \"precision mediump sampler2D;\",\n                \"#endif\",\n            ];\n\n            const vertSrc = preamble(\"vertex\"  ).concat(vertexShader);\n            const fragSrc = preamble(\"fragment\").concat([\n                // Not the best place to define here, TODO: Move somewhere more appropriate after refactors\n                \"vec4 sRGBToLinear(in vec4 value) {\",\n                \"  return vec4(mix(pow(value.rgb * 0.9478672986 + 0.0521327014, vec3(2.4)), value.rgb * 0.0773993808, vec3(lessThanEqual(value.rgb, vec3(0.04045)))), value.w);\",\n                \"}\"\n            ]).concat(fragmentShader);\n\n            const makeShader = (type, srcLines) => {\n                const src = srcLines.join(\"\\n\");\n                const shader = gl.createShader(type);\n                gl.shaderSource(shader, src);\n                gl.compileShader(shader);\n                if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n                    return [ shader ];\n                } else {\n                    return [ null,\n                             [\n                                 \"Failed to compile\",\n                                 gl.getShaderInfoLog(shader),\n                                 src.split(\"\\n\").map((line, i) => (i + 1) + \": \" + line + \"\\n\").join(\"\")\n                             ]\n                           ];\n                }\n            };\n\n            const [vertShader, vertErrors] = makeShader(gl.VERTEX_SHADER,   vertSrc);\n            const [fragShader, fragErrors] = makeShader(gl.FRAGMENT_SHADER, fragSrc);\n\n            const errorObj = errors => {\n                console.error(errors.join(\"\\n\"));\n                return [ null, errors ];\n            };\n\n            if (vertErrors) {\n                return errorObj([\"Vertex shader error\"].concat(vertErrors));\n            } else if (fragErrors) {\n                return errorObj([\"Fragment shader error\"].concat(fragErrors));\n            } else {\n                const program = gl.createProgram();\n                if (! program) {\n                    return errorObj([\"Failed to allocate program\"]);\n                } else {\n                    gl.attachShader(program, vertShader);\n                    gl.attachShader(program, fragShader);\n                    gl.linkProgram(program);\n                    // HACK: Disable validation temporarily\n                    // Perhaps we should defer validation until render-time, when the program has values set for all inputs?\n                    if (! gl.getProgramParameter(program, gl.LINK_STATUS)) {\n                        return errorObj([\n                            \"\",\n                            gl.getProgramInfoLog(this.program),\n                            \"\",\n                            \"Vertex shader:\",\n                            \"\",\n                            ...vertSrc,\n                            \"\",\n                            \"Fragment shader:\",\n                            \"\",\n                            ...fragSrc\n                        ]);\n                    } else {\n                        const getInputSetter = makeInputSetters(gl, program);\n                        attrSetters.forEach(i => i(getInputSetter));\n                        const uSetters = unifSetters.map(i => i(getInputSetter)).filter(s => s);\n                        const id = ids$1.addItem({});\n                        return [ {\n                            id: id,\n                            bind: () => gl.useProgram(program),\n                            inputSetters: {\n                                attributesHash: attrHahes.sort().join(\", \"),\n                                setUniforms:   (frameCtx, state) => {\n                                    clipTransformSetup && clipTransformSetup.setClipPosInputValue(frameCtx);\n                                    uSetters.forEach(s => s(state));\n                                }\n                            },\n                            destroy: () => {\n                                ids$1.removeItem(id);\n                                gl.deleteProgram(program);\n                                gl.deleteShader(vertShader);\n                                gl.deleteShader(fragShader);\n                            }\n                        } ];\n                    }\n                }\n            }\n        }\n    };\n};\n\nconst createLightSetup = function(programVariables, lightsState) {\n    const lightAmbient = programVariables.createUniform(\"vec4\", \"lightAmbient\", (set) => set(lightsState.getAmbientColorAndIntensity()));\n\n    const lights = lightsState.lights;\n    const directionals = lights.map((light, i) => {\n        const lightUniforms = {\n            color: programVariables.createUniform(\"vec4\", `lightColor${i}`, (set) => {\n                const light = lights[i]; // in case it changed\n                tempVec4$3[0] = light.color[0];\n                tempVec4$3[1] = light.color[1];\n                tempVec4$3[2] = light.color[2];\n                tempVec4$3[3] = light.intensity;\n                set(tempVec4$3);\n            }),\n            position:  programVariables.createUniform(\"vec3\", `lightPos${i}`, (set) => set(lights[i].pos)),\n            direction: programVariables.createUniform(\"vec3\", `lightDir${i}`, (set) => set(lights[i].dir)),\n\n            shadowProjMatrix: programVariables.createUniform(\"mat4\", `shadowProjMatrix${i}`, (set) => set(lights[i].getShadowViewMatrix())),\n            shadowViewMatrix: programVariables.createUniform(\"mat4\", `shadowViewMatrix${i}`, (set) => set(lights[i].getShadowViewMatrix())),\n            shadowMap:        programVariables.createUniform(\"sampler2D\", `shadowMap${i}`, (set) => set(lights[i].getShadowRenderBuf().colorTextures[0]))\n        };\n\n        const withViewLightDir = getDirection => {\n            return {\n                glslLight: {\n                    isViewSpace: light.space === \"view\",\n                    getColor: () => `${lightUniforms.color}.rgb * ${lightUniforms.color}.a`,\n                    getDirection: (viewMatrix, viewPosition) => `normalize(${getDirection(viewMatrix, viewPosition)})`,\n                    shadowParameters: light.castsShadow && {\n                        getShadowProjMatrix: () => lightUniforms.shadowProjMatrix,\n                        getShadowViewMatrix: () => lightUniforms.shadowViewMatrix,\n                        getShadowMap:        () => lightUniforms.shadowMap\n                    }\n                },\n                setupLightsInputs: () => {\n                    const setters = Object.values(lightUniforms).map(u => u.setupLightsInputs()).filter(v => v);\n                    return () => setters.forEach(setState => setState());\n                }\n            };\n        };\n\n        if (light.type === \"dir\") {\n            if (light.space === \"view\") {\n                return withViewLightDir((viewMatrix, viewPosition) => `-${lightUniforms.direction}`);\n            } else {\n                // If normal mapping, the fragment->light vector will be in tangent space\n                return withViewLightDir((viewMatrix, viewPosition) => `-(${viewMatrix} * vec4(${lightUniforms.direction}, 0.0)).xyz`);\n            }\n        } else if (light.type === \"point\") {\n            if (light.space === \"view\") {\n                return withViewLightDir((viewMatrix, viewPosition) => `${lightUniforms.position} - ${viewPosition}`);\n            } else {\n                // If normal mapping, the fragment->light vector will be in tangent space\n                return withViewLightDir((viewMatrix, viewPosition) => `(${viewMatrix} * vec4(${lightUniforms.position}, 1.0)).xyz - ${viewPosition}`);\n            }\n        } else {\n            return null;\n        }\n    }).filter(v => v);\n\n    const setupCubeTexture = (name, getMaps) => {\n        const getValue = () => { const m = getMaps(); return (m.length > 0) && m[0]; };\n        const initMap = getValue();\n        return initMap && setupTexture(programVariables, \"samplerCube\", name, initMap.encoding, (set) => { const v = getValue(); v && set(v.texture); });\n    };\n\n    const lightMap      = setupCubeTexture(\"light\",      () => lightsState.lightMaps);\n    const reflectionMap = setupCubeTexture(\"reflection\", () => lightsState.reflectionMaps);\n\n    return {\n        getHash: () => lightsState.getHash(),\n        getAmbientColor: () => `${lightAmbient}.rgb * ${lightAmbient}.a`,\n        directionalLights: directionals.map(light => light.glslLight),\n        getIrradiance: lightMap      && ((worldNormal) => `${lightMap(worldNormal)}.rgb`),\n        getReflection: reflectionMap && ((reflectVec, mipLevel) => `${reflectionMap(reflectVec, mipLevel)}.rgb`)\n    };\n};\n\nconst setupTexture = (programVariables, type, name, encoding, getTexture) => {\n    const map = programVariables.createUniform(type, name + \"Map\", getTexture);\n    return (texturePos, bias) => {\n        const texel = (bias\n                       ? `texture(${map}, ${texturePos}, ${bias})`\n                       : `texture(${map}, ${texturePos})`);\n        return (encoding !== LinearEncoding) ? `${TEXTURE_DECODE_FUNCS[encoding]}(${texel})` : texel;\n    };\n};\n\nconst makeInputSetters = function(gl, handle) {\n    const activeInputs = { };\n\n    const numAttributes = gl.getProgramParameter(handle, gl.ACTIVE_ATTRIBUTES);\n    for (let i = 0; i < numAttributes; ++i) {\n        const attribute = gl.getActiveAttrib(handle, i);\n        const location = gl.getAttribLocation(handle, attribute.name);\n        activeInputs[attribute.name] = function(arrayBuf) {\n            arrayBuf.bindAtLocation(location);\n            gl.enableVertexAttribArray(location);\n            const divisor = arrayBuf.attributeDivisor;\n            if (divisor) {\n                gl.vertexAttribDivisor(location, divisor);\n            }\n        };\n        activeInputs[attribute.name].attributeHash = `${location.toString().padStart(1+Math.floor(Math.log10(numAttributes)), \"0\")}:${attribute.name}`;\n    }\n\n    const numBlocks = gl.getProgramParameter(handle, gl.ACTIVE_UNIFORM_BLOCKS);\n    for (let i = 0; i < numBlocks; ++i) {\n        const blockName = gl.getActiveUniformBlockName(handle, i);\n        const uniformBlockIndex = gl.getUniformBlockIndex(handle, blockName);\n        const uniformBlockBinding = i;\n        gl.uniformBlockBinding(handle, uniformBlockIndex, uniformBlockBinding);\n        const buffer = gl.createBuffer();\n        activeInputs[blockName] = function(data) {\n            gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);\n            gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW);\n            gl.bindBufferBase(gl.UNIFORM_BUFFER, uniformBlockBinding, buffer);\n        };\n    }\n\n    const numUniforms = gl.getProgramParameter(handle, gl.ACTIVE_UNIFORMS);\n    let nextUnit = 0;\n    for (let i = 0; i < numUniforms; ++i) {\n        const u = gl.getActiveUniform(handle, i);\n        let uName = u.name;\n        if (uName.endsWith(\"[0]\")) {\n            uName = uName.substr(0, uName.length - 3);\n        }\n        if (uName[uName.length - 1] === \"\\u0000\") {\n            uName = uName.substr(0, uName.length - 1);\n        }\n        const location = gl.getUniformLocation(handle, uName);\n        ((function() {\n            for (let k in gl) {\n                if (u.type === gl[k])\n                    return k;\n            }\n            return null;\n        }))();\n\n        if ((u.type === gl.SAMPLER_2D)\n            ||\n            (u.type === gl.SAMPLER_CUBE)\n            ||\n            (u.type === gl.SAMPLER_2D_SHADOW)\n            ||\n            ((gl instanceof window.WebGL2RenderingContext)\n             &&\n             ((u.type === gl.UNSIGNED_INT_SAMPLER_2D)\n              ||\n              (u.type === gl.INT_SAMPLER_2D)))) {\n            const unit = nextUnit++;\n            activeInputs[uName] = function(texture) {\n                const bound = texture.bind(unit);\n                if (bound) {\n                    gl.uniform1i(location, unit);\n                }\n                return bound;\n            };\n        } else {\n            activeInputs[uName] = (function() {\n                if (u.size === 1) {\n                    switch (u.type) {\n                    case gl.BOOL:       return value => gl.uniform1i(location, value);\n                    case gl.INT:        return value => gl.uniform1i(location, value);\n                    case gl.FLOAT:      return value => gl.uniform1f(location, value);\n                    case gl.FLOAT_VEC2: return value => gl.uniform2fv(location, value);\n                    case gl.FLOAT_VEC3: return value => gl.uniform3fv(location, value);\n                    case gl.FLOAT_VEC4: return value => gl.uniform4fv(location, value);\n                    case gl.FLOAT_MAT3: return value => gl.uniformMatrix3fv(location, false, value);\n                    case gl.FLOAT_MAT4: return value => gl.uniformMatrix4fv(location, false, value);\n                    }\n                } else if (u.size > 1) {\n                    switch (u.type) {\n                    case gl.FLOAT:      return value => gl.uniform1fv(location, value);\n                    case gl.FLOAT_VEC2: return value => gl.uniform2fv(location, value);\n                    case gl.FLOAT_VEC3: return value => gl.uniform3fv(location, value);\n                    case gl.FLOAT_VEC4: return value => gl.uniform4fv(location, value);\n                    }\n                }\n                throw `Unhandled uniform ${uName}`;\n            })();\n        }\n    }\n\n    return function(name) {\n        const u = activeInputs[name];\n        if (! u) {\n            throw `Missing input \"${name}\"`;\n        }\n        return u;\n    };\n};\n\nconst tempVec4$2 = math.vec4();\n\nconst DrawShaderSource = function(meshDrawHash, programVariables, geometry, material, scene) {\n    const materialState = material._state;\n    const phongMaterial    = (materialState.type === \"PhongMaterial\");\n    const metallicMaterial = (materialState.type === \"MetallicMaterial\");\n    const specularMaterial = (materialState.type === \"SpecularMaterial\");\n\n    const attributes = geometry.attributes;\n    const lightSetup = createLightSetup(programVariables, scene._lightsState);\n\n    const colorize = programVariables.createUniform(\"vec4\", \"colorize\", (set, state) => set(state.meshColorize));\n\n    const fresnel = programVariables.createFragmentDefinition(\n        \"fresnel\",\n        (name, src) => {\n            src.push(`float ${name}(vec3 eyeDir, vec3 normal, float edgeBias, float centerBias, float power) {`);\n            src.push(\"    float fr = abs(dot(eyeDir, normal));\");\n            src.push(\"    float finalFr = clamp((fr - edgeBias) / (centerBias - edgeBias), 0.0, 1.0);\");\n            src.push(\"    return pow(finalFr, power);\");\n            src.push(\"}\");\n        });\n\n    const setupFresnel = (name, colorSwizzle, getMaterialValue) => {\n        const fresnelUniform = (type, namePostfix, getParameterValue) => {\n            return programVariables.createUniform(type, name + \"Fresnel\" + namePostfix, (set, state) => set(getParameterValue(getMaterialValue(state.material))));\n        };\n        const edgeBias    = fresnelUniform(\"float\", \"EdgeBias\",    (fresnelValue => fresnelValue.edgeBias));\n        const centerBias  = fresnelUniform(\"float\", \"CenterBias\",  (fresnelValue => fresnelValue.centerBias));\n        const power       = fresnelUniform(\"float\", \"Power\",       (fresnelValue => fresnelValue.power));\n        const edgeColor   = fresnelUniform(\"vec3\",  \"EdgeColor\",   (fresnelValue => fresnelValue.edgeColor));\n        const centerColor = fresnelUniform(\"vec3\",  \"CenterColor\", (fresnelValue => fresnelValue.centerColor));\n\n        return getMaterialValue(material) && ((viewEyeDir, viewNormal) => {\n                const f = `${fresnel}(${viewEyeDir}, ${viewNormal}, ${edgeBias}, ${centerBias}, ${power})`;\n                return `mix(${edgeColor + colorSwizzle}, ${centerColor + colorSwizzle}, ${f})`;\n        });\n    };\n\n    const diffuseFresnel  = setupFresnel(\"diffuse\",  \"\",   mtl => mtl._diffuseFresnel);\n    const specularFresnel = setupFresnel(\"specular\", \"\",   mtl => mtl._specularFresnel);\n    const emissiveFresnel = setupFresnel(\"emissive\", \"\",   mtl => mtl._emissiveFresnel);\n    const alphaFresnel    = setupFresnel(\"alpha\",    \".r\", mtl => mtl._alphaFresnel);\n\n\n    const setup2dTexture = (name, getMaterialValue) => {\n        const initTex = attributes.uv && getMaterialValue(material);\n        const tex = initTex && setupTexture(programVariables, \"sampler2D\", name, initTex.encoding, (set, state) => set(getMaterialValue(state.material)._state.texture));\n        return tex && (function() {\n            const matrix = initTex._state.matrix && programVariables.createUniform(\"mat4\", name + \"MapMatrix\", (set, state) => set(getMaterialValue(state.material)._state.matrix));\n            const getTexCoordExpression = matrix ? (texPos => `(${matrix} * ${texPos}).st`) : (texPos => `${texPos}.st`);\n            const sample = (texturePos, bias) => tex(getTexCoordExpression(texturePos));\n            sample.getTexCoordExpression = getTexCoordExpression;\n            return sample;\n        })();\n    };\n\n    const ambientMap            = setup2dTexture(\"ambient\",            mtl => mtl._ambientMap);\n    const baseColorMap          = setup2dTexture(\"baseColor\",          mtl => mtl._baseColorMap);\n    const diffuseMap            = setup2dTexture(\"diffuse\",            mtl => mtl._diffuseMap);\n    const emissiveMap           = setup2dTexture(\"emissive\",           mtl => mtl._emissiveMap);\n    const occlusionMap          = setup2dTexture(\"occlusion\",          mtl => mtl._occlusionMap);\n    const alphaMap              = setup2dTexture(\"alpha\",              mtl => mtl._alphaMap);\n    const metallicMap           = setup2dTexture(\"metallic\",           mtl => mtl._metallicMap);\n    const roughnessMap          = setup2dTexture(\"roughness\",          mtl => mtl._roughnessMap);\n    const metallicRoughnessMap  = setup2dTexture(\"metallicRoughness\",  mtl => mtl._metallicRoughnessMap);\n    const specularMap           = setup2dTexture(\"specular\",           mtl => mtl._specularMap);\n    const glossinessMap         = setup2dTexture(\"glossiness\",         mtl => mtl._glossinessMap);\n    const specularGlossinessMap = setup2dTexture(\"specularGlossiness\", mtl => mtl._specularGlossinessMap);\n    const normalMap             = setup2dTexture(\"normal\",             mtl => mtl._normalMap);\n\n\n    const setupUniform = (name, type, getMaterialValue) => {\n        const initValue = getMaterialValue(material);\n        const isDefined = (type === \"float\") ? ((initValue !== undefined) && (initValue !== null)) : initValue;\n        return isDefined && programVariables.createUniform(type, name, (set, state) => set(getMaterialValue(state.material)));\n    };\n\n    const materialAmbient         = setupUniform(\"materialAmbient\",    \"vec3\",  mtl => mtl.ambient);\n    const materialDiffuse         = setupUniform(\"materialDiffuse\",    \"vec3\",  mtl => mtl.diffuse);\n    const materialBaseColor       = setupUniform(\"materialBaseColor\",  \"vec3\",  mtl => mtl.baseColor);\n    const materialEmissive        = setupUniform(\"materialEmissive\",   \"vec3\",  mtl => mtl.emissive);\n    const materialSpecular        = setupUniform(\"materialSpecular\",   \"vec3\",  mtl => mtl.specular);\n    const materialGlossiness      = setupUniform(\"materialGlossiness\", \"float\", mtl => mtl.glossiness);\n    const materialMetallic        = setupUniform(\"materialMetallic\",   \"float\", mtl => mtl.metallic);\n    const materialRoughness       = setupUniform(\"materialRoughness\",  \"float\", mtl => mtl.roughness);\n    const materialShininess       = setupUniform(\"materialShininess\",  \"float\", mtl => mtl.shininess);\n    const materialSpecularF0      = setupUniform(\"materialSpecularF0\", \"float\", mtl => mtl.specularF0);\n    const materialAlphaModeCutoff = setupUniform(\"materialAlphaModeCutoff\", \"vec4\",  mtl => {\n        const alpha = mtl.alpha;\n        if ((alpha !== undefined) && (alpha !== null)) {\n            tempVec4$2[0] = alpha;\n            tempVec4$2[1] = (mtl.alphaMode === 1 ? 1 : 0);\n            tempVec4$2[2] = mtl.alphaCutoff;\n            return tempVec4$2;\n        } else {\n            return null;\n        }\n    });\n\n    const vViewPosition = programVariables.createVarying(\"vec3\", \"vViewPosition\", () => `${attributes.position.view}.xyz`);\n    const texturePos = programVariables.createVarying(\"vec4\", \"texturePos\", () => `vec4(${attributes.uv}, 1.0, 1.0)`);\n    const vColor = attributes.color && programVariables.createVarying(\"vec4\", \"vColor\", () => attributes.color);\n\n    const vViewNormal = programVariables.createVarying(\"vec3\", \"vViewNormal\", () => attributes.normal.view);\n    const texUnitConverter = `mat4(0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0)`;\n    const vDirectionals = lightSetup.directionalLights.map((light, i) => ({\n        vViewLightReverseDir: programVariables.createVarying(\"vec3\", `vViewLightReverseDir${i}`, () => light.getDirection(geometry.viewMatrix, null)),\n        vShadowPosFromLight:  programVariables.createVarying(\"vec3\", `vShadowPosFromLight${i}`, () => `(${texUnitConverter} * ${light.shadowParameters.getShadowProjMatrix()} * (${light.shadowParameters.getShadowViewMatrix()} * ${attributes.position.world})).xyz`)\n    }));\n    const vWorldNormal = programVariables.createVarying(\"vec3\", \"vWorldNormal\", () => attributes.normal.world);\n\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n\n    const saturate = programVariables.createFragmentDefinition(\n        \"saturate\",\n        (name, src) => src.push(`float ${name}(const in float a) { return clamp(a, 0.0, 1.0); }`));\n\n    const BRDF_Specular_GGX = programVariables.createFragmentDefinition(\n        \"BRDF_Specular_GGX\",\n        (name, src) => {\n            src.push(\"vec3 F_Schlick(const in vec3 specularColor, const in float dotLH) {\");\n            src.push(\"   float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\");\n            src.push(\"   return ( 1.0 - specularColor ) * fresnel + specularColor;\");\n            src.push(\"}\");\n\n            src.push(\"float G_GGX_Smith(const in float alpha, const in float dotNL, const in float dotNV) {\");\n            src.push(\"   float a2 = ( alpha * alpha );\");\n            src.push(\"   float gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * ( dotNL * dotNL ) );\");\n            src.push(\"   float gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * ( dotNV * dotNV ) );\");\n            src.push(\"   return 1.0 / ( gl * gv );\");\n            src.push(\"}\");\n\n            src.push(\"float G_GGX_SmithCorrelated(const in float alpha, const in float dotNL, const in float dotNV) {\");\n            src.push(\"   float a2 = ( alpha * alpha );\");\n            src.push(\"   float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * ( dotNV * dotNV ) );\");\n            src.push(\"   float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * ( dotNL * dotNL ) );\");\n            src.push(\"   return 0.5 / max( gv + gl, 1e-6 );\");\n            src.push(\"}\");\n\n            src.push(\"float D_GGX(const in float alpha, const in float dotNH) {\");\n            src.push(\"   float a2 = ( alpha * alpha );\");\n            src.push(\"   float denom = ( dotNH * dotNH) * ( a2 - 1.0 ) + 1.0;\");\n            src.push(\"   return 0.31830988618 * a2 / ( denom * denom);\"); // 1/PI\n            src.push(\"}\");\n\n            src.push(`vec3 ${name}(const in vec3 incidentLightDirection, const in vec3 viewNormal, const in vec3 viewEyeDir, const in vec3 specularColor, const in float roughness) {`);\n            src.push(\"   float alpha = ( roughness * roughness );\");\n            src.push(\"   vec3 halfDir = normalize( incidentLightDirection + viewEyeDir );\");\n            src.push(`   float dotNL = ${saturate}( dot( viewNormal, incidentLightDirection ) );`);\n            src.push(`   float dotNV = ${saturate}( dot( viewNormal, viewEyeDir ) );`);\n            src.push(`   float dotNH = ${saturate}( dot( viewNormal, halfDir ) );`);\n            src.push(`   float dotLH = ${saturate}( dot( incidentLightDirection, halfDir ) );`);\n            src.push(\"   vec3  F = F_Schlick( specularColor, dotLH );\");\n            src.push(\"   float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\");\n            src.push(\"   float D = D_GGX( alpha, dotNH );\");\n            src.push(\"   return F * (G * D);\");\n            src.push(\"}\");\n        });\n\n    const BRDF_Specular_GGX_Environment = programVariables.createFragmentDefinition(\n        \"BRDF_Specular_GGX_Environment\",\n        (name, src) => {\n            src.push(`vec3 ${name}(const in vec3 viewNormal, const in vec3 viewEyeDir, const in vec3 specularColor, const in float roughness) {`);\n            src.push(`   float dotNV = ${saturate}(dot(viewNormal, viewEyeDir));`);\n            src.push(\"   const vec4 c0 = vec4( -1, -0.0275, -0.572,  0.022);\");\n            src.push(\"   const vec4 c1 = vec4(  1,  0.0425,   1.04, -0.04);\");\n            src.push(\"   vec4 r = roughness * c0 + c1;\");\n            src.push(\"   float a004 = min(r.x * r.x, exp2(-9.28 * dotNV)) * r.x + r.y;\");\n            src.push(\"   vec2 AB    = vec2(-1.04, 1.04) * a004 + r.zw;\");\n            src.push(\"   return specularColor * AB.x + AB.y;\");\n            src.push(\"}\");\n        });\n\n    const perturbNormal2Arb = programVariables.createFragmentDefinition(\n        \"perturbNormal2Arb\",\n        (name, src) => {\n            src.push(`vec3 ${name}( vec3 eye_pos, vec3 surf_norm, vec2 uv, vec4 texel ) {`);\n            src.push(\"      vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\");\n            src.push(\"      vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\");\n            src.push(\"      vec2 st0 = dFdx( uv.st );\");\n            src.push(\"      vec2 st1 = dFdy( uv.st );\");\n            src.push(\"      vec3 S = normalize( q0 * st1.t - q1 * st0.t );\");\n            src.push(\"      vec3 T = normalize( -q0 * st1.s + q1 * st0.s );\");\n            src.push(\"      vec3 N = normalize( surf_norm );\");\n            src.push(\"      vec3 mapN = texel.xyz * 2.0 - 1.0;\");\n            src.push(\"      mat3 tsn = mat3( S, T, N );\");\n            //     src.push(\"      mapN *= 3.0;\");\n            src.push(\"      return normalize( tsn * mapN );\");\n            src.push(\"}\");\n        });\n\n    return {\n        getHash: () => [\n            meshDrawHash,\n            scene.gammaOutput ? \"go\" : \"\",\n            lightSetup.getHash(),\n            material._state.hash\n        ],\n        programName: \"Draw\",\n        canActAsBackground: true,\n        discardPoints: true,\n        setupPointSize: true,\n        setsLineWidth: true,\n        appendFragmentOutputs: (src, getGammaOutputExpression, gl_FragCoord) => {\n            const hasNonAmbientLighting = attributes.normal && ((lightSetup.directionalLights.length > 0) || lightSetup.getIrradiance || lightSetup.getReflection);\n            src.push(`vec3 diffuseColor = ${(hasNonAmbientLighting && (phongMaterial || specularMaterial) && materialDiffuse) || (metallicMaterial && materialBaseColor) || \"vec3(1.0)\"};`);\n            src.push(`vec4 alphaModeCutoff = ${((phongMaterial || metallicMaterial || specularMaterial) && materialAlphaModeCutoff) || \"vec4(1.0, 0.0, 0.0, 0.0)\"};`);\n            src.push(\"float alpha = alphaModeCutoff[0];\");\n            (phongMaterial || metallicMaterial || specularMaterial) && alphaMap && src.push(`alpha *= ${alphaMap(texturePos)}.r;`);\n\n            if (vColor) {\n                src.push(`diffuseColor *= ${vColor}.rgb;`);\n                src.push(`alpha *= ${vColor}.a;`);\n            }\n            if (metallicMaterial && baseColorMap) {\n                src.push(\"vec4 baseColorTexel = \" + baseColorMap(texturePos) + \";\");\n                src.push(\"diffuseColor *= baseColorTexel.rgb;\");\n                src.push(\"alpha *= baseColorTexel.a;\");\n            }\n            if ((phongMaterial || specularMaterial) && diffuseMap) {\n                src.push(\"vec4 diffuseTexel = \" + diffuseMap(texturePos) + \";\");\n                src.push(\"diffuseColor *= diffuseTexel.rgb;\");\n                src.push(\"alpha *= diffuseTexel.a;\");\n            }\n\n            src.push(`vec3 emissiveColor = ${((phongMaterial || metallicMaterial || specularMaterial) && materialEmissive) || \"vec3(0.0)\"};`);\n            (phongMaterial || metallicMaterial || specularMaterial) && emissiveMap && src.push(`emissiveColor = ${emissiveMap(texturePos)}.rgb;`);\n\n            if (hasNonAmbientLighting) {\n\n                src.push(`vec3 specular    = ${((phongMaterial || specularMaterial) && materialSpecular)   || \"vec3(1.0)\"};`);\n                src.push(`float glossiness = ${(specularMaterial && materialGlossiness) || \"1.0\"};`);\n                src.push(`float metallic   = ${(metallicMaterial && materialMetallic)   || \"1.0\"};`);\n                src.push(`float roughness  = ${((metallicMaterial || specularMaterial) && materialRoughness)  || \"1.0\"};`);\n                src.push(`float shininess  = ${(phongMaterial && materialShininess)|| \"1.0\"};`);\n                src.push(`float specularF0 = ${(metallicMaterial && materialSpecularF0) || \"1.0\"};`);\n                src.push(`float occlusion  = ${((phongMaterial || metallicMaterial || specularMaterial) && occlusionMap) ? `${occlusionMap(texturePos)}.r` : \"1.0\"};`);\n\n                //--------------------------------------------------------------------------------\n                // SHADING\n                //--------------------------------------------------------------------------------\n\n                metallicMaterial && metallicMap  && src.push(`metallic  *= ${metallicMap(texturePos)}.r;`);\n                metallicMaterial && roughnessMap && src.push(`roughness *= ${roughnessMap(texturePos)}.r;`);\n\n                if (metallicMaterial && metallicRoughnessMap) {\n                    src.push(\"vec4 metalRoughTexel = \" + metallicRoughnessMap(texturePos) + \";\");\n                    src.push(\"metallic  *= metalRoughTexel.b;\");\n                    src.push(\"roughness *= metalRoughTexel.g;\");\n                }\n\n                (phongMaterial || specularMaterial) && specularMap && src.push(`specular *= ${specularMap(texturePos)}.rgb;`);\n                specularMaterial && glossinessMap && src.push(`glossiness *= ${glossinessMap(texturePos)}.r;`);\n\n                if (specularMaterial && specularGlossinessMap) {\n                    src.push(\"vec4 specGlossTexel = \" + specularGlossinessMap(texturePos) + \";\"); // TODO: what if only RGB texture?\n                    src.push(\"specular   *= specGlossTexel.rgb;\");\n                    src.push(\"glossiness *= specGlossTexel.a;\");\n                }\n\n                const vViewNormalized = `normalize(${vViewNormal})`;\n                const viewNormal = (((phongMaterial || metallicMaterial || specularMaterial) && normalMap)\n                                    ? `${perturbNormal2Arb}(${vViewPosition}, ${vViewNormalized}, ${normalMap.getTexCoordExpression(texturePos)}, ${normalMap(texturePos)})`\n                                    : vViewNormalized);\n                src.push(`vec3 viewNormal = ${viewNormal};`);\n\n                src.push(`vec3 viewEyeDir = normalize(-${vViewPosition});`);\n\n                diffuseFresnel  && src.push(`diffuseColor  *= ${diffuseFresnel (\"viewEyeDir\", \"viewNormal\")};`);\n                specularFresnel && src.push(`specular      *= ${specularFresnel(\"viewEyeDir\", \"viewNormal\")};`);\n                emissiveFresnel && src.push(`emissiveColor *= ${emissiveFresnel(\"viewEyeDir\", \"viewNormal\")};`);\n                alphaFresnel    && src.push(`alpha         *= ${alphaFresnel   (\"viewEyeDir\", \"viewNormal\")};`);\n\n                src.push(\"if (alphaModeCutoff[1] == 1.0 && alpha < alphaModeCutoff[2]) {\"); // ie. (alphaMode == \"mask\" && alpha < alphaCutoff)\n                src.push(\"   discard;\"); // TODO: Discard earlier within this shader?\n                src.push(\"}\");\n\n                src.push(\"vec3 material_diffuseColor;\");\n\n                if (phongMaterial) {\n                    src.push(\"material_diffuseColor = diffuseColor;\");\n                    src.push(\"roughness = 0.0;\");\n                }\n\n                if (specularMaterial) {\n                    src.push(\"float oneMinusSpecularStrength = 1.0 - max(max(specular.r, specular.g ),specular.b);\"); // Energy conservation\n                    src.push(\"material_diffuseColor = diffuseColor * oneMinusSpecularStrength;\");\n                    src.push(\"roughness = clamp(1.0 - glossiness, 0.04, 1.0);\");\n                }\n\n                if (metallicMaterial) {\n                    src.push(\"float dielectricSpecular = 0.16 * specularF0 * specularF0;\");\n                    src.push(\"material_diffuseColor = diffuseColor * (1.0 - dielectricSpecular) * (1.0 - metallic);\");\n                    src.push(\"roughness = clamp(roughness, 0.04, 1.0);\");\n                    src.push(\"specular = mix(vec3(dielectricSpecular), diffuseColor, metallic);\");\n                }\n\n                // ENVIRONMENT AND REFLECTION MAP SHADING\n\n                if (phongMaterial || metallicMaterial || specularMaterial) {\n                    src.push(\"const float PI = 3.14159265359;\");\n                    src.push(\"vec3 reflDiff = vec3(0.0);\");\n                    src.push(\"vec3 reflSpec = vec3(0.0);\");\n\n                    lightSetup.getIrradiance && src.push(`reflDiff += ${lightSetup.getIrradiance(`normalize(${vWorldNormal})`)};`);\n\n                    if (lightSetup.getReflection) {\n                        const reflectVec = `reflect(-viewEyeDir, viewNormal)`;\n                        const spec = (phongMaterial\n                                      ? `0.2 * PI * ${lightSetup.getReflection(reflectVec)}`\n                                      : (function() {\n                                          const blinnExpFromRoughness = `2.0 / pow(roughness + 0.0001, 2.0) - 2.0`;\n                                          const specularBRDFContrib = `${BRDF_Specular_GGX_Environment}(viewNormal, viewEyeDir, specular, roughness)`;\n\n                                          const viewReflectVec = `normalize((vec4(${reflectVec}, 0.0) * ${geometry.viewMatrix}).xyz)`;\n                                          const maxMIPLevelScalar = \"4.0\";\n                                          const desiredMIPLevel = `${maxMIPLevelScalar} - 0.39624 - 0.25 * log2(pow(${blinnExpFromRoughness}, 2.0) + 1.0)`;\n                                          const mipLevel = `clamp(${desiredMIPLevel}, 0.0, ${maxMIPLevelScalar})`; //TODO: a random factor - fix this\n                                          return `${specularBRDFContrib} * ${lightSetup.getReflection(viewReflectVec, mipLevel)}`;\n                                      })());\n                        src.push(`reflSpec += ${spec};`);\n                    }\n                    if (lightSetup.directionalLights.some(ligth => ligth.shadowParameters)) {\n                        src.push(\"const vec4 bitShift = vec4(1.0, 1.0/256.0, 1.0/(256.0 * 256.0), 1.0/(256.0*256.0*256.0));\");\n                        src.push(\"const float texelSize = 1.0 / 1024.0;\");\n                        src.push(\"float shadow;\");\n                        src.push(\"float fragmentDepth;\");\n                    }\n                    lightSetup.directionalLights.forEach((light, i) => {\n                        if (light.shadowParameters) {\n                            const shadowAcneRemover = \"0.007\";\n                            src.push(`fragmentDepth = ${vDirectionals[i].vShadowPosFromLight}.z - ${shadowAcneRemover};`);\n                            src.push(\"shadow = 0.0;\");\n                            src.push(\"for (int x = -3; x <= 3; x++) {\");\n                            src.push(\"  for (int y = -3; y <= 3; y++) {\");\n                            src.push(`      float texelDepth = dot(texture(${light.getShadowMap()}, ${vDirectionals[i].vShadowPosFromLight}.xy + vec2(x, y) * texelSize), bitShift);`);\n                            src.push(`      if (fragmentDepth < texelDepth) {`);\n                            src.push(\"          shadow += 1.0;\");\n                            src.push(\"      }\");\n                            src.push(\"  }\");\n                            src.push(\"}\");\n                            src.push(\"shadow /= 9.0;\");\n                        }\n                        src.push(`vec3 lightColor${i} = ${light.getColor()}${light.shadowParameters ? (\" * \" + \"shadow\") : \"\"};`);\n                        src.push(`vec3 lightDirection${i} = ${light.isViewSpace ? light.getDirection(null, vViewPosition) : vDirectionals[i].vViewLightReverseDir};`);\n                        const dotNL = `${saturate}(dot(viewNormal, lightDirection${i}))`;\n                        src.push(`vec3 irradiance${i} = ${dotNL} * lightColor${i};`);\n                        src.push(`reflDiff += irradiance${i};`);\n                        const spec = (phongMaterial\n                                      ? `lightColor${i} * specular * pow(max(dot(reflect(-lightDirection${i}, -viewNormal), viewEyeDir), 0.0), shininess)`\n                                      : `irradiance${i} * PI * ${BRDF_Specular_GGX}(lightDirection${i}, viewNormal, viewEyeDir, specular, roughness)`);\n                        src.push(`reflSpec += ${spec};`);\n                    });\n                }\n\n                const ambient = phongMaterial && `${lightSetup.getAmbientColor()} * diffuseColor`;\n                src.push(\"vec3 outgoingLight = emissiveColor + occlusion * (reflDiff * material_diffuseColor + reflSpec)\" + (ambient ? (\" + \" + ambient) : \"\") + \";\");\n            } else {\n                src.push(`vec3 ambientColor = ${(phongMaterial && materialAmbient) || \"vec3(1.0)\"};`);\n                phongMaterial && ambientMap && src.push(`ambientColor *= ${ambientMap(texturePos)}.rgb;`);\n                src.push(`ambientColor *= ${lightSetup.getAmbientColor()};`);\n                src.push(\"vec3 outgoingLight = emissiveColor + ambientColor;\");\n            }\n\n            src.push(`vec4 fragColor = ${colorize} * vec4(outgoingLight, alpha);`);\n\n            src.push(`${outColor} = ${getGammaOutputExpression ? getGammaOutputExpression(\"fragColor\") : \"fragColor\"};`);\n        }\n    };\n};\n\nconst LambertShaderSource = function(meshDrawHash, programVariables, geometry, material, scene) {\n    const lightSetup       = createLightSetup(programVariables, scene._lightsState);\n    const colorize         = programVariables.createUniform(\"vec4\",  \"colorize\",         (set, state) => set(state.meshColorize));\n    const materialAlpha    = programVariables.createUniform(\"float\", \"materialAlpha\",    (set, state) => set(state.material.alpha));\n    const materialColor    = programVariables.createUniform(\"vec3\",  \"materialColor\",    (set, state) => set(state.material.color));\n    const materialEmissive = programVariables.createUniform(\"vec3\",  \"materialEmissive\", (set, state) => set(state.material.emissive));\n    const vColor           = programVariables.createVarying(\"vec4\", \"vColor\", () => {\n        const attributes = geometry.attributes;\n        const lightComponents = [\n            lightSetup.getAmbientColor()\n        ].concat(attributes.normal\n                 ? lightSetup.directionalLights.map(\n                     light => `(max(dot(${attributes.normal.view}, ${light.getDirection(geometry.viewMatrix, attributes.position.view)}), 0.0) * ${light.getColor()})`)\n                 : [ ]);\n        return `${colorize} * vec4((${lightComponents.join(\" + \")}) * ${materialColor} + ${materialEmissive}, ${materialAlpha});`; // TODO: How to have ambient bright enough for canvas BG but not too bright for scene?\n    });\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n\n    return {\n        getHash: () => [\n            meshDrawHash,\n            scene.gammaOutput ? \"go\" : \"\",\n            lightSetup.getHash(),\n            material._state.hash\n        ],\n        programName: \"Lambert\",\n        canActAsBackground: true,\n        discardPoints: true,\n        setupPointSize: true,\n        setsLineWidth: true,\n        appendFragmentOutputs: (src, getGammaOutputExpression) => src.push(`${outColor} = ${getGammaOutputExpression ? getGammaOutputExpression(vColor) : vColor};`)\n    };\n};\n\nconst EmphasisShaderSource = function(meshHash, programVariables, geometry, scene, isFill) {\n    const lightSetup = isFill && createLightSetup(programVariables, scene._lightsState);\n    const uColor = programVariables.createUniform(\"vec3\",  \"uColor\", (set, state) => set(isFill ? state.material.fillColor : state.material.edgeColor));\n    const uAlpha = programVariables.createUniform(\"float\", \"uAlpha\", (set, state) => set(isFill ? state.material.fillAlpha : state.material.edgeAlpha));\n    const vColor = programVariables.createVarying(\"vec4\", \"vColor\", () => {\n        const attributes = geometry.attributes;\n        const lightComponents = isFill && [\n            lightSetup.getAmbientColor()\n        ].concat(attributes.normal\n                 ? lightSetup.directionalLights.map(\n                     light => `(max(dot(${attributes.normal.view}, ${light.getDirection(geometry.viewMatrix, attributes.position.view)}), 0.0) * ${light.getColor()})`)\n                 : [ ]);\n        // TODO: A blending mode for emphasis materials, to select add/multiply/mix\n        // `vec4((mix(reflectedColor, ${uColor}, 0.7)), ${uAlpha})`\n        return `vec4(${uColor}${lightComponents ? ` * (${lightComponents.join(\" + \")})` : \"\"}, ${uAlpha})`;\n        // `${vColor} = vec4(reflectedColor + ${uColor}, ${uAlpha})`\n    });\n\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        getHash: () => [\n            meshHash,\n            scene.gammaOutput ? \"go\" : \"\", // Gamma input not needed\n            lightSetup && lightSetup.getHash()\n        ],\n        programName: isFill ? \"EmphasisFill\" : \"EmphasisEdges\",\n        dontSetFrontFace: true,\n        discardPoints: isFill,\n        drawEdges: ! isFill,\n        appendFragmentOutputs: (src, getGammaOutputExpression) => src.push(`${outColor} = ${getGammaOutputExpression ? getGammaOutputExpression(vColor) : vColor};`)\n    };\n};\n\nconst tmpVec4 = math.vec4();\n\nconst PickMeshShaderSource = function(meshHash, programVariables) {\n    const pickColor = programVariables.createUniform(\"vec4\", \"pickColor\", (set, state) => {\n        var pickID = state.meshPickID; // Mesh-indexed color\n        tmpVec4[0] = pickID       & 0xFF;\n        tmpVec4[1] = pickID >>  8 & 0xFF;\n        tmpVec4[2] = pickID >> 16 & 0xFF;\n        tmpVec4[3] = pickID >> 24 & 0xFF;\n        math.mulVec4Scalar(tmpVec4, 1 / 255, tmpVec4);\n        set(tmpVec4);\n    });\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        getHash: () => [ meshHash ],\n        programName: \"PickMesh\",\n        isPick: true,\n        dontBillboardAnything: true,\n        appendFragmentOutputs: (src) => src.push(`${outColor} = ${pickColor};`)\n    };\n};\n\nconst PickTriangleShaderSource = function(meshHash, programVariables, geometry) {\n    const vColor = programVariables.createVarying(\"vec4\", \"vColor\", () => geometry.attributes.pickColor);\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        getHash: () => [ meshHash ],\n        programName: \"PickTriangle\",\n        isPick: true,\n        trianglePick: true,\n        dontBillboardAnything: true,\n        appendFragmentOutputs: (src) => src.push(`${outColor} = ${vColor};`)\n    };\n};\n\nconst OcclusionShaderSource = function(meshPickOcclusionHash, programVariables) {\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        getHash: () => [ meshPickOcclusionHash ],\n        programName: \"Occlusion\",\n        skipIfTransparent: true,\n        appendFragmentOutputs: (src) => src.push(`${outColor} = vec4(0.0, 0.0, 1.0, 1.0);`)\n    };\n};\n\nconst ShadowShaderSource = function(meshHash, programVariables) {\n    const encodeFloat = programVariables.createFragmentDefinition(\n        \"encodeFloat\",\n        (name, src) => {\n            src.push(`vec4 ${name}( const in float depth ) {`);\n            src.push(\"  const vec4 bitShift = vec4(256 * 256 * 256, 256 * 256, 256, 1.0);\");\n            src.push(\"  const vec4 bitMask = vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);\");\n            src.push(\"  vec4 comp = fract(depth * bitShift);\");\n            src.push(\"  comp -= comp.xxyz * bitMask;\");\n            src.push(\"  return comp;\");\n            src.push(\"}\");\n        });\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        getHash: () => [ meshHash ],\n        programName: \"Shadow\",\n        setsLineWidth: true,\n        useShadowView: true,\n        dontBillboardAnything: true,\n        dontGetLogDepth: true,\n        appendFragmentOutputs: (src, getGammaOutputExpression, gl_FragCoord) => src.push(`${outColor} = ${encodeFloat}(${gl_FragCoord}.z);`)\n    };\n};\n\n/**\n * Indicates what rendering needs to be done for the layers within a {@link Drawable}.\n *\n * Each Drawable has a RenderFlags in {@link Drawable#renderFlags}.\n *\n * Before rendering each frame, {@link Renderer} will call {@link Drawable#rebuildRenderFlags} on each {@link Drawable}.\n *\n * Then, when rendering a frame, Renderer will apply rendering passes to each Drawable according on what flags are set in {@link Drawable#renderFlags}.\n *\n * @private\n */\nclass RenderFlags {\n\n    /**\n     * @private\n     */\n    constructor() {\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate which layers are visible within the {@link Drawable}.\n         *\n         * This is a list of IDs of visible layers within the {@link Drawable}. The IDs will be whatever the\n         * {@link Drawable} uses to identify its layers, usually integers.\n         *\n         * @property visibleLayers\n         * @type {Number[]}\n         */\n        this.visibleLayers = [];\n\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate which {@link SectionPlane}s are active within each layer of the {@link Drawable}.\n         *\n         * Layout is as follows:\n         *\n         * ````[\n         *      false, false, true, // Layer 0, SectionPlanes 0, 1, 2\n         *      false, true, true,  // Layer 1, SectionPlanes 0, 1, 2\n         *      true, false, true   // Layer 2, SectionPlanes 0, 1, 2\n         * ]````\n         *\n         * @property sectionPlanesActivePerLayer\n         * @type {Boolean[]}\n         */\n        this.sectionPlanesActivePerLayer = [];\n\n        this.reset();\n    }\n\n    /**\n     * @private\n     */\n    reset() {\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate whether the {@link Drawable} is culled.\n         * \n         * When this is ````false````, then all of the other properties on ````RenderFlags```` will remain at their default values.\n         * \n         * @property culled\n         * @type {Boolean}\n         */\n        this.culled = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate whether the {@link Drawable} is sliced by any {@link SectionPlane}s.\n         *\n         * @property sectioned\n         * @type {Boolean}\n         */\n        this.sectioned  = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the number of layers within the {@link Drawable}.\n         *\n         * @property numLayers\n         * @type {Number}\n         */\n        this.numLayers = 0;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the number of visible layers within the {@link Drawable}.\n         *\n         * @property numVisibleLayers\n         * @type {Number}\n         */\n        this.numVisibleLayers = 0;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs {@link Drawable#drawColorOpaque}.\n         * @property colorOpaque\n         * @type {boolean}\n         */\n        this.colorOpaque = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs {@link Drawable#drawColorTransparent}.\n         * @property colorTransparent\n         * @type {boolean}\n         */\n        this.colorTransparent = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs {@link Drawable#drawEdgesColorOpaque}.\n         * @property edgesOpaque\n         * @type {boolean}\n         */\n        this.edgesOpaque = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs {@link Drawable#drawEdgesColorTransparent}.\n         * @property edgesTransparent\n         * @type {boolean}\n         */\n        this.edgesTransparent = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs an opaque {@link Drawable#drawSilhouetteXRayed}.\n         * @property xrayedSilhouetteOpaque\n         * @type {boolean}\n         */\n        this.xrayedSilhouetteOpaque = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs an opaque {@link Drawable#drawEdgesXRayed}.\n         * @property xrayedEdgesOpaque\n         * @type {boolean}\n         */\n        this.xrayedEdgesOpaque = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs a transparent {@link Drawable#drawSilhouetteXRayed}.\n         * @property xrayedSilhouetteTransparent\n         * @type {boolean}\n         */\n        this.xrayedSilhouetteTransparent = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs a transparent {@link Drawable#drawEdgesXRayed}.\n         * @property xrayedEdgesTransparent\n         * @type {boolean}\n         */\n        this.xrayedEdgesTransparent = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs an opaque {@link Drawable#drawSilhouetteHighlighted}.\n         * @property highlightedSilhouetteOpaque\n         * @type {boolean}\n         */\n        this.highlightedSilhouetteOpaque = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs an opaque {@link Drawable#drawEdgesHighlighted}.\n         * @property highlightedEdgesOpaque\n         * @type {boolean}\n         */\n        this.highlightedEdgesOpaque = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs a transparent {@link Drawable#drawSilhouetteHighlighted}.\n         * @property highlightedSilhouetteTransparent\n         * @type {boolean}\n         */\n        this.highlightedSilhouetteTransparent = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs a transparent {@link Drawable#drawEdgesHighlighted}.\n         * @property highlightedEdgesTransparent\n         * @type {boolean}\n         */\n        this.highlightedEdgesTransparent = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs an opaque {@link Drawable#drawSilhouetteSelected}.\n         * @property selectedSilhouetteOpaque\n         * @type {boolean}\n         */\n        this.selectedSilhouetteOpaque = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs an opaque {@link Drawable#drawEdgesSelected}.\n         * @property selectedEdgesOpaque\n         * @type {boolean}\n         */\n        this.selectedEdgesOpaque = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs a transparent {@link Drawable#drawSilhouetteSelected}.\n         * @property selectedSilhouetteTransparent\n         * @type {boolean}\n         */\n        this.selectedSilhouetteTransparent = false;\n\n        /**\n         * Set by {@link Drawable#rebuildRenderFlags} to indicate the {@link Drawable} needs a transparent {@link Drawable#drawEdgesSelected}.\n         * @property selectedEdgesTransparent\n         * @type {boolean}\n         */\n        this.selectedEdgesTransparent = false;\n    }\n}\n\n/**\n Fired when this Mesh is picked via a call to {@link Scene/pick:method\"}}Scene#pick(){{/crossLink}}.\n\n The event parameters will be the hit result returned by the {@link Scene/pick:method\"}}Scene#pick(){{/crossLink}} method.\n @event picked\n */\n\nconst obb = math.OBB3();\nconst angleAxis$1 = math.vec4();\nconst q1$1 = math.vec4();\nconst q2$1 = math.vec4();\nconst xAxis$1 = math.vec3([1, 0, 0]);\nconst yAxis$1 = math.vec3([0, 1, 0]);\nconst zAxis$1 = math.vec3([0, 0, 1]);\n\nconst veca = math.vec3(3);\nconst vecb = math.vec3(3);\n\nconst identityMat$1 = math.identityMat4();\n\nconst ids = new Map$1({});\nconst renderersCache = { };\n\n/**\n * @desc An {@link Entity} that is a drawable element, with a {@link Geometry} and a {@link Material}, that can be\n * connected into a scene graph using {@link Node}s.\n *\n * ## Usage\n *\n * The example below is the same as the one given for {@link Node}, since the two classes work together.  In this example,\n * we'll create a scene graph in which a root {@link Node} represents a group and the Meshes are leaves.\n *\n * Since {@link Node} implements {@link Entity}, we can designate the root {@link Node} as a model, causing it to be registered by its\n * ID in {@link Scene#models}.\n *\n * Since Mesh also implements {@link Entity}, we can designate the leaf Meshes as objects, causing them to\n * be registered by their IDs in {@link Scene#objects}.\n *\n * We can then find those {@link Entity} types in {@link Scene#models} and {@link Scene#objects}.\n *\n * We can also update properties of our object-Meshes via calls to {@link Scene#setObjectsHighlighted} etc.\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#sceneGraph)]\n *\n * ````javascript\n * import {Viewer, Mesh, Node, PhongMaterial, buildBoxGeometry, ReadableGeometry} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * const boxGeometry = new ReadableGeometry(viewer.scene, buildBoxGeometry({\n *      xSize: 1,\n *      ySize: 1,\n *      zSize: 1\n * }));\n *\n * new Node(viewer.scene, {\n *      id: \"table\",\n *      isModel: true, // <---------- Node represents a model, so is registered by ID in viewer.scene.models\n *      rotation: [0, 50, 0],\n *      position: [0, 0, 0],\n *      scale: [1, 1, 1],\n *\n *      children: [\n *\n *          new Mesh(viewer.scene, { // Red table leg\n *              id: \"redLeg\",\n *              isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n *              position: [-4, -6, -4],\n *              scale: [1, 3, 1],\n *              rotation: [0, 0, 0],\n *              material: new PhongMaterial(viewer.scene, {\n *                  diffuse: [1, 0.3, 0.3]\n *              }),\n *              geometry: boxGeometry\n *          }),\n *\n *          new Mesh(viewer.scene, { // Green table leg\n *              id: \"greenLeg\",\n *              isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n *              position: [4, -6, -4],\n *              scale: [1, 3, 1],\n *              rotation: [0, 0, 0],\n *              material: new PhongMaterial(viewer.scene, {\n *                  diffuse: [0.3, 1.0, 0.3]\n *              }),\n *              geometry: boxGeometry\n *          }),\n *\n *          new Mesh(viewer.scene, {// Blue table leg\n *              id: \"blueLeg\",\n *              isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n *              position: [4, -6, 4],\n *              scale: [1, 3, 1],\n *              rotation: [0, 0, 0],\n *              material: new PhongMaterial(viewer.scene, {\n *                  diffuse: [0.3, 0.3, 1.0]\n *              }),\n *              geometry: boxGeometry\n *          }),\n *\n *          new Mesh(viewer.scene, {  // Yellow table leg\n *              id: \"yellowLeg\",\n *              isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n *              position: [-4, -6, 4],\n *              scale: [1, 3, 1],\n *              rotation: [0, 0, 0],\n *              material: new PhongMaterial(viewer.scene, {\n *                   diffuse: [1.0, 1.0, 0.0]\n *              }),\n *              geometry: boxGeometry\n *          }),\n *\n *          new Mesh(viewer.scene, { // Purple table top\n *              id: \"tableTop\",\n *              isObject: true, // <------ Node represents an object, so is registered by ID in viewer.scene.objects\n *              position: [0, -3, 0],\n *              scale: [6, 0.5, 6],\n *              rotation: [0, 0, 0],\n *              material: new PhongMaterial(viewer.scene, {\n *                  diffuse: [1.0, 0.3, 1.0]\n *              }),\n *              geometry: boxGeometry\n *          })\n *      ]\n *  });\n *\n * // Find Nodes and Meshes by their IDs\n *\n * var table = viewer.scene.models[\"table\"];                // Since table Node has isModel == true\n *\n * var redLeg = viewer.scene.objects[\"redLeg\"];             // Since the Meshes have isObject == true\n * var greenLeg = viewer.scene.objects[\"greenLeg\"];\n * var blueLeg = viewer.scene.objects[\"blueLeg\"];\n *\n * // Highlight one of the table leg Meshes\n *\n * viewer.scene.setObjectsHighlighted([\"redLeg\"], true);    // Since the Meshes have isObject == true\n *\n * // Periodically update transforms on our Nodes and Meshes\n *\n * viewer.scene.on(\"tick\", function () {\n *\n *       // Rotate legs\n *       redLeg.rotateY(0.5);\n *       greenLeg.rotateY(0.5);\n *       blueLeg.rotateY(0.5);\n *\n *       // Rotate table\n *       table.rotateY(0.5);\n *       table.rotateX(0.3);\n *   });\n * ````\n *\n * ## Metadata\n *\n * As mentioned, we can also associate {@link MetaModel}s and {@link MetaObject}s with our {@link Node}s and Meshes,\n * within a {@link MetaScene}. See {@link MetaScene} for an example.\n *\n * @implements {Entity}\n * @implements {Drawable}\n */\nclass Mesh extends Component {\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent scene, generated automatically when omitted.\n     * @param {String} [cfg.originalSystemId] ID of the corresponding object within the originating system, if any.\n     * @param {Boolean} [cfg.isModel] Specify ````true```` if this Mesh represents a model, in which case the Mesh will be registered by {@link Mesh#id} in {@link Scene#models} and may also have a corresponding {@link MetaModel} with matching {@link MetaModel#id}, registered by that ID in {@link MetaScene#metaModels}.\n     * @param {Boolean} [cfg.isObject] Specify ````true```` if this Mesh represents an object, in which case the Mesh will be registered by {@link Mesh#id} in {@link Scene#objects} and may also have a corresponding {@link MetaObject} with matching {@link MetaObject#id}, registered by that ID in {@link MetaScene#metaObjects}.\n     * @param {Node} [cfg.parent] The parent Node.\n     * @param {Number[]} [cfg.origin] World-space origin for this Mesh. When this is given, then ````matrix````, ````position```` and ````geometry```` are all assumed to be relative to this center.\n     * @param {Number[]} [cfg.rtcCenter] Deprecated - renamed to ````origin````.\n     * @param {Number[]} [cfg.position=[0,0,0]] 3D position of this Mesh, relative to ````origin````.\n     * @param {Number[]} [cfg.scale=[1,1,1]] Local scale.\n     * @param {Number[]} [cfg.rotation=[0,0,0]] Local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Local modelling transform matrix. Overrides the position, scale and rotation parameters.\n     * @param {Number[]} [cfg.offset=[0,0,0]] World-space 3D translation offset. Translates the Mesh in World space, after modelling transforms.\n     * @param {Boolean} [cfg.occluder=true] Indicates if the Mesh is able to occlude {@link Marker}s.\n     * @param {Boolean} [cfg.visible=true] Indicates if the Mesh is initially visible.\n     * @param {Boolean} [cfg.culled=false] Indicates if the Mesh is initially culled from view.\n     * @param {Boolean} [cfg.pickable=true] Indicates if the Mesh is initially pickable.\n     * @param {Boolean} [cfg.clippable=true] Indicates if the Mesh is initially clippable.\n     * @param {Boolean} [cfg.collidable=true] Indicates if the Mesh is initially included in boundary calculations.\n     * @param {Boolean} [cfg.castsShadow=true] Indicates if the Mesh initially casts shadows.\n     * @param {Boolean} [cfg.receivesShadow=true]  Indicates if the Mesh initially receives shadows.\n     * @param {Boolean} [cfg.xrayed=false] Indicates if the Mesh is initially xrayed.\n     * @param {Boolean} [cfg.highlighted=false] Indicates if the Mesh is initially highlighted.\n     * @param {Boolean} [cfg.selected=false] Indicates if the Mesh is initially selected.\n     * @param {Boolean} [cfg.edges=false] Indicates if the Mesh's edges are initially emphasized.\n     * @param {Boolean} [cfg.background=false] Indicates if the Mesh should act as background, e.g., it can be used for a skybox.\n     * @param {Number[]} [cfg.colorize=[1.0,1.0,1.0]] Mesh's initial RGB colorize color, multiplies by the rendered fragment colors.\n     * @param {Number} [cfg.opacity=1.0] Mesh's initial opacity factor, multiplies by the rendered fragment alpha.\n     * @param {String} [cfg.billboard=\"none\"] Mesh's billboarding behaviour. Options are \"none\" for no billboarding, \"spherical\" to always directly face {@link Camera.eye}, rotating both vertically and horizontally, or \"cylindrical\" to face the {@link Camera#eye} while rotating only about its vertically axis (use that mode for things like trees on a landscape).\n     * @param {Geometry} [cfg.geometry] {@link Geometry} to define the shape of this Mesh. Inherits {@link Scene#geometry} by default.\n     * @param {Material} [cfg.material] {@link Material} to define the normal rendered appearance for this Mesh. Inherits {@link Scene#material} by default.\n     * @param {EmphasisMaterial} [cfg.xrayMaterial] {@link EmphasisMaterial} to define the xrayed appearance for this Mesh. Inherits {@link Scene#xrayMaterial} by default.\n     * @param {EmphasisMaterial} [cfg.highlightMaterial] {@link EmphasisMaterial} to define the xrayed appearance for this Mesh. Inherits {@link Scene#highlightMaterial} by default.\n     * @param {EmphasisMaterial} [cfg.selectedMaterial] {@link EmphasisMaterial} to define the selected appearance for this Mesh. Inherits {@link Scene#selectedMaterial} by default.\n     * @param {EmphasisMaterial} [cfg.edgeMaterial] {@link EdgeMaterial} to define the appearance of enhanced edges for this Mesh. Inherits {@link Scene#edgeMaterial} by default.\n     * @param {Number} [cfg.renderOrder=0] Specifies the rendering order for this mESH. This is used to control the order in which\n     * mESHES are drawn when they have transparent objects, to give control over the order in which those objects are blended within the transparent\n     * render pass.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this.renderOrder = cfg.renderOrder || 0;\n\n        /**\n         * ID of the corresponding object within the originating system, if any.\n         *\n         * @type {String}\n         * @abstract\n         */\n        this.originalSystemId = (cfg.originalSystemId || this.id);\n\n        /** @private **/\n        this.renderFlags = new RenderFlags();\n\n        this._state = new RenderState({ // NOTE: Renderer gets modeling and normal matrices from Mesh#matrix and Mesh.#normalWorldMatrix\n            visible: true,\n            culled: false,\n            pickable: null,\n            clippable: null,\n            collidable: null,\n            occluder: (cfg.occluder !== false),\n            castsShadow: null,\n            receivesShadow: null,\n            xrayed: false,\n            highlighted: false,\n            selected: false,\n            edges: false,\n            stationary: !!cfg.stationary,\n            background: !!cfg.background,\n            billboard: this._checkBillboard(cfg.billboard),\n            layer: null,\n            colorize: null,\n            pickID: this.scene._renderer.getPickID(this),\n            drawHash: \"\",\n            pickOcclusionHash: \"\",\n            offset: math.vec3(),\n            origin: null,\n            originHash: null,\n            isUI: cfg.isUI\n        });\n\n        const material = cfg.material ? this._checkComponent2([\"PhongMaterial\", \"MetallicMaterial\", \"SpecularMaterial\", \"LambertMaterial\"], cfg.material) : this.scene.material;\n\n        const mesh = this;\n\n        const wrapRenderer = (getProgramSetup) => {\n            let instance = null;\n            const ensureInstance = () => {\n                if (! instance) {\n                    const programVariablesState = createProgramVariablesState();\n                    const createAttribute = programVariablesState.programVariables.createAttribute;\n                    const geometryState = mesh._geometry._state;\n                    const attributes = {\n                        position:  createAttribute(\"vec3\", \"position\"),\n                        color:     geometryState.colorsBuf && createAttribute(\"vec4\", \"color\"),\n                        pickColor: createAttribute(\"vec4\", \"pickColor\"),\n                        uv:        geometryState.uvBuf && createAttribute(\"vec2\", \"uv\"),\n                        normal:    (geometryState.autoVertexNormals || geometryState.normalsBuf) && [ \"triangles\", \"triangle-strip\", \"triangle-fan\" ].includes(geometryState.primitiveName) && createAttribute(\"vec3\", \"normal\")\n                    };\n\n                    const lazyShaderVariable = function(name) {\n                        const variable = {\n                            toString: () => {\n                                variable.needed = true;\n                                return name;\n                            }\n                        };\n                        return variable;\n                    };\n                    const worldNormal = attributes.normal && lazyShaderVariable(\"worldNormal\");\n                    const viewNormal  = worldNormal && lazyShaderVariable(\"viewNormal\");\n                    const decodedUv = attributes.uv && lazyShaderVariable(\"decodedUv\");\n\n                    const programSetup = getProgramSetup(\n                        programVariablesState.programVariables,\n                        {\n                            attributes: {\n                                position:  {\n                                    world: \"worldPosition\",\n                                    view:  \"viewPosition\"\n                                },\n                                color:     attributes.color,\n                                pickColor: attributes.pickColor,\n                                uv:        decodedUv,\n                                normal:    attributes.normal && {\n                                    world: worldNormal,\n                                    view:  viewNormal\n                                }\n                            },\n                            viewMatrix: \"viewMatrix2\"\n                        });\n                    const hash = [\n                        programSetup.programName,\n                        mesh.scene.canvas.canvas.id,\n                        mesh.scene._sectionPlanesState.getHash(),\n                        mesh._geometry._state.hash\n                    ].concat(programSetup.getHash()).join(\";\");\n                    if (! (hash in renderersCache)) {\n                        const renderer = instantiateMeshRenderer(mesh, attributes, { decodedUv: decodedUv, worldNormal: worldNormal, viewNormal: viewNormal }, programSetup, programVariablesState);\n                        if (renderer.errors) {\n                            console.log(renderer.errors.join(\"\\n\"));\n                            return;\n                        }\n                        const id = ids.addItem({});\n                        renderersCache[hash] = {\n                            drawMesh: renderer.drawMesh,\n                            id: id,\n                            useCount: 0,\n                            delete: () => {\n                                ids.removeItem(id);\n                                renderer.destroy();\n                                delete renderersCache[hash];\n                                stats.memory.programs--;\n                            }\n                        };\n                        stats.memory.programs++;\n                    }\n                    instance = renderersCache[hash];\n                    instance.useCount++;\n                }\n            };\n            return {\n                get:      ensureInstance,\n                getId:    () => instance.id,\n                put:      () => { if (instance) { if (--instance.useCount === 0) { instance.delete(); } instance = null; } },\n                drawMesh: (frameCtx, mesh, material) => {\n                    ensureInstance();\n                    instance && instance.drawMesh(frameCtx, mesh, material);\n                }\n            };\n        };\n\n        const scene = mesh.scene;\n        const emphasisShaderSourceMaker = isFill => (vars, geo) => EmphasisShaderSource(mesh._state.hash, vars, geo, scene, isFill);\n        this._renderers = {\n            _drawRenderer:          wrapRenderer((vars, geo) => ((material.type === \"LambertMaterial\")\n                                                                 ? LambertShaderSource(mesh._state.drawHash, vars, geo, material, scene)\n                                                                 : DrawShaderSource   (mesh._state.drawHash, vars, geo, material, scene))),\n            _shadowRenderer:        wrapRenderer((vars) => ShadowShaderSource(mesh._state.hash, vars)),\n            _emphasisEdgesRenderer: wrapRenderer(emphasisShaderSourceMaker(false)),\n            _emphasisFillRenderer:  wrapRenderer(emphasisShaderSourceMaker(true)),\n            _pickMeshRenderer:      wrapRenderer((vars) => PickMeshShaderSource(mesh._state.hash, vars)),\n            _pickTriangleRenderer:  wrapRenderer((vars, geo) => PickTriangleShaderSource(mesh._state.hash, vars, geo)),\n            _occlusionRenderer:     wrapRenderer((vars) => OcclusionShaderSource(mesh._state.pickOcclusionHash, vars))\n        };\n\n        this._geometry = cfg.geometry ? this._checkComponent2([\"ReadableGeometry\", \"VBOGeometry\"], cfg.geometry) : this.scene.geometry;\n        this._material = material;\n        this._xrayMaterial = cfg.xrayMaterial ? this._checkComponent(\"EmphasisMaterial\", cfg.xrayMaterial) : this.scene.xrayMaterial;\n        this._highlightMaterial = cfg.highlightMaterial ? this._checkComponent(\"EmphasisMaterial\", cfg.highlightMaterial) : this.scene.highlightMaterial;\n        this._selectedMaterial = cfg.selectedMaterial ? this._checkComponent(\"EmphasisMaterial\", cfg.selectedMaterial) : this.scene.selectedMaterial;\n        this._edgeMaterial = cfg.edgeMaterial ? this._checkComponent(\"EdgeMaterial\", cfg.edgeMaterial) : this.scene.edgeMaterial;\n\n        this._parentNode = null;\n\n        this._aabb = null;\n        this._aabbDirty = true;\n\n        this._numTriangles = (this._geometry ? this._geometry.numTriangles : 0);\n\n        this.scene._aabbDirty = true;\n\n        this._scale = math.vec3();\n        this._quaternion = math.identityQuaternion();\n        this._rotation = math.vec3();\n        this._position = math.vec3();\n\n        this._worldMatrix = math.identityMat4();\n        this._worldNormalMatrix = math.identityMat4();\n\n        this._localMatrixDirty = true;\n        this._worldMatrixDirty = true;\n        this._worldNormalMatrixDirty = true;\n\n        const origin = cfg.origin || cfg.rtcCenter;\n        if (origin) {\n            this._state.origin = math.vec3(origin);\n            this._state.originHash = origin.join();\n        }\n\n        if (cfg.matrix) {\n            this.matrix = cfg.matrix;\n        } else {\n            this.scale = cfg.scale;\n            this.position = cfg.position;\n            if (cfg.quaternion) ; else {\n                this.rotation = cfg.rotation;\n            }\n        }\n\n        this._isObject = cfg.isObject;\n        if (this._isObject) {\n            this.scene._registerObject(this);\n        }\n\n        this._isModel = cfg.isModel;\n        if (this._isModel) {\n            this.scene._registerModel(this);\n        }\n\n        this.visible = cfg.visible;\n        this.culled = cfg.culled;\n        this.pickable = cfg.pickable;\n        this.clippable = cfg.clippable;\n        this.collidable = cfg.collidable;\n        this.castsShadow = cfg.castsShadow;\n        this.receivesShadow = cfg.receivesShadow;\n        this.xrayed = cfg.xrayed;\n        this.highlighted = cfg.highlighted;\n        this.selected = cfg.selected;\n        this.edges = cfg.edges;\n        this.layer = cfg.layer;\n        this.colorize = cfg.colorize;\n        this.opacity = cfg.opacity;\n        this.offset = cfg.offset;\n\n        if (cfg.parentId) {\n            const parentNode = this.scene.components[cfg.parentId];\n            if (!parentNode) {\n                this.error(\"Parent not found: '\" + cfg.parentId + \"'\");\n            } else if (!parentNode.isNode) {\n                this.error(\"Parent is not a Node: '\" + cfg.parentId + \"'\");\n            } else {\n                parentNode.addChild(this);\n            }\n            this._parentNode = parentNode;\n        } else if (cfg.parent) {\n            if (!cfg.parent.isNode) {\n                this.error(\"Parent is not a Node\");\n            }\n            cfg.parent.addChild(this);\n            this._parentNode = cfg.parent;\n        }\n\n        this.compile();\n    }\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Mesh\";\n    }\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Mesh members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns true to indicate that this Component is a Mesh.\n     * @final\n     * @type {Boolean}\n     */\n    get isMesh() {\n        return true;\n    }\n\n    /**\n     * The parent Node.\n     *\n     * The parent Node may also be set by passing the Mesh to the parent's {@link Node#addChild} method.\n     *\n     * @type {Node}\n     */\n    get parent() {\n        return this._parentNode;\n    }\n\n    /**\n     * Defines the shape of this Mesh.\n     *\n     * Set to {@link Scene#geometry} by default.\n     *\n     * @type {Geometry}\n     */\n    get geometry() {\n        return this._geometry;\n    }\n\n    /**\n     * Defines the appearance of this Mesh when rendering normally, ie. when not xrayed, highlighted or selected.\n     *\n     * Set to {@link Scene#material} by default.\n     *\n     * @type {Material}\n     */\n    get material() {\n        return this._material;\n    }\n\n    /**\n     * Gets the Mesh's local translation.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    get position() {\n        return this._position;\n    }\n\n    /**\n     * Sets the Mesh's local translation.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    set position(value) {\n        this._position.set(value || [0, 0, 0]);\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Mesh's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    get rotation() {\n        return this._rotation;\n    }\n\n    /**\n     * Sets the Mesh's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    set rotation(value) {\n        this._rotation.set(value || [0, 0, 0]);\n        math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Mesh's local rotation quaternion.\n     *\n     * Default value is ````[0,0,0,1]````.\n     *\n     * @type {Number[]}\n     */\n    get quaternion() {\n        return this._quaternion;\n    }\n\n    /**\n     * Sets the Mesh's local rotation quaternion.\n     *\n     * Default value is ````[0,0,0,1]````.\n     *\n     * @type {Number[]}\n     */\n    set quaternion(value) {\n        this._quaternion.set(value || [0, 0, 0, 1]);\n        math.quaternionToEuler(this._quaternion, \"XYZ\", this._rotation);\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Mesh's local scale.\n     *\n     * Default value is ````[1,1,1]````.\n     *\n     * @type {Number[]}\n     */\n    get scale() {\n        return this._scale;\n    }\n\n    /**\n     * Sets the Mesh's local scale.\n     *\n     * Default value is ````[1,1,1]````.\n     *\n     * @type {Number[]}\n     */\n    set scale(value) {\n        this._scale.set(value || [1, 1, 1]);\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Mesh's local modeling transform matrix.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @type {Number[]}\n     */\n    get matrix() {\n        if (this._localMatrixDirty) {\n            if (!this.__localMatrix) {\n                this.__localMatrix = math.identityMat4();\n            }\n            math.composeMat4(this._position, this._quaternion, this._scale, this.__localMatrix);\n            this._localMatrixDirty = false;\n        }\n        return this.__localMatrix;\n    }\n\n    /**\n     * Sets the Mesh's local modeling transform matrix.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @type {Number[]}\n     */\n    set matrix(value) {\n        if (!this.__localMatrix) {\n            this.__localMatrix = math.identityMat4();\n        }\n        this.__localMatrix.set(value || identityMat$1);\n        math.decomposeMat4(this.__localMatrix, this._position, this._quaternion, this._scale);\n        this._localMatrixDirty = false;\n        this._setWorldMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Mesh's World matrix.\n     *\n     * @property worldMatrix\n     * @type {Number[]}\n     */\n    get worldMatrix() {\n        if (this._worldMatrixDirty) {\n            this._buildWorldMatrix();\n        }\n        return this._worldMatrix;\n    }\n\n    /**\n     * Gets the Mesh's World normal matrix.\n     *\n     * @type {Number[]}\n     */\n    get worldNormalMatrix() {\n        if (this._worldNormalMatrixDirty) {\n            this._buildWorldNormalMatrix();\n        }\n        return this._worldNormalMatrix;\n    }\n\n    /**\n     * Returns true to indicate that Mesh implements {@link Entity}.\n     *\n     * @returns {Boolean}\n     */\n    get isEntity() {\n        return true;\n    }\n\n    /**\n     * Returns ````true```` if this Mesh represents a model.\n     *\n     * When this returns ````true````, the Mesh will be registered by {@link Mesh#id} in {@link Scene#models} and\n     * may also have a corresponding {@link MetaModel}.\n     *\n     * @type {Boolean}\n     */\n    get isModel() {\n        return this._isModel;\n    }\n\n    /**\n     * Returns ````true```` if this Mesh represents an object.\n     *\n     * When this returns ````true````, the Mesh will be registered by {@link Mesh#id} in {@link Scene#objects} and\n     * may also have a corresponding {@link MetaObject}.\n     *\n     * @type {Boolean}\n     */\n    get isObject() {\n        return this._isObject;\n    }\n\n    /**\n     * Returns ````true```` if this Mesh is an UI object.\n     *\n     * @type {Boolean}\n     */\n    get isUI() {\n        return this._state.isUI;\n    }\n\n    /**\n     * Gets the Mesh's World-space 3D axis-aligned bounding box.\n     *\n     * Represented by a six-element Float64Array containing the min/max extents of the\n     * axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n     *\n     * @type {Number[]}\n     */\n    get aabb() {\n        if (this._aabbDirty) {\n            this._updateAABB();\n        }\n        return this._aabb;\n    }\n\n    /**\n     * Gets the 3D origin of the Mesh's {@link Geometry}'s vertex positions.\n     *\n     * When this is given, then {@link Mesh#matrix}, {@link Mesh#position} and {@link Mesh#geometry} are all assumed to be relative to this center position.\n     *\n     * @type {Float64Array}\n     */\n    get origin() {\n        return this._state.origin;\n    }\n\n    /**\n     * Sets the 3D origin of the Mesh's {@link Geometry}'s vertex positions.\n     *\n     * When this is given, then {@link Mesh#matrix}, {@link Mesh#position} and {@link Mesh#geometry} are all assumed to be relative to this center position.\n     *\n     * @type {Float64Array}\n     */\n    set origin(origin) {\n        if (origin) {\n            if (!this._state.origin) {\n                this._state.origin = math.vec3();\n            }\n            this._state.origin.set(origin);\n            this._state.originHash = origin.join();\n            this._setAABBDirty();\n            this.scene._aabbDirty = true;\n        } else {\n            if (this._state.origin) {\n                this._state.origin = null;\n                this._state.originHash = null;\n                this._setAABBDirty();\n                this.scene._aabbDirty = true;\n            }\n        }\n    }\n\n    /**\n     * Gets the World-space origin for this Mesh.\n     *\n     * Deprecated and replaced by {@link Mesh#origin}.\n     *\n     * @deprecated\n     * @type {Float64Array}\n     */\n    get rtcCenter() {\n        return this.origin;\n    }\n\n    /**\n     * Sets the World-space origin for this Mesh.\n     *\n     * Deprecated and replaced by {@link Mesh#origin}.\n     *\n     * @deprecated\n     * @type {Float64Array}\n     */\n    set rtcCenter(rtcCenter) {\n        this.origin = rtcCenter;\n    }\n\n    /**\n     * The approximate number of triangles in this Mesh.\n     *\n     * @type {Number}\n     */\n    get numTriangles() {\n        return this._numTriangles;\n    }\n\n    /**\n     * Gets if this Mesh is visible.\n     *\n     * Only rendered when {@link Mesh#visible} is ````true```` and {@link Mesh#culled} is ````false````.\n     *\n     * When {@link Mesh#isObject} and {@link Mesh#visible} are both ````true```` the Mesh will be\n     * registered by {@link Mesh#id} in {@link Scene#visibleObjects}.\n     *\n     * @type {Boolean}\n     */\n    get visible() {\n        return this._state.visible;\n    }\n\n    /**\n     * Sets if this Mesh is visible.\n     *\n     * Only rendered when {@link Mesh#visible} is ````true```` and {@link Mesh#culled} is ````false````.\n     *\n     * When {@link Mesh#isObject} and {@link Mesh#visible} are both ````true```` the Mesh will be\n     * registered by {@link Mesh#id} in {@link Scene#visibleObjects}.\n     *\n     * @type {Boolean}\n     */\n    set visible(visible) {\n        visible = visible !== false;\n        this._state.visible = visible;\n        if (this._isObject) {\n            this.scene._objectVisibilityUpdated(this, visible);\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this Mesh is xrayed.\n     *\n     * XRayed appearance is configured by the {@link EmphasisMaterial} referenced by {@link Mesh#xrayMaterial}.\n     *\n     * When {@link Mesh#isObject} and {@link Mesh#xrayed} are both ````true``` the Mesh will be\n     * registered by {@link Mesh#id} in {@link Scene#xrayedObjects}.\n     *\n     * @type {Boolean}\n     */\n    get xrayed() {\n        return this._state.xrayed;\n    }\n\n    /**\n     * Sets if this Mesh is xrayed.\n     *\n     * XRayed appearance is configured by the {@link EmphasisMaterial} referenced by {@link Mesh#xrayMaterial}.\n     *\n     * When {@link Mesh#isObject} and {@link Mesh#xrayed} are both ````true``` the Mesh will be\n     * registered by {@link Mesh#id} in {@link Scene#xrayedObjects}.\n     *\n     * @type {Boolean}\n     */\n    set xrayed(xrayed) {\n        xrayed = !!xrayed;\n        if (this._state.xrayed === xrayed) {\n            return;\n        }\n        this._state.xrayed = xrayed;\n        if (this._isObject) {\n            this.scene._objectXRayedUpdated(this, xrayed);\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this Mesh is highlighted.\n     *\n     * Highlighted appearance is configured by the {@link EmphasisMaterial} referenced by {@link Mesh#highlightMaterial}.\n     *\n     * When {@link Mesh#isObject} and {@link Mesh#highlighted} are both ````true```` the Mesh will be\n     * registered by {@link Mesh#id} in {@link Scene#highlightedObjects}.\n     *\n     * @type {Boolean}\n     */\n    get highlighted() {\n        return this._state.highlighted;\n    }\n\n    /**\n     * Sets if this Mesh is highlighted.\n     *\n     * Highlighted appearance is configured by the {@link EmphasisMaterial} referenced by {@link Mesh#highlightMaterial}.\n     *\n     * When {@link Mesh#isObject} and {@link Mesh#highlighted} are both ````true```` the Mesh will be\n     * registered by {@link Mesh#id} in {@link Scene#highlightedObjects}.\n     *\n     * @type {Boolean}\n     */\n    set highlighted(highlighted) {\n        highlighted = !!highlighted;\n        if (highlighted === this._state.highlighted) {\n            return;\n        }\n        this._state.highlighted = highlighted;\n        if (this._isObject) {\n            this.scene._objectHighlightedUpdated(this, highlighted);\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this Mesh is selected.\n     *\n     * Selected appearance is configured by the {@link EmphasisMaterial} referenced by {@link Mesh#selectedMaterial}.\n     *\n     * When {@link Mesh#isObject} and {@link Mesh#selected} are both ````true``` the Mesh will be\n     * registered by {@link Mesh#id} in {@link Scene#selectedObjects}.\n     *\n     * @type {Boolean}\n     */\n    get selected() {\n        return this._state.selected;\n    }\n\n    /**\n     * Sets if this Mesh is selected.\n     *\n     * Selected appearance is configured by the {@link EmphasisMaterial} referenced by {@link Mesh#selectedMaterial}.\n     *\n     * When {@link Mesh#isObject} and {@link Mesh#selected} are both ````true``` the Mesh will be\n     * registered by {@link Mesh#id} in {@link Scene#selectedObjects}.\n     *\n     * @type {Boolean}\n     */\n    set selected(selected) {\n        selected = !!selected;\n        if (selected === this._state.selected) {\n            return;\n        }\n        this._state.selected = selected;\n        if (this._isObject) {\n            this.scene._objectSelectedUpdated(this, selected);\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this Mesh is edge-enhanced.\n     *\n     * Edge appearance is configured by the {@link EdgeMaterial} referenced by {@link Mesh#edgeMaterial}.\n     *\n     * @type {Boolean}\n     */\n    get edges() {\n        return this._state.edges;\n    }\n\n    /**\n     * Sets if this Mesh is edge-enhanced.\n     *\n     * Edge appearance is configured by the {@link EdgeMaterial} referenced by {@link Mesh#edgeMaterial}.\n     *\n     * @type {Boolean}\n     */\n    set edges(edges) {\n        edges = !!edges;\n        if (edges === this._state.edges) {\n            return;\n        }\n        this._state.edges = edges;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this Mesh is culled.\n     *\n     * Only rendered when {@link Mesh#visible} is ````true```` and {@link Mesh#culled} is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get culled() {\n        return this._state.culled;\n    }\n\n    /**\n     * Sets if this Mesh is culled.\n     *\n     * Only rendered when {@link Mesh#visible} is ````true```` and {@link Mesh#culled} is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set culled(value) {\n        this._state.culled = !!value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this Mesh is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * @type {Boolean}\n     */\n    get clippable() {\n        return this._state.clippable;\n    }\n\n    /**\n     * Sets if this Mesh is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * @type {Boolean}\n     */\n    set clippable(value) {\n        value = value !== false;\n        if (this._state.clippable === value) {\n            return;\n        }\n        this._state.clippable = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this Mesh included in boundary calculations.\n     *\n     * @type {Boolean}\n     */\n    get collidable() {\n        return this._state.collidable;\n    }\n\n    /**\n     * Sets if this Mesh included in boundary calculations.\n     *\n     * @type {Boolean}\n     */\n    set collidable(value) {\n        value = value !== false;\n        if (value === this._state.collidable) {\n            return;\n        }\n        this._state.collidable = value;\n        this._setAABBDirty();\n        this.scene._aabbDirty = true;\n\n    }\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Entity members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Gets if this Mesh is pickable.\n     *\n     * Picking is done via calls to {@link Scene#pick}.\n     *\n     * @type {Boolean}\n     */\n    get pickable() {\n        return this._state.pickable;\n    }\n\n    /**\n     * Sets if this Mesh is pickable.\n     *\n     * Picking is done via calls to {@link Scene#pick}.\n     *\n     * @type {Boolean}\n     */\n    set pickable(value) {\n        value = value !== false;\n        if (this._state.pickable === value) {\n            return;\n        }\n        this._state.pickable = value;\n        // No need to trigger a render;\n        // state is only used when picking\n    }\n\n    /**\n     * Gets if this Mesh casts shadows.\n     *\n     * @type {Boolean}\n     */\n    get castsShadow() {\n        return this._state.castsShadow;\n    }\n\n    /**\n     * Sets if this Mesh casts shadows.\n     *\n     * @type {Boolean}\n     */\n    set castsShadow(value) {\n        value = value !== false;\n        if (value === this._state.castsShadow) {\n            return;\n        }\n        this._state.castsShadow = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this Mesh can have shadows cast upon it.\n     *\n     * @type {Boolean}\n     */\n    get receivesShadow() {\n        return this._state.receivesShadow;\n    }\n\n    /**\n     * Sets if this Mesh can have shadows cast upon it.\n     *\n     * @type {Boolean}\n     */\n    set receivesShadow(value) {\n        value = value !== false;\n        if (value === this._state.receivesShadow) {\n            return;\n        }\n        this._state.receivesShadow = value;\n        this._state.hash = value ? \"/mod/rs;\" : \"/mod;\";\n        this.fire(\"dirty\", this); // Now need to (re)compile objectRenderers to include/exclude shadow mapping\n    }\n\n    /**\n     * Gets if this Mesh can have Scalable Ambient Obscurance (SAO) applied to it.\n     *\n     * SAO is configured by {@link SAO}.\n     *\n     * @type {Boolean}\n     * @abstract\n     */\n    get saoEnabled() {\n        return false; // TODO: Support SAO on Meshes\n    }\n\n    /**\n     * Gets the RGB colorize color for this Mesh.\n     *\n     * Multiplies by rendered fragment colors.\n     *\n     * Each element of the color is in range ````[0..1]````.\n     *\n     * @type {Number[]}\n     */\n    get colorize() {\n        return this._state.colorize;\n    }\n\n    /**\n     * Sets the RGB colorize color for this Mesh.\n     *\n     * Multiplies by rendered fragment colors.\n     *\n     * Each element of the color is in range ````[0..1]````.\n     *\n     * @type {Number[]}\n     */\n    set colorize(value) {\n        let colorize = this._state.colorize;\n        if (!colorize) {\n            colorize = this._state.colorize = new Float32Array(4);\n            colorize[3] = 1;\n        }\n        if (value) {\n            colorize[0] = value[0];\n            colorize[1] = value[1];\n            colorize[2] = value[2];\n        } else {\n            colorize[0] = 1;\n            colorize[1] = 1;\n            colorize[2] = 1;\n        }\n        const colorized = (!!value);\n        this.scene._objectColorizeUpdated(this, colorized);\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the opacity factor for this Mesh.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    get opacity() {\n        return this._state.colorize[3];\n    }\n\n    /**\n     * Sets the opacity factor for this Mesh.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    set opacity(opacity) {\n        let colorize = this._state.colorize;\n        if (!colorize) {\n            colorize = this._state.colorize = new Float32Array(4);\n            colorize[0] = 1;\n            colorize[1] = 1;\n            colorize[2] = 1;\n        }\n        const opacityUpdated = (opacity !== null && opacity !== undefined);\n        colorize[3] = opacityUpdated ? opacity : 1.0;\n        this.scene._objectOpacityUpdated(this, opacityUpdated);\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this Mesh is transparent.\n     * @returns {Boolean}\n     */\n    get transparent() {\n        return this._material.alphaMode === 2 /* blend */ || this._state.colorize[3] < 1\n    }\n\n    /**\n     * Gets the Mesh's rendering order relative to other Meshes.\n     *\n     * Default value is ````0````.\n     *\n     * This can be set on multiple transparent Meshes, to make them render in a specific order for correct alpha blending.\n     *\n     * @type {Number}\n     */\n    get layer() {\n        return this._state.layer;\n    }\n\n    /**\n     * Sets the Mesh's rendering order relative to other Meshes.\n     *\n     * Default value is ````0````.\n     *\n     * This can be set on multiple transparent Meshes, to make them render in a specific order for correct alpha blending.\n     *\n     * @type {Number}\n     */\n    set layer(value) {\n        // TODO: Only accept rendering layer in range [0...MAX_layer]\n        value = value || 0;\n        value = Math.round(value);\n        if (value === this._state.layer) {\n            return;\n        }\n        this._state.layer = value;\n        this._renderer.needStateSort();\n    }\n\n    /**\n     * Gets if the Node's position is stationary.\n     *\n     * When true, will disable the effect of {@link Camera} translations for this Mesh, while still allowing it to rotate. This is useful for skyboxes.\n     *\n     * @type {Boolean}\n     */\n    get stationary() {\n        return this._state.stationary;\n    }\n\n    /**\n     * Gets the Node's billboarding behaviour.\n     *\n     * Options are:\n     * * ````\"none\"```` -  (default) - No billboarding.\n     * * ````\"spherical\"```` - Mesh is billboarded to face the viewpoint, rotating both vertically and horizontally.\n     * * ````\"cylindrical\"```` - Mesh is billboarded to face the viewpoint, rotating only about its vertically axis. Use this mode for things like trees on a landscape.\n     * @type {String}\n     */\n    get billboard() {\n        return this._state.billboard;\n    }\n\n    /**\n     * Gets the Mesh's 3D World-space offset.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    get offset() {\n        return this._state.offset;\n    }\n\n    /**\n     * Sets the Mesh's 3D World-space offset.\n     *\n     * The offset dynamically translates the Mesh in World-space.\n     *\n     * Default value is ````[0, 0, 0]````.\n     *\n     * Provide a null or undefined value to reset to the default value.\n     *\n     * @type {Number[]}\n     */\n    set offset(value) {\n        this._state.offset.set(value || [0, 0, 0]);\n        this._setAABBDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Returns true to indicate that Mesh implements {@link Drawable}.\n     * @final\n     * @type {Boolean}\n     */\n    get isDrawable() {\n        return true;\n    }\n\n    /**\n     * Property with final value ````true```` to indicate that xeokit should render this Mesh in sorted order, relative to other Meshes.\n     *\n     * The sort order is determined by {@link Mesh#stateSortCompare}.\n     *\n     * Sorting is essential for rendering performance, so that xeokit is able to avoid applying runs of the same state changes to the GPU, ie. can collapse them.\n     *\n     * @type {Boolean}\n     */\n    get isStateSortable() {\n        return true;\n    }\n\n    /**\n     * Defines the appearance of this Mesh when xrayed.\n     *\n     * Mesh is xrayed when {@link Mesh#xrayed} is ````true````.\n     *\n     * Set to {@link Scene#xrayMaterial} by default.\n     *\n     * @type {EmphasisMaterial}\n     */\n    get xrayMaterial() {\n        return this._xrayMaterial;\n    }\n\n    /**\n     * Defines the appearance of this Mesh when highlighted.\n     *\n     * Mesh is xrayed when {@link Mesh#highlighted} is ````true````.\n     *\n     * Set to {@link Scene#highlightMaterial} by default.\n     *\n     * @type {EmphasisMaterial}\n     */\n    get highlightMaterial() {\n        return this._highlightMaterial;\n    }\n\n    /**\n     * Defines the appearance of this Mesh when selected.\n     *\n     * Mesh is xrayed when {@link Mesh#selected} is ````true````.\n     *\n     * Set to {@link Scene#selectedMaterial} by default.\n     *\n     * @type {EmphasisMaterial}\n     */\n    get selectedMaterial() {\n        return this._selectedMaterial;\n    }\n\n    /**\n     * Defines the appearance of this Mesh when edges are enhanced.\n     *\n     * Mesh is xrayed when {@link Mesh#edges} is ````true````.\n     *\n     * Set to {@link Scene#edgeMaterial} by default.\n     *\n     * @type {EdgeMaterial}\n     */\n    get edgeMaterial() {\n        return this._edgeMaterial;\n    }\n\n    _checkBillboard(value) {\n        value = value || \"none\";\n        if (value !== \"spherical\" && value !== \"cylindrical\" && value !== \"none\") {\n            this.error(\"Unsupported value for 'billboard': \" + value + \" - accepted values are \" +\n                \"'spherical', 'cylindrical' and 'none' - defaulting to 'none'.\");\n            value = \"none\";\n        }\n        return value;\n    }\n\n    /**\n     * Called by xeokit to compile shaders for this Mesh.\n     * @private\n     */\n    compile() {\n        const scene = this.scene;\n        const state = this._state;\n        const hash = [\n            scene.canvas.canvas.id,\n            scene._sectionPlanesState.getHash()\n        ];\n        if (state.stationary) {\n            hash.push(\"/s\");\n        }\n        if (state.billboard === \"none\") {\n            hash.push(\"/n\");\n        } else if (state.billboard === \"spherical\") {\n            hash.push(\"/s\");\n        } else if (state.billboard === \"cylindrical\") {\n            hash.push(\"/c\");\n        }\n        hash.push(\";\");\n\n        const drawHash = hash.concat([\n            scene.gammaOutput ? \"go\" : \"\",\n            scene._lightsState.getHash(),\n            state.receivesShadow ? \"/rs\" : \"\"\n        ]).join(\"\");\n        if (this._state.drawHash !== drawHash) {\n            this._state.drawHash = drawHash;\n            this._renderers._drawRenderer.put();\n            this._renderers._shadowRenderer.put();\n            this._renderers._emphasisFillRenderer.put();\n            this._renderers._emphasisEdgesRenderer.put();\n            this._renderers._drawRenderer.get();\n            // this._renderers._shadowRenderer.get();\n            this._renderers._emphasisFillRenderer.get();\n            this._renderers._emphasisEdgesRenderer.get();\n        }\n        const pickOcclusionHash = hash.join(\"\");\n        if (this._state.pickOcclusionHash !== pickOcclusionHash) {\n            this._state.pickOcclusionHash = pickOcclusionHash;\n            this._renderers._pickMeshRenderer.put();\n            this._renderers._pickTriangleRenderer.put();\n            this._renderers._pickMeshRenderer.get();\n            if (this._state.occluder) {\n                this._renderers._occlusionRenderer.put();\n                this._renderers._occlusionRenderer.get();\n            }\n        }\n    }\n\n    _setLocalMatrixDirty() {\n        this._localMatrixDirty = true;\n        this._setWorldMatrixDirty();\n    }\n\n    _setWorldMatrixDirty() {\n        this._worldMatrixDirty = true;\n        this._worldNormalMatrixDirty = true;\n    }\n\n    _buildWorldMatrix() {\n        const localMatrix = this.matrix;\n        if (!this._parentNode) {\n            for (let i = 0, len = localMatrix.length; i < len; i++) {\n                this._worldMatrix[i] = localMatrix[i];\n            }\n        } else {\n            math.mulMat4(this._parentNode.worldMatrix, localMatrix, this._worldMatrix);\n        }\n        this._worldMatrixDirty = false;\n    }\n\n    _buildWorldNormalMatrix() {\n        if (this._worldMatrixDirty) {\n            this._buildWorldMatrix();\n        }\n        if (!this._worldNormalMatrix) {\n            this._worldNormalMatrix = math.mat4();\n        }\n        // Note: order of inverse and transpose doesn't matter\n        math.transposeMat4(this._worldMatrix, this._worldNormalMatrix);\n        math.inverseMat4(this._worldNormalMatrix);\n        this._worldNormalMatrixDirty = false;\n    }\n\n    _setAABBDirty() {\n        if (this.collidable) {\n            for (let node = this; node; node = node._parentNode) {\n                node._aabbDirty = true;\n            }\n        }\n    }\n\n    _updateAABB() {\n        this.scene._aabbDirty = true;\n        if (!this._aabb) {\n            this._aabb = math.AABB3();\n        }\n        this._buildAABB(this.worldMatrix, this._aabb); // Mesh or VBOSceneModel\n        this._aabbDirty = false;\n    }\n\n    _buildAABB(worldMatrix, aabb) {\n\n        math.transformOBB3(worldMatrix, this._geometry.obb, obb);\n        math.OBB3ToAABB3(obb, aabb);\n\n        const offset = this._state.offset;\n\n        aabb[0] += offset[0];\n        aabb[1] += offset[1];\n        aabb[2] += offset[2];\n        aabb[3] += offset[0];\n        aabb[4] += offset[1];\n        aabb[5] += offset[2];\n\n        if (this._state.origin) {\n            const origin = this._state.origin;\n            aabb[0] += origin[0];\n            aabb[1] += origin[1];\n            aabb[2] += origin[2];\n            aabb[3] += origin[0];\n            aabb[4] += origin[1];\n            aabb[5] += origin[2];\n        }\n    }\n\n    /**\n     * Rotates the Mesh about the given local axis by the given increment.\n     *\n     * @param {Number[]} axis Local axis about which to rotate.\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotate(axis, angle) {\n        angleAxis$1[0] = axis[0];\n        angleAxis$1[1] = axis[1];\n        angleAxis$1[2] = axis[2];\n        angleAxis$1[3] = angle * math.DEGTORAD;\n        math.angleAxisToQuaternion(angleAxis$1, q1$1);\n        math.mulQuaternions(this.quaternion, q1$1, q2$1);\n        this.quaternion = q2$1;\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n        return this;\n    }\n\n    /**\n     * Rotates the Mesh about the given World-space axis by the given increment.\n     *\n     * @param {Number[]} axis Local axis about which to rotate.\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateOnWorldAxis(axis, angle) {\n        angleAxis$1[0] = axis[0];\n        angleAxis$1[1] = axis[1];\n        angleAxis$1[2] = axis[2];\n        angleAxis$1[3] = angle * math.DEGTORAD;\n        math.angleAxisToQuaternion(angleAxis$1, q1$1);\n        math.mulQuaternions(q1$1, this.quaternion, q1$1);\n        //this.quaternion.premultiply(q1);\n        return this;\n    }\n\n    /**\n     * Rotates the Mesh about the local X-axis by the given increment.\n     *\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateX(angle) {\n        return this.rotate(xAxis$1, angle);\n    }\n\n    /**\n     * Rotates the Mesh about the local Y-axis by the given increment.\n     *\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateY(angle) {\n        return this.rotate(yAxis$1, angle);\n    }\n\n    /**\n     * Rotates the Mesh about the local Z-axis by the given increment.\n     *\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateZ(angle) {\n        return this.rotate(zAxis$1, angle);\n    }\n\n    /**\n     * Translates the Mesh along local space vector by the given increment.\n     *\n     * @param {Number[]} axis Normalized local space 3D vector along which to translate.\n     * @param {Number} distance Distance to translate along  the vector.\n     */\n    translate(axis, distance) {\n        math.vec3ApplyQuaternion(this.quaternion, axis, veca);\n        math.mulVec3Scalar(veca, distance, vecb);\n        math.addVec3(this.position, vecb, this.position);\n        this._setLocalMatrixDirty();\n        this._setAABBDirty();\n        this.glRedraw();\n        return this;\n    }\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Drawable members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Translates the Mesh along the local X-axis by the given increment.\n     *\n     * @param {Number} distance Distance to translate along  the X-axis.\n     */\n    translateX(distance) {\n        return this.translate(xAxis$1, distance);\n    }\n\n    /**\n     * Translates the Mesh along the local Y-axis by the given increment.\n     *\n     * @param {Number} distance Distance to translate along  the Y-axis.\n     */\n    translateY(distance) {\n        return this.translate(yAxis$1, distance);\n    }\n\n    /**\n     * Translates the Mesh along the local Z-axis by the given increment.\n     *\n     * @param {Number} distance Distance to translate along  the Z-axis.\n     */\n    translateZ(distance) {\n        return this.translate(zAxis$1, distance);\n    }\n\n    /**\n     * Comparison function used by the renderer to determine the order in which xeokit should render the Mesh, relative to to other Meshes.\n     *\n     * xeokit requires this method because Mesh implements {@link Drawable}.\n     *\n     * Sorting is essential for rendering performance, so that xeokit is able to avoid needlessly applying runs of the same rendering state changes to the GPU, ie. can collapse them.\n     *\n     * @param {Mesh} mesh1\n     * @param {Mesh} mesh2\n     * @returns {number}\n     */\n    stateSortCompare(mesh1, mesh2) {\n        return (mesh1._state.layer - mesh2._state.layer)\n            || (mesh1._renderers._drawRenderer.getId() - mesh2._renderers._drawRenderer.getId()) // Program state\n            || (mesh1._material._state.id - mesh2._material._state.id) // Material state\n            || (mesh1._geometry._state.id - mesh2._geometry._state.id); // Geometry state\n    }\n\n    /** @private */\n    rebuildRenderFlags() {\n        this.renderFlags.reset();\n        if (!this._getActiveSectionPlanes()) {\n            this.renderFlags.culled = true;\n            return;\n        }\n        this.renderFlags.numLayers = 1;\n        this.renderFlags.numVisibleLayers = 1;\n        this.renderFlags.visibleLayers[0] = 0;\n        this._updateRenderFlags();\n    }\n\n    /**\n     * @private\n     */\n    _updateRenderFlags() {\n\n        const renderFlags = this.renderFlags;\n        const state = this._state;\n\n        if (state.xrayed) {\n            const xrayMaterial = this._xrayMaterial._state;\n            if (xrayMaterial.fill) {\n                if (xrayMaterial.fillAlpha < 1.0) {\n                    renderFlags.xrayedSilhouetteTransparent = true;\n                } else {\n                    renderFlags.xrayedSilhouetteOpaque = true;\n                }\n            }\n            if (xrayMaterial.edges) {\n                if (xrayMaterial.edgeAlpha < 1.0) {\n                    renderFlags.xrayedEdgesTransparent = true;\n                } else {\n                    renderFlags.xrayedEdgesOpaque = true;\n                }\n            }\n        } else {\n            const normalMaterial = this._material._state;\n            if (normalMaterial.alpha < 1.0 || state.colorize[3] < 1.0) {\n                renderFlags.colorTransparent = true;\n            } else {\n                renderFlags.colorOpaque = true;\n            }\n            if (state.edges) {\n                const edgeMaterial = this._edgeMaterial._state;\n                if (edgeMaterial.alpha < 1.0) {\n                    renderFlags.edgesTransparent = true;\n                } else {\n                    renderFlags.edgesOpaque = true;\n                }\n            }\n            if (state.selected) {\n                const selectedMaterial = this._selectedMaterial._state;\n                if (selectedMaterial.fill) {\n                    if (selectedMaterial.fillAlpha < 1.0) {\n                        renderFlags.selectedSilhouetteTransparent = true;\n                    } else {\n                        renderFlags.selectedSilhouetteOpaque = true;\n                    }\n                }\n                if (selectedMaterial.edges) {\n                    if (selectedMaterial.edgeAlpha < 1.0) {\n                        renderFlags.selectedEdgesTransparent = true;\n                    } else {\n                        renderFlags.selectedEdgesOpaque = true;\n                    }\n                }\n            } else if (state.highlighted) {\n                const highlightMaterial = this._highlightMaterial._state;\n                if (highlightMaterial.fill) {\n                    if (highlightMaterial.fillAlpha < 1.0) {\n                        renderFlags.highlightedSilhouetteTransparent = true;\n                    } else {\n                        renderFlags.highlightedSilhouetteOpaque = true;\n                    }\n                }\n                if (highlightMaterial.edges) {\n                    if (highlightMaterial.edgeAlpha < 1.0) {\n                        renderFlags.highlightedEdgesTransparent = true;\n                    } else {\n                        renderFlags.highlightedEdgesOpaque = true;\n                    }\n                }\n            }\n        }\n    }\n\n    _getActiveSectionPlanes() {\n\n        if (this._state.clippable) {\n\n            const sectionPlanes = this.scene._sectionPlanesState.sectionPlanes;\n            const numSectionPlanes = sectionPlanes.length;\n\n            if (numSectionPlanes > 0) {\n                for (let i = 0; i < numSectionPlanes; i++) {\n\n                    const sectionPlane = sectionPlanes[i];\n                    const renderFlags = this.renderFlags;\n\n                    if (!sectionPlane.active) {\n                        renderFlags.sectionPlanesActivePerLayer[i] = false;\n\n                    } else {\n\n                        if (this._state.origin) {\n\n                            const intersect = math.planeAABB3Intersect(sectionPlane.dir, sectionPlane.dist, this.aabb);\n                            const outside = (intersect === -1);\n\n                            if (outside) {\n                                return false;\n                            }\n\n                            const intersecting = (intersect === 0);\n                            renderFlags.sectionPlanesActivePerLayer[i] = intersecting;\n\n                        } else {\n                            renderFlags.sectionPlanesActivePerLayer[i] = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        return true;\n    }\n\n    // ---------------------- NORMAL RENDERING -----------------------------------\n\n    /** @private  */\n    drawColorOpaque(frameCtx) {\n        this._renderers._drawRenderer.drawMesh(frameCtx, this, this._material);\n    }\n\n    /** @private  */\n    drawColorTransparent(frameCtx) {\n        this._renderers._drawRenderer.drawMesh(frameCtx, this, this._material);\n    }\n\n    // ---------------------- RENDERING SAO POST EFFECT TARGETS --------------\n\n    // TODO\n\n    // ---------------------- EMPHASIS RENDERING -----------------------------------\n\n    /** @private  */\n    drawSilhouetteXRayed(frameCtx) {\n        this._renderers._emphasisFillRenderer.drawMesh(frameCtx, this, this._xrayMaterial);\n    }\n\n    /** @private  */\n    drawSilhouetteHighlighted(frameCtx) {\n        this._renderers._emphasisFillRenderer.drawMesh(frameCtx, this, this._highlightMaterial);\n    }\n\n    /** @private  */\n    drawSilhouetteSelected(frameCtx) {\n        this._renderers._emphasisFillRenderer.drawMesh(frameCtx, this, this._selectedMaterial);\n    }\n\n    // ---------------------- EDGES RENDERING -----------------------------------\n\n    /** @private  */\n    drawEdgesColorOpaque(frameCtx) {\n        this._renderers._emphasisEdgesRenderer.drawMesh(frameCtx, this, this._edgeMaterial);\n    }\n\n    /** @private  */\n    drawEdgesColorTransparent(frameCtx) {\n        this._renderers._emphasisEdgesRenderer.drawMesh(frameCtx, this, this._edgeMaterial);\n    }\n\n    /** @private  */\n    drawEdgesXRayed(frameCtx) {\n        this._renderers._emphasisEdgesRenderer.drawMesh(frameCtx, this, this._xrayMaterial);\n    }\n\n    /** @private  */\n    drawEdgesHighlighted(frameCtx) {\n        this._renderers._emphasisEdgesRenderer.drawMesh(frameCtx, this, this._highlightMaterial);\n    }\n\n    /** @private  */\n    drawEdgesSelected(frameCtx) {\n        this._renderers._emphasisEdgesRenderer.drawMesh(frameCtx, this, this._selectedMaterial);\n    }\n\n    // ---------------------- OCCLUSION CULL RENDERING -----------------------------------\n\n    /** @private  */\n    drawOcclusion(frameCtx) {\n        this._renderers._occlusionRenderer.drawMesh(frameCtx, this, this._material);\n    }\n\n    // ---------------------- SHADOW BUFFER RENDERING -----------------------------------\n\n    /** @private  */\n    drawShadow(frameCtx) {\n        this._renderers._shadowRenderer.drawMesh(frameCtx, this, this._material);\n    }\n\n    // ---------------------- PICKING RENDERING ----------------------------------\n\n    /** @private  */\n    drawPickMesh(frameCtx) {\n        this._renderers._pickMeshRenderer.drawMesh(frameCtx, this, this._material);\n    }\n\n    /** @private\n     */\n    canPickTriangle() {\n        return this._geometry.isReadableGeometry; // VBOGeometry does not support surface picking because it has no geometry data in browser memory\n    }\n\n    /** @private  */\n    drawPickTriangles(frameCtx) {\n        this._renderers._pickTriangleRenderer.drawMesh(frameCtx, this, this._material);\n    }\n\n    /** @private */\n    pickTriangleSurface(pickViewMatrix, pickProjMatrix, projection, pickResult) {\n        pickTriangleSurface(this, pickViewMatrix, pickProjMatrix, projection, pickResult);\n    }\n\n    /** @private  */\n    drawPickVertices(frameCtx) {\n\n    }\n\n    /**\n     * @private\n     * @returns {PerformanceNode}\n     */\n    delegatePickedEntity() {\n        return this;\n    }\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Component members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Destroys this Mesh.\n     */\n    destroy() {\n        super.destroy(); // xeokit.Object\n        Object.values(this._renderers).forEach(r => r.put());\n\n        this.scene._renderer.putPickID(this._state.pickID); // TODO: somehow puch this down into xeokit framework?\n        if (this._isObject) {\n            this.scene._deregisterObject(this);\n            if (this._visible) {\n                this.scene._objectVisibilityUpdated(this, false, false);\n            }\n            if (this._xrayed) {\n                this.scene._objectXRayedUpdated(this, false, false);\n            }\n            if (this._selected) {\n                this.scene._objectSelectedUpdated(this, false, false);\n            }\n            if (this._highlighted) {\n                this.scene._objectHighlightedUpdated(this, false, false);\n            }\n            this.scene._objectColorizeUpdated(this, false);\n            this.scene._objectOpacityUpdated(this, false);\n            if (this.offset.some((v) => v !== 0))\n                this.scene._objectOffsetUpdated(this, false);\n        }\n        if (this._isModel) {\n            this.scene._deregisterModel(this);\n        }\n        this.glRedraw();\n    }\n\n}\n\n\nconst pickTriangleSurface = (function () {\n\n    // Cached vars to avoid garbage collection\n\n    const localRayOrigin = math.vec3();\n    const localRayDir = math.vec3();\n    const positionA = math.vec3();\n    const positionB = math.vec3();\n    const positionC = math.vec3();\n    const triangleVertices = math.vec3();\n    const position = math.vec4();\n    const worldPos = math.vec3();\n    const viewPos = math.vec3();\n    const bary = math.vec3();\n    const normalA = math.vec3();\n    const normalB = math.vec3();\n    const normalC = math.vec3();\n    const uva = math.vec3();\n    const uvb = math.vec3();\n    const uvc = math.vec3();\n    const tempVec4a = math.vec4();\n    const tempVec4b = math.vec4();\n    const tempVec4c = math.vec4();\n    const tempVec3 = math.vec3();\n    const tempVec3b = math.vec3();\n    const tempVec3c = math.vec3();\n    const tempVec3d = math.vec3();\n    const tempVec3e = math.vec3();\n    const tempVec3f = math.vec3();\n    const tempVec3g = math.vec3();\n    const tempVec3h = math.vec3();\n    const tempVec3i = math.vec3();\n    const tempVec3j = math.vec3();\n    const tempVec3k = math.vec3();\n\n    return function (mesh, pickViewMatrix, pickProjMatrix, projection, pickResult) {\n\n        var primIndex = pickResult.primIndex;\n\n        if (primIndex !== undefined && primIndex !== null && primIndex > -1) {\n\n            const geometry = mesh.geometry._state;\n            const scene = mesh.scene;\n            const camera = scene.camera;\n            const canvas = scene.canvas;\n\n            if (geometry.primitiveName === \"triangles\") {\n\n                // Triangle picked; this only happens when the\n                // Mesh has a Geometry that has primitives of type \"triangle\"\n\n                pickResult.primitive = \"triangle\";\n\n                // Get the World-space positions of the triangle's vertices\n\n                const i = primIndex; // Indicates the first triangle index in the indices array\n\n                const indices = geometry.indices; // Indices into geometry arrays, not into shared VertexBufs\n                const positions = geometry.positions;\n\n                let ia3;\n                let ib3;\n                let ic3;\n\n                if (indices) {\n\n                    var ia = indices[i + 0];\n                    var ib = indices[i + 1];\n                    var ic = indices[i + 2];\n\n                    triangleVertices[0] = ia;\n                    triangleVertices[1] = ib;\n                    triangleVertices[2] = ic;\n\n                    pickResult.indices = triangleVertices;\n\n                    ia3 = ia * 3;\n                    ib3 = ib * 3;\n                    ic3 = ic * 3;\n\n                } else {\n\n                    ia3 = i * 3;\n                    ib3 = ia3 + 3;\n                    ic3 = ib3 + 3;\n                }\n\n                positionA[0] = positions[ia3 + 0];\n                positionA[1] = positions[ia3 + 1];\n                positionA[2] = positions[ia3 + 2];\n\n                positionB[0] = positions[ib3 + 0];\n                positionB[1] = positions[ib3 + 1];\n                positionB[2] = positions[ib3 + 2];\n\n                positionC[0] = positions[ic3 + 0];\n                positionC[1] = positions[ic3 + 1];\n                positionC[2] = positions[ic3 + 2];\n\n                if (geometry.compressGeometry) {\n\n                    // Decompress vertex positions\n\n                    const positionsDecodeMatrix = geometry.positionsDecodeMatrix;\n                    if (positionsDecodeMatrix) {\n                        geometryCompressionUtils.decompressPosition(positionA, positionsDecodeMatrix, positionA);\n                        geometryCompressionUtils.decompressPosition(positionB, positionsDecodeMatrix, positionB);\n                        geometryCompressionUtils.decompressPosition(positionC, positionsDecodeMatrix, positionC);\n                    }\n                }\n\n                // Attempt to ray-pick the triangle in local space\n\n                if (pickResult.canvasPos) {\n                    math.canvasPosToLocalRay(canvas.canvas, mesh.origin ? createRTCViewMat(pickViewMatrix, mesh.origin) : pickViewMatrix, pickProjMatrix, projection, mesh.worldMatrix, pickResult.canvasPos, localRayOrigin, localRayDir);\n\n                } else if (pickResult.origin && pickResult.direction) {\n                    math.worldRayToLocalRay(mesh.worldMatrix, pickResult.origin, pickResult.direction, localRayOrigin, localRayDir);\n                }\n\n                math.normalizeVec3(localRayDir);\n                math.rayPlaneIntersect(localRayOrigin, localRayDir, positionA, positionB, positionC, position);\n\n                // Get Local-space cartesian coordinates of the ray-triangle intersection\n\n                pickResult.localPos = position;\n                pickResult.position = position;\n\n                // Get interpolated World-space coordinates\n\n                // Need to transform homogeneous coords\n\n                tempVec4a[0] = position[0];\n                tempVec4a[1] = position[1];\n                tempVec4a[2] = position[2];\n                tempVec4a[3] = 1;\n\n                // Get World-space cartesian coordinates of the ray-triangle intersection\n\n                math.transformVec4(mesh.worldMatrix, tempVec4a, tempVec4b);\n\n                worldPos[0] = tempVec4b[0];\n                worldPos[1] = tempVec4b[1];\n                worldPos[2] = tempVec4b[2];\n\n                if (pickResult.canvasPos && mesh.origin) {\n                    worldPos[0] += mesh.origin[0];\n                    worldPos[1] += mesh.origin[1];\n                    worldPos[2] += mesh.origin[2];\n                }\n\n                pickResult.worldPos = worldPos;\n\n                // Get View-space cartesian coordinates of the ray-triangle intersection\n\n                math.transformVec4(camera.matrix, tempVec4b, tempVec4c);\n\n                viewPos[0] = tempVec4c[0];\n                viewPos[1] = tempVec4c[1];\n                viewPos[2] = tempVec4c[2];\n\n                pickResult.viewPos = viewPos;\n\n                // Get barycentric coordinates of the ray-triangle intersection\n\n                math.cartesianToBarycentric(position, positionA, positionB, positionC, bary);\n\n                pickResult.bary = bary;\n\n                // Get interpolated normal vector\n\n                const normals = geometry.normals;\n\n                if (normals) {\n\n                    if (geometry.compressGeometry) {\n\n                        // Decompress vertex normals\n\n                        const ia2 = ia * 3;\n                        const ib2 = ib * 3;\n                        const ic2 = ic * 3;\n\n                        geometryCompressionUtils.decompressNormal(normals.subarray(ia2, ia2 + 2), normalA);\n                        geometryCompressionUtils.decompressNormal(normals.subarray(ib2, ib2 + 2), normalB);\n                        geometryCompressionUtils.decompressNormal(normals.subarray(ic2, ic2 + 2), normalC);\n\n                    } else {\n\n                        normalA[0] = normals[ia3];\n                        normalA[1] = normals[ia3 + 1];\n                        normalA[2] = normals[ia3 + 2];\n\n                        normalB[0] = normals[ib3];\n                        normalB[1] = normals[ib3 + 1];\n                        normalB[2] = normals[ib3 + 2];\n\n                        normalC[0] = normals[ic3];\n                        normalC[1] = normals[ic3 + 1];\n                        normalC[2] = normals[ic3 + 2];\n                    }\n\n                    const normal = math.addVec3(math.addVec3(\n                            math.mulVec3Scalar(normalA, bary[0], tempVec3),\n                            math.mulVec3Scalar(normalB, bary[1], tempVec3b), tempVec3c),\n                        math.mulVec3Scalar(normalC, bary[2], tempVec3d), tempVec3e);\n\n                    pickResult.worldNormal = math.normalizeVec3(math.transformVec3(mesh.worldNormalMatrix, normal, tempVec3f));\n                }\n\n                // Get interpolated UV coordinates\n\n                const uvs = geometry.uv;\n\n                if (uvs) {\n\n                    uva[0] = uvs[(ia * 2)];\n                    uva[1] = uvs[(ia * 2) + 1];\n\n                    uvb[0] = uvs[(ib * 2)];\n                    uvb[1] = uvs[(ib * 2) + 1];\n\n                    uvc[0] = uvs[(ic * 2)];\n                    uvc[1] = uvs[(ic * 2) + 1];\n\n                    if (geometry.compressGeometry) {\n\n                        // Decompress vertex UVs\n\n                        const uvDecodeMatrix = geometry.uvDecodeMatrix;\n                        if (uvDecodeMatrix) {\n                            geometryCompressionUtils.decompressUV(uva, uvDecodeMatrix, uva);\n                            geometryCompressionUtils.decompressUV(uvb, uvDecodeMatrix, uvb);\n                            geometryCompressionUtils.decompressUV(uvc, uvDecodeMatrix, uvc);\n                        }\n                    }\n\n                    pickResult.uv = math.addVec3(\n                        math.addVec3(\n                            math.mulVec2Scalar(uva, bary[0], tempVec3g),\n                            math.mulVec2Scalar(uvb, bary[1], tempVec3h), tempVec3i),\n                        math.mulVec2Scalar(uvc, bary[2], tempVec3j), tempVec3k);\n                }\n            }\n        }\n    }\n})();\n\nconst instantiateMeshRenderer = (mesh, attributes, auxVariables, programSetup, programVariablesState) => {\n    const programVariables = programVariablesState.programVariables;\n    const decodedUv   = auxVariables.decodedUv;\n    const worldNormal = auxVariables.worldNormal;\n    const viewNormal  = auxVariables.viewNormal;\n    const scene = mesh.scene;\n    const gl = scene.canvas.gl;\n    const meshStateBackground = mesh._state.background;\n    const geometryState = mesh._geometry._state;\n    const quantizedGeometry = geometryState.compressGeometry;\n    const isPoints = geometryState.primitiveName === \"points\";\n\n    const pointSize             = programVariables.createUniform(\"float\", \"pointSize\");\n    const modelMatrix           = programVariables.createUniform(\"mat4\",  \"modelMatrix\");\n    const modelNormalMatrix     = programVariables.createUniform(\"mat4\",  \"modelNormalMatrix\");\n    const offset                = programVariables.createUniform(\"vec3\",  \"offset\");\n    const scale                 = programVariables.createUniform(\"vec3\",  \"scale\");\n    const positionsDecodeMatrix = programVariables.createUniform(\"mat4\",  \"positionsDecodeMatrix\");\n    const uvDecodeMatrix        = programVariables.createUniform(\"mat3\",  \"uvDecodeMatrix\");\n    const viewMatrix            = programVariables.createUniform(\"mat4\",  \"viewMatrix\");\n    const viewNormalMatrix      = programVariables.createUniform(\"mat4\",  \"viewNormalMatrix\");\n    const projMatrix            = programVariables.createUniform(\"mat4\",  \"projMatrix\");\n\n    const billboard = mesh.billboard;\n    const isBillboard = (! programSetup.dontBillboardAnything) && ((billboard === \"spherical\") || (billboard === \"cylindrical\"));\n    const stationary = mesh.stationary;\n    const defineBillboard = isBillboard && ((name, src) => [\n        `mat4 ${name}(in mat4 matIn) {`,\n        \"   mat4 mat = matIn;\",\n        `   mat[0].xyz = vec3(${scale}[0], 0.0, 0.0);`,\n        ...((billboard === \"spherical\") ? [ `   mat[1].xyz = vec3(0.0, ${scale}[1], 0.0);` ] : [ ]),\n        \"   mat[2].xyz = vec3(0.0, 0.0, 1.0);\",\n        \"   return mat;\",\n        \"}\",\n    ].forEach(l => src.push(l)));\n\n    const billboardIfApplicable = (function() {\n        const billboardVert = defineBillboard && programVariables.createVertexDefinition(\"billboard\", defineBillboard);\n        return v => billboardVert ? `${billboardVert}(${v})` : v;\n    })();\n\n    const billboardIfApplicableFrag = (function() {\n        const billboardFrag = defineBillboard && programVariables.createFragmentDefinition(\"billboard\", defineBillboard);\n        return v => billboardFrag ? `${billboardFrag}(${v})` : v;\n    })();\n\n    const fragmentOutputsSetup = [ ];\n    if (programSetup.dontBillboardAnything) {\n        fragmentOutputsSetup.push(`mat4 viewMatrix2 = ${viewMatrix};`);\n    } else {\n        fragmentOutputsSetup.push(`mat4 viewMatrix1 = ${viewMatrix};`);\n        if (stationary) {\n            fragmentOutputsSetup.push(\"viewMatrix1[3].xyz = vec3(0.0, 0.0, 0.0);\");\n        } else if (meshStateBackground) {\n            fragmentOutputsSetup.push(\"viewMatrix1[3]     = vec4(0.0, 0.0, 0.0, 1.0);\");\n        }\n        fragmentOutputsSetup.push(`mat4 viewMatrix2 = ${billboardIfApplicableFrag(\"viewMatrix1\")};`);\n    }\n\n    const clipPos = \"clipPos\";\n    const getVertexData = function() {\n        const viewNormalDefinition = viewNormal && viewNormal.needed && `vec3 ${viewNormal} = normalize((${billboardIfApplicable(viewNormalMatrix)} * vec4(${worldNormal}, 0.0)).xyz);`;\n        const src = [ ];\n        src.push(`vec4 localPosition = vec4(${attributes.position}, 1.0);`);\n        if (quantizedGeometry) {\n            src.push(`localPosition = ${positionsDecodeMatrix} * localPosition;`);\n        }\n        src.push(`vec4 worldPosition = ${billboardIfApplicable(modelMatrix)} * localPosition;`);\n        src.push(`worldPosition.xyz = worldPosition.xyz + ${offset};`);\n        if (programSetup.dontBillboardAnything) {\n            src.push(`vec4 viewPosition = ${viewMatrix} * worldPosition;`);\n        } else {\n            src.push(`mat4 viewMatrix1 = ${viewMatrix};`);\n            if (stationary) {\n                src.push(\"viewMatrix1[3].xyz = vec3(0.0, 0.0, 0.0);\");\n            } else if (meshStateBackground) {\n                src.push(\"viewMatrix1[3]     = vec4(0.0, 0.0, 0.0, 1.0);\");\n            }\n            src.push(`mat4 viewMatrix2 = ${billboardIfApplicable(\"viewMatrix1\")};`);\n            src.push(`vec4 viewPosition = ${(isBillboard\n                                                 ? `${billboardIfApplicable(`viewMatrix1 * ${modelMatrix}`)} * localPosition`\n                                                 : \"viewMatrix2 * worldPosition\")};`);\n        }\n        decodedUv && decodedUv.needed && src.push(`vec2 ${decodedUv} = ${quantizedGeometry ? `(${uvDecodeMatrix} * vec3(${attributes.uv}, 1.0)).xy` : attributes.uv};`);\n        if (worldNormal && worldNormal.needed) {\n            const localNormal = quantizedGeometry ? `${programVariables.commonLibrary.octDecode}(${attributes.normal}.xy)` : attributes.normal;\n            src.push(`vec3 ${worldNormal} = (${billboardIfApplicable(modelNormalMatrix)} * vec4(${localNormal}, 0.0)).xyz;`);\n        }\n        viewNormalDefinition && src.push(viewNormalDefinition);\n        src.push(`vec4 ${clipPos} = ${projMatrix} * viewPosition;`);\n        return src;\n    };\n\n    const clippable = programVariables.createUniform(\"bool\", \"clippable\");\n\n    const [ program, errors ] = programVariablesState.buildProgram(\n        gl,\n        programSetup.programName,\n        {\n            appendFragmentOutputs:          (src, getGammaOutputExpression, gl_FragCoord, sliceColorOr) => {\n                fragmentOutputsSetup.forEach(line => src.push(line));\n                programSetup.appendFragmentOutputs(src, getGammaOutputExpression, gl_FragCoord, sliceColorOr);\n            },\n            clippableTest:                  () => clippable,\n            clippingCaps:                   programSetup.clippingCaps,\n            clipPos:                        meshStateBackground ? `${clipPos}.xyww` : clipPos,\n            crossSections:                  scene.crossSections,\n            discardPoints:                  isPoints && programSetup.discardPoints,\n            getGammaFactor:                 scene.gammaOutput && (() => scene.gammaFactor),\n            getLogDepth:                    (! programSetup.dontGetLogDepth) && scene.logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n            getPointSize:                   programSetup.setupPointSize && isPoints && (() => pointSize),\n            getVertexData:                  getVertexData,\n            projMatrix:                     projMatrix,\n            sectionPlanesState:             scene._sectionPlanesState,\n            testPerspectiveForGl_FragDepth: true,\n            usePickClipPos:                 programSetup.isPick,\n            worldPositionAttribute:         \"worldPosition\"\n        });\n\n    if (errors) {\n        return { errors: errors };\n    } else {\n        const inputSetters = program.inputSetters;\n\n        let lastMaterialId = null;\n        let lastGeometryId = null;\n\n        return {\n            destroy: () => program.destroy(),\n            drawMesh: (frameCtx, mesh, material) => {\n                if (programSetup.skipIfTransparent && (material.alpha < 1.0)) {\n                    return;\n                }\n\n                const materialState = material._state;\n                const meshState = mesh._state;\n                const geometry = mesh._geometry;\n                const geometryState = geometry._state;\n                const viewParams = frameCtx.viewParams;\n                const actsAsBackground = programSetup.canActAsBackground && meshStateBackground;\n\n                if (frameCtx.lastProgramId !== program.id) {\n                    frameCtx.lastProgramId = program.id;\n                    program.bind();\n                    frameCtx.useProgram++;\n                    lastMaterialId = null;\n                    lastGeometryId = null;\n                    if (actsAsBackground) {\n                        gl.depthFunc(gl.LEQUAL);\n                    }\n                }\n\n                if (materialState.id !== lastMaterialId) {\n                    if (frameCtx.backfaces !== materialState.backfaces) {\n                        if (materialState.backfaces) {\n                            gl.disable(gl.CULL_FACE);\n                        } else {\n                            gl.enable(gl.CULL_FACE);\n                        }\n                        frameCtx.backfaces = materialState.backfaces;\n                    }\n\n                    if ((! programSetup.dontSetFrontFace) && (frameCtx.frontface !== materialState.frontface)) {\n                        gl.frontFace(materialState.frontface ? gl.CCW : gl.CW);\n                        frameCtx.frontface = materialState.frontface;\n                    }\n\n                    if (programSetup.drawEdges && (frameCtx.lineWidth !== materialState.edgeWidth)) {\n                        gl.lineWidth(materialState.edgeWidth);\n                        frameCtx.lineWidth = materialState.edgeWidth;\n                    }\n\n                    if (programSetup.setsLineWidth && (frameCtx.lineWidth !== materialState.lineWidth)) {\n                        gl.lineWidth(materialState.lineWidth);\n                        frameCtx.lineWidth = materialState.lineWidth;\n                    }\n\n                    lastMaterialId = materialState.id;\n                }\n\n                const setUniforms = (projMat, viewMat) => {\n                    const setUni = (u, v) => (u.setInputValue && u.setInputValue(v));\n                    setUni(pointSize,             material.pointSize);\n                    setUni(modelMatrix,           mesh.worldMatrix);\n                    setUni(modelNormalMatrix,     mesh.worldNormalMatrix);\n                    setUni(offset,                mesh.offset);\n                    setUni(scale,                 mesh.scale);\n                    setUni(positionsDecodeMatrix, geometryState.positionsDecodeMatrix);\n                    setUni(uvDecodeMatrix,        geometryState.uvDecodeMatrix);\n                    setUni(viewMatrix,            viewMat);\n                    setUni(viewNormalMatrix,      viewParams.viewNormalMatrix);\n                    setUni(projMatrix,            projMat);\n                    setUni(clippable,             mesh.clippable);\n\n                    inputSetters.setUniforms(frameCtx, {\n                        material:     material,\n                        meshColorize: mesh.colorize,\n                        meshPickID:   mesh._state.pickID,\n                        mesh:         {\n                            origin:      mesh.origin,\n                            renderFlags: { sectionPlanesActivePerLayer: mesh.renderFlags.sectionPlanesActivePerLayer }\n                        },\n                        view:         { far: viewParams.far }\n                    });\n                };\n\n                const origin = (! programSetup.useShadowView) && mesh.origin;\n                setUniforms(viewParams.projMatrix, origin ? frameCtx.getRTCViewMatrix(meshState.originHash, origin) : viewParams.viewMatrix);\n\n                const setAttributes = (triangleGeometry) => {\n                    const setAttr = (a, b) => {\n                        if (a && a.setInputValue && b) {\n                            a.setInputValue(b);\n                            frameCtx.bindArray++;\n                        }\n                    };\n                    setAttr(attributes.position,  (triangleGeometry || geometryState).positionsBuf);\n                    setAttr(attributes.color,     geometryState.colorsBuf);\n                    setAttr(attributes.pickColor, triangleGeometry && triangleGeometry.pickColorsBuf);\n                    setAttr(attributes.uv,        geometryState.uvBuf);\n                    setAttr(attributes.normal,    geometryState.normalsBuf);\n                };\n\n                if (programSetup.trianglePick) {\n                    const positionsBuf = geometry._getPickTrianglePositions();\n                    if (geometryState.id !== lastGeometryId) {\n                        setAttributes({ positionsBuf: positionsBuf, pickColorsBuf: geometry._getPickTriangleColors() });\n                        lastGeometryId = geometryState.id;\n                    }\n\n                    gl.drawArrays(geometryState.primitive, 0, positionsBuf.numItems / 3);\n                } else if (programSetup.drawEdges) {\n                    const indicesBuf = ((geometryState.primitive === gl.TRIANGLES)\n                                        ? geometry._getEdgeIndices()\n                                        : ((geometryState.primitive === gl.LINES) && geometryState.indicesBuf));\n\n                    if (indicesBuf) {\n                        if (geometryState.id !== lastGeometryId) {\n                            setAttributes();\n\n                            indicesBuf.bind();\n                            frameCtx.bindArray++;\n                            lastGeometryId = geometryState.id;\n                        }\n\n                        gl.drawElements(gl.LINES, indicesBuf.numItems, indicesBuf.itemType, 0);\n\n                        frameCtx.drawElements++;\n                    }\n                } else {\n                    if (geometryState.id !== lastGeometryId) {\n                        setAttributes();\n\n                        if (geometryState.indicesBuf) {\n                            geometryState.indicesBuf.bind();\n                            frameCtx.bindArray++;\n                        }\n                        lastGeometryId = geometryState.id;\n                    }\n\n                    if (geometryState.indicesBuf) {\n                        gl.drawElements(geometryState.primitive, geometryState.indicesBuf.numItems, geometryState.indicesBuf.itemType, 0);\n                        frameCtx.drawElements++;\n                    } else if (geometryState.positionsBuf) {\n                        gl.drawArrays(gl.TRIANGLES, 0, geometryState.positionsBuf.numItems);\n                        frameCtx.drawArrays++;\n                    }\n                }\n\n                if (actsAsBackground) {\n                    gl.depthFunc(gl.LESS);\n                }\n            }\n        };\n    }\n};\n\n/**\n * @desc A **Material** defines the surface appearance of attached {@link Mesh}es.\n *\n * Material is the base class for:\n *\n * * {@link MetallicMaterial} - physically-based material for metallic surfaces. Use this one for things made of metal.\n * * {@link SpecularMaterial} - physically-based material for non-metallic (dielectric) surfaces. Use this one for insulators, such as ceramics, plastics, wood etc.\n * * {@link PhongMaterial} - material for classic Blinn-Phong shading. This is less demanding of graphics hardware than the physically-based materials.\n * * {@link LambertMaterial} - material for fast, flat-shaded CAD rendering without textures. Use this for navigating huge CAD or BIM models interactively. This material gives the best rendering performance and uses the least memory.\n * * {@link EmphasisMaterial} - defines the appearance of Meshes when \"xrayed\" or \"highlighted\".\n * * {@link EdgeMaterial} - defines the appearance of Meshes when edges are emphasized.\n *\n * A {@link Scene} is allowed to contain a mixture of these material types.\n *\n */\n\nclass Material extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Material\";\n    }\n\n    constructor(owner, cfg={}) {\n        super(owner, cfg);\n        stats.memory.materials++;\n    }\n\n    destroy() {\n        super.destroy();\n        stats.memory.materials--;\n    }\n}\n\nconst alphaModes$1 = {\"opaque\": 0, \"mask\": 1, \"blend\": 2};\nconst alphaModeNames$1 = [\"opaque\", \"mask\", \"blend\"];\n\n/**\n * @desc Configures the normal rendered appearance of {@link Mesh}es using the non-physically-correct Blinn-Phong shading model.\n *\n * * Useful for non-realistic objects like gizmos.\n * * {@link SpecularMaterial} is best for insulators, such as wood, ceramics and plastic.\n * * {@link MetallicMaterial} is best for conductive materials, such as metal.\n * * {@link LambertMaterial} is appropriate for high-detail models that need to render as efficiently as possible.\n *\n * ## Usage\n *\n * In the example below, we'll create a {@link Mesh} with a PhongMaterial with a diffuse {@link Texture} and a specular {@link Fresnel}, using a {@link buildTorusGeometry} to create the {@link Geometry}.\n *\n * [[Run this example](/examples/index.html#materials_PhongMaterial)]\n *\n *  ```` javascript\n * import {Viewer, Mesh, buildTorusGeometry,\n *     ReadableGeometry, PhongMaterial, Texture, Fresnel} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *        canvasId: \"myCanvas\"\n *    });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry({\n *          center: [0, 0, 0],\n *          radius: 1.5,\n *          tube: 0.5,\n *          radialSegments: 32,\n *          tubeSegments: 24,\n *          arc: Math.PI * 2.0\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *          ambient: [0.9, 0.3, 0.9],\n *          shininess: 30,\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse/uvGrid2.jpg\"\n *          }),\n *          specularFresnel: new Fresnel(viewer.scene, {\n *              leftColor: [1.0, 1.0, 1.0],\n *              rightColor: [0.0, 0.0, 0.0],\n *              power: 4\n *          })\n *     })\n * });\n * ````\n *\n * ## PhongMaterial Properties\n *\n *  The following table summarizes PhongMaterial properties:\n *\n * | Property | Type | Range | Default Value | Space | Description |\n * |:--------:|:----:|:-----:|:-------------:|:-----:|:-----------:|\n * | {@link PhongMaterial#ambient} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the ambient light reflected by the material. |\n * | {@link PhongMaterial#diffuse} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the diffuse light reflected by the material. |\n * | {@link PhongMaterial#specular} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the specular light reflected by the material. |\n * | {@link PhongMaterial#emissive} | Array | [0, 1] for all components | [0,0,0] | linear | The RGB components of the light emitted by the material. |\n * | {@link PhongMaterial#alpha} | Number | [0, 1] | 1 | linear | The transparency of the material surface (0 fully transparent, 1 fully opaque). |\n * | {@link PhongMaterial#shininess} | Number | [0, 128] | 80 | linear | Determines the size and sharpness of specular highlights. |\n * | {@link PhongMaterial#reflectivity} | Number | [0, 1] | 1 | linear | Determines the amount of reflectivity. |\n * | {@link PhongMaterial#diffuseMap} | {@link Texture} |  | null | sRGB | Texture RGB components multiplying by {@link PhongMaterial#diffuse}. If the fourth component (A) is present, it multiplies by {@link PhongMaterial#alpha}. |\n * | {@link PhongMaterial#specularMap} | {@link Texture} |  | null | sRGB | Texture RGB components multiplying by {@link PhongMaterial#specular}. If the fourth component (A) is present, it multiplies by {@link PhongMaterial#alpha}. |\n * | {@link PhongMaterial#emissiveMap} | {@link Texture} |  | null | linear | Texture with RGB components multiplying by {@link PhongMaterial#emissive}. |\n * | {@link PhongMaterial#alphaMap} | {@link Texture} |  | null | linear | Texture with first component multiplying by {@link PhongMaterial#alpha}. |\n * | {@link PhongMaterial#occlusionMap} | {@link Texture} |  | null | linear | Ambient occlusion texture multiplying by {@link PhongMaterial#ambient}, {@link PhongMaterial#diffuse} and {@link PhongMaterial#specular}. |\n * | {@link PhongMaterial#normalMap} | {@link Texture} |  | null | linear | Tangent-space normal map. |\n * | {@link PhongMaterial#diffuseFresnel} | {@link Fresnel} |  | null |  | Fresnel term applied to {@link PhongMaterial#diffuse}. |\n * | {@link PhongMaterial#specularFresnel} | {@link Fresnel} |  | null |  | Fresnel term applied to {@link PhongMaterial#specular}. |\n * | {@link PhongMaterial#emissiveFresnel} | {@link Fresnel} |  | null |  | Fresnel term applied to {@link PhongMaterial#emissive}. |\n * | {@link PhongMaterial#reflectivityFresnel} | {@link Fresnel} |  | null |  | Fresnel term applied to {@link PhongMaterial#reflectivity}. |\n * | {@link PhongMaterial#alphaFresnel} | {@link Fresnel} |  | null |  | Fresnel term applied to {@link PhongMaterial#alpha}. |\n * | {@link PhongMaterial#lineWidth} | Number | [0..100] | 1 |  | Line width in pixels. |\n * | {@link PhongMaterial#pointSize} | Number | [0..100] | 1 |  | Point size in pixels. |\n * | {@link PhongMaterial#alphaMode} | String | \"opaque\", \"blend\", \"mask\" | \"blend\" |  | Alpha blend mode. |\n * | {@link PhongMaterial#alphaCutoff} | Number | [0..1] | 0.5 |  | Alpha cutoff value. |\n * | {@link PhongMaterial#backfaces} | Boolean |  | false |  | Whether to render geometry backfaces. |\n * | {@link PhongMaterial#frontface} | String | \"ccw\", \"cw\" | \"ccw\" |  | The winding order for geometry frontfaces - \"cw\" for clockwise, or \"ccw\" for counter-clockwise. |\n */\nclass PhongMaterial extends Material {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"PhongMaterial\";\n    }\n\n    /**\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] The PhongMaterial configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number[]} [cfg.ambient=[1.0, 1.0, 1.0 ]]  PhongMaterial ambient color.\n     * @param {Number[]} [cfg.diffuse=[ 1.0, 1.0, 1.0 ]] PhongMaterial diffuse color.\n     * @param {Number[]} [cfg.specular=[ 1.0, 1.0, 1.0 ]]  PhongMaterial specular color.\n     * @param {Number[]} [cfg.emissive=[ 0.0, 0.0, 0.0 ]] PhongMaterial emissive color.\n     * @param {Number} [cfg.alpha=1] Scalar in range 0-1 that controls alpha, where 0 is completely transparent and 1 is completely opaque.\n     * @param {Number} [cfg.shininess=80] Scalar in range 0-128 that determines the size and sharpness of specular highlights.\n     * @param {Number} [cfg.reflectivity=1] Scalar in range 0-1 that controls how much {@link ReflectionMap} is reflected.\n     * @param {Number} [cfg.lineWidth=1] Scalar that controls the width of lines.\n     * @param {Number} [cfg.pointSize=1] Scalar that controls the size of points.\n     * @param {Texture} [cfg.ambientMap=null] A ambient map {@link Texture}, which will multiply by the diffuse property. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Texture} [cfg.diffuseMap=null] A diffuse map {@link Texture}, which will override the effect of the diffuse property. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Texture} [cfg.specularMap=null] A specular map {@link Texture}, which will override the effect of the specular property. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Texture} [cfg.emissiveMap=undefined] An emissive map {@link Texture}, which will override the effect of the emissive property. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Texture} [cfg.normalMap=undefined] A normal map {@link Texture}. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Texture} [cfg.alphaMap=undefined] An alpha map {@link Texture}, which will override the effect of the alpha property. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Texture} [cfg.reflectivityMap=undefined] A reflectivity control map {@link Texture}, which will override the effect of the reflectivity property. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Texture} [cfg.occlusionMap=null] An occlusion map {@link Texture}. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Fresnel} [cfg.diffuseFresnel=undefined] A diffuse {@link Fresnel\"}}Fresnel{{/crossLink}}. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Fresnel} [cfg.specularFresnel=undefined] A specular {@link Fresnel\"}}Fresnel{{/crossLink}}. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Fresnel} [cfg.emissiveFresnel=undefined] An emissive {@link Fresnel\"}}Fresnel{{/crossLink}}. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Fresnel} [cfg.alphaFresnel=undefined] An alpha {@link Fresnel\"}}Fresnel{{/crossLink}}. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {Fresnel} [cfg.reflectivityFresnel=undefined] A reflectivity {@link Fresnel\"}}Fresnel{{/crossLink}}. Must be within the same {@link Scene} as this PhongMaterial.\n     * @param {String} [cfg.alphaMode=\"opaque\"] The alpha blend mode - accepted values are \"opaque\", \"blend\" and \"mask\". See the {@link PhongMaterial#alphaMode} property for more info.\n     * @param {Number} [cfg.alphaCutoff=0.5] The alpha cutoff value. See the {@link PhongMaterial#alphaCutoff} property for more info.\n     * @param {Boolean} [cfg.backfaces=false] Whether to render geometry backfaces.\n     * @param {Boolean} [cfg.frontface=\"ccw\"] The winding order for geometry front faces - \"cw\" for clockwise, or \"ccw\" for counter-clockwise.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            type: \"PhongMaterial\",\n            ambient: math.vec3([1.0, 1.0, 1.0]),\n            diffuse: math.vec3([1.0, 1.0, 1.0]),\n            specular: math.vec3([1.0, 1.0, 1.0]),\n            emissive: math.vec3([0.0, 0.0, 0.0]),\n            alpha: null,\n            shininess: null,\n            reflectivity: null,\n            alphaMode: null,\n            alphaCutoff: null,\n            lineWidth: null,\n            pointSize: null,\n            backfaces: null,\n            frontface: null, // Boolean for speed; true == \"ccw\", false == \"cw\"\n            hash: null\n        });\n\n        this.ambient = cfg.ambient;\n        this.diffuse = cfg.diffuse;\n        this.specular = cfg.specular;\n        this.emissive = cfg.emissive;\n        this.alpha = cfg.alpha;\n        this.shininess = cfg.shininess;\n        this.reflectivity = cfg.reflectivity;\n        this.lineWidth = cfg.lineWidth;\n        this.pointSize = cfg.pointSize;\n\n        if (cfg.ambientMap) {\n            this._ambientMap = this._checkComponent(\"Texture\", cfg.ambientMap);\n        }\n        if (cfg.diffuseMap) {\n            this._diffuseMap = this._checkComponent(\"Texture\", cfg.diffuseMap);\n        }\n        if (cfg.specularMap) {\n            this._specularMap = this._checkComponent(\"Texture\", cfg.specularMap);\n        }\n        if (cfg.emissiveMap) {\n            this._emissiveMap = this._checkComponent(\"Texture\", cfg.emissiveMap);\n        }\n        if (cfg.alphaMap) {\n            this._alphaMap = this._checkComponent(\"Texture\", cfg.alphaMap);\n        }\n        if (cfg.reflectivityMap) {\n            this._reflectivityMap = this._checkComponent(\"Texture\", cfg.reflectivityMap);\n        }\n        if (cfg.normalMap) {\n            this._normalMap = this._checkComponent(\"Texture\", cfg.normalMap);\n        }\n        if (cfg.occlusionMap) {\n            this._occlusionMap = this._checkComponent(\"Texture\", cfg.occlusionMap);\n        }\n        if (cfg.diffuseFresnel) {\n            this._diffuseFresnel = this._checkComponent(\"Fresnel\", cfg.diffuseFresnel);\n        }\n        if (cfg.specularFresnel) {\n            this._specularFresnel = this._checkComponent(\"Fresnel\", cfg.specularFresnel);\n        }\n        if (cfg.emissiveFresnel) {\n            this._emissiveFresnel = this._checkComponent(\"Fresnel\", cfg.emissiveFresnel);\n        }\n        if (cfg.alphaFresnel) {\n            this._alphaFresnel = this._checkComponent(\"Fresnel\", cfg.alphaFresnel);\n        }\n        if (cfg.reflectivityFresnel) {\n            this._reflectivityFresnel = this._checkComponent(\"Fresnel\", cfg.reflectivityFresnel);\n        }\n\n        this.alphaMode = cfg.alphaMode;\n        this.alphaCutoff = cfg.alphaCutoff;\n        this.backfaces = cfg.backfaces;\n        this.frontface = cfg.frontface;\n\n        this._makeHash();\n    }\n\n    _makeHash() {\n        const state = this._state;\n        const hash = [\"/p\"]; // 'P' for Phong\n        if (this._normalMap) {\n            hash.push(\"/nm\");\n            if (this._normalMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._ambientMap) {\n            hash.push(\"/am\");\n            if (this._ambientMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n            hash.push(\"/\" + this._ambientMap.encoding);\n        }\n        if (this._diffuseMap) {\n            hash.push(\"/dm\");\n            if (this._diffuseMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n            hash.push(\"/\" + this._diffuseMap.encoding);\n        }\n        if (this._specularMap) {\n            hash.push(\"/sm\");\n            if (this._specularMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._emissiveMap) {\n            hash.push(\"/em\");\n            if (this._emissiveMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n            hash.push(\"/\" + this._emissiveMap.encoding);\n        }\n        if (this._alphaMap) {\n            hash.push(\"/opm\");\n            if (this._alphaMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._reflectivityMap) {\n            hash.push(\"/rm\");\n            if (this._reflectivityMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._occlusionMap) {\n            hash.push(\"/ocm\");\n            if (this._occlusionMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._diffuseFresnel) {\n            hash.push(\"/df\");\n        }\n        if (this._specularFresnel) {\n            hash.push(\"/sf\");\n        }\n        if (this._emissiveFresnel) {\n            hash.push(\"/ef\");\n        }\n        if (this._alphaFresnel) {\n            hash.push(\"/of\");\n        }\n        if (this._reflectivityFresnel) {\n            hash.push(\"/rf\");\n        }\n        hash.push(\";\");\n        state.hash = hash.join(\"\");\n    }\n\n    /**\n     * Sets the PhongMaterial's ambient color.\n     *\n     * Default value is ````[0.3, 0.3, 0.3]````.\n     *\n     * @type {Number[]}\n     */\n    set ambient(value) {\n        let ambient = this._state.ambient;\n        if (!ambient) {\n            ambient = this._state.ambient = new Float32Array(3);\n        } else if (value && ambient[0] === value[0] && ambient[1] === value[1] && ambient[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            ambient[0] = value[0];\n            ambient[1] = value[1];\n            ambient[2] = value[2];\n        } else {\n            ambient[0] = .2;\n            ambient[1] = .2;\n            ambient[2] = .2;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the PhongMaterial's ambient color.\n     *\n     * Default value is ````[0.3, 0.3, 0.3]````.\n     *\n     * @type {Number[]}\n     */\n    get ambient() {\n        return this._state.ambient;\n    }\n\n    /**\n     * Sets the PhongMaterial's diffuse color.\n     *\n     * Multiplies by {@link PhongMaterial#diffuseMap}.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @type {Number[]}\n     */\n    set diffuse(value) {\n        let diffuse = this._state.diffuse;\n        if (!diffuse) {\n            diffuse = this._state.diffuse = new Float32Array(3);\n        } else if (value && diffuse[0] === value[0] && diffuse[1] === value[1] && diffuse[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            diffuse[0] = value[0];\n            diffuse[1] = value[1];\n            diffuse[2] = value[2];\n        } else {\n            diffuse[0] = 1;\n            diffuse[1] = 1;\n            diffuse[2] = 1;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Sets the PhongMaterial's diffuse color.\n     *\n     * Multiplies by {@link PhongMaterial#diffuseMap}.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @type {Number[]}\n     */\n    get diffuse() {\n        return this._state.diffuse;\n    }\n\n    /**\n     * Sets the PhongMaterial's specular color.\n     *\n     * Multiplies by {@link PhongMaterial#specularMap}.\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     * @type {Number[]}\n     */\n    set specular(value) {\n        let specular = this._state.specular;\n        if (!specular) {\n            specular = this._state.specular = new Float32Array(3);\n        } else if (value && specular[0] === value[0] && specular[1] === value[1] && specular[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            specular[0] = value[0];\n            specular[1] = value[1];\n            specular[2] = value[2];\n        } else {\n            specular[0] = 1;\n            specular[1] = 1;\n            specular[2] = 1;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the PhongMaterial's specular color.\n     *\n     * Multiplies by {@link PhongMaterial#specularMap}.\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     * @type {Number[]}\n     */\n    get specular() {\n        return this._state.specular;\n    }\n\n    /**\n     * Sets the PhongMaterial's emissive color.\n     *\n     * Multiplies by {@link PhongMaterial#emissiveMap}.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     * @type {Number[]}\n     */\n    set emissive(value) {\n        let emissive = this._state.emissive;\n        if (!emissive) {\n            emissive = this._state.emissive = new Float32Array(3);\n        } else if (value && emissive[0] === value[0] && emissive[1] === value[1] && emissive[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            emissive[0] = value[0];\n            emissive[1] = value[1];\n            emissive[2] = value[2];\n        } else {\n            emissive[0] = 0;\n            emissive[1] = 0;\n            emissive[2] = 0;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the PhongMaterial's emissive color.\n     *\n     * Multiplies by {@link PhongMaterial#emissiveMap}.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     * @type {Number[]}\n     */\n    get emissive() {\n        return this._state.emissive;\n    }\n\n    /**\n     * Sets the PhongMaterial alpha.\n     *\n     * This is a factor in the range [0..1] indicating how transparent the PhongMaterial is.\n     *\n     * A value of 0.0 indicates fully transparent, 1.0 is fully opaque.\n     *\n     * Multiplies by {@link PhongMaterial#alphaMap}.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set alpha(value) {\n        value = (value !== undefined && value !== null) ? value : 1.0;\n        if (this._state.alpha === value) {\n            return;\n        }\n        this._state.alpha = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the PhongMaterial alpha.\n     *\n     * This is a factor in the range [0..1] indicating how transparent the PhongMaterial is.\n     *\n     * A value of 0.0 indicates fully transparent, 1.0 is fully opaque.\n     *\n     * Multiplies by {@link PhongMaterial#alphaMap}.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    get alpha() {\n        return this._state.alpha;\n    }\n\n    /**\n     * Sets the PhongMaterial shininess.\n     *\n     * This is a factor in range [0..128] that determines the size and sharpness of the specular highlights create by this PhongMaterial.\n     *\n     * Larger values produce smaller, sharper highlights. A value of 0.0 gives very large highlights that are almost never\n     * desirable. Try values close to 10 for a larger, fuzzier highlight and values of 100 or more for a small, sharp\n     * highlight.\n     *\n     * Default value is ```` 80.0````.\n     *\n     * @type {Number}\n     */\n    set shininess(value) {\n        this._state.shininess = value !== undefined ? value : 80;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the PhongMaterial shininess.\n     *\n     * This is a factor in range [0..128] that determines the size and sharpness of the specular highlights create by this PhongMaterial.\n     *\n     * Larger values produce smaller, sharper highlights. A value of 0.0 gives very large highlights that are almost never\n     * desirable. Try values close to 10 for a larger, fuzzier highlight and values of 100 or more for a small, sharp\n     * highlight.\n     *\n     * Default value is ```` 80.0````.\n     *\n     * @type {Number}\n     */\n    get shininess() {\n        return this._state.shininess;\n    }\n\n    /**\n     * Sets the PhongMaterial's line width.\n     *\n     * This is not supported by WebGL implementations based on DirectX [2019].\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set lineWidth(value) {\n        this._state.lineWidth = value || 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the PhongMaterial's line width.\n     *\n     * This is not supported by WebGL implementations based on DirectX [2019].\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    get lineWidth() {\n        return this._state.lineWidth;\n    }\n\n    /**\n     * Sets the PhongMaterial's point size.\n     *\n     * Default value is 1.0.\n     *\n     * @type {Number}\n     */\n    set pointSize(value) {\n        this._state.pointSize = value || 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the PhongMaterial's point size.\n     *\n     * Default value is 1.0.\n     *\n     * @type {Number}\n     */\n    get pointSize() {\n        return this._state.pointSize;\n    }\n\n    /**\n     * Sets how much {@link ReflectionMap} is reflected by this PhongMaterial.\n     *\n     * This is a scalar in range ````[0-1]````. Default value is ````1.0````.\n     *\n     * The surface will be non-reflective when this is ````0````, and completely mirror-like when it is ````1.0````.\n     *\n     * Multiplies by {@link PhongMaterial#reflectivityMap}.\n     *\n     * @type {Number}\n     */\n    set reflectivity(value) {\n        this._state.reflectivity = value !== undefined ? value : 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets how much {@link ReflectionMap} is reflected by this PhongMaterial.\n     *\n     * This is a scalar in range ````[0-1]````. Default value is ````1.0````.\n     *\n     * The surface will be non-reflective when this is ````0````, and completely mirror-like when it is ````1.0````.\n     *\n     * Multiplies by {@link PhongMaterial#reflectivityMap}.\n     *\n     * @type {Number}\n     */\n    get reflectivity() {\n        return this._state.reflectivity;\n    }\n\n    /**\n     * Gets the PhongMaterials's normal map {@link Texture}.\n     *\n     * @type {Texture}\n     */\n    get normalMap() {\n        return this._normalMap;\n    }\n\n    /**\n     * Gets the PhongMaterials's ambient {@link Texture}.\n     *\n     * Multiplies by {@link PhongMaterial#ambient}.\n     *\n     * @type {Texture}\n     */\n    get ambientMap() {\n        return this._ambientMap;\n    }\n\n    /**\n     * Gets the PhongMaterials's diffuse {@link Texture}.\n     *\n     * Multiplies by {@link PhongMaterial#diffuse}.\n     *\n     * @type {Texture}\n     */\n    get diffuseMap() {\n        return this._diffuseMap;\n    }\n\n    /**\n     * Gets the PhongMaterials's specular {@link Texture}.\n     *\n     * Multiplies by {@link PhongMaterial#specular}.\n     *\n     * @type {Texture}\n     */\n    get specularMap() {\n        return this._specularMap;\n    }\n\n    /**\n     * Gets the PhongMaterials's emissive {@link Texture}.\n     *\n     * Multiplies by {@link PhongMaterial#emissive}.\n     *\n     * @type {Texture}\n     */\n    get emissiveMap() {\n        return this._emissiveMap;\n    }\n\n    /**\n     * Gets the PhongMaterials's alpha {@link Texture}.\n     *\n     * Multiplies by {@link PhongMaterial#alpha}.\n     *\n     * @type {Texture}\n     */\n    get alphaMap() {\n        return this._alphaMap;\n    }\n\n    /**\n     * Gets the PhongMaterials's reflectivity {@link Texture}.\n     *\n     * Multiplies by {@link PhongMaterial#reflectivity}.\n     *\n     * @type {Texture}\n     */\n    get reflectivityMap() {\n        return this._reflectivityMap;\n    }\n\n    /**\n     * Gets the PhongMaterials's ambient occlusion {@link Texture}.\n     *\n     * @type {Texture}\n     */\n    get occlusionMap() {\n        return this._occlusionMap;\n    }\n\n    /**\n     * Gets the PhongMaterials's diffuse {@link Fresnel}.\n     *\n     * Applies to {@link PhongMaterial#diffuse}.\n     *\n     * @type {Fresnel}\n     */\n    get diffuseFresnel() {\n        return this._diffuseFresnel;\n    }\n\n    /**\n     * Gets the PhongMaterials's specular {@link Fresnel}.\n     *\n     * Applies to {@link PhongMaterial#specular}.\n     *\n     * @type {Fresnel}\n     */\n    get specularFresnel() {\n        return this._specularFresnel;\n    }\n\n    /**\n     * Gets the PhongMaterials's emissive {@link Fresnel}.\n     *\n     * Applies to {@link PhongMaterial#emissive}.\n     *\n     * @type {Fresnel}\n     */\n    get emissiveFresnel() {\n        return this._emissiveFresnel;\n    }\n\n    /**\n     * Gets the PhongMaterials's alpha {@link Fresnel}.\n     *\n     * Applies to {@link PhongMaterial#alpha}.\n     *\n     * @type {Fresnel}\n     */\n    get alphaFresnel() {\n        return this._alphaFresnel;\n    }\n\n    /**\n     * Gets the PhongMaterials's reflectivity {@link Fresnel}.\n     *\n     * Applies to {@link PhongMaterial#reflectivity}.\n     *\n     * @type {Fresnel}\n     */\n    get reflectivityFresnel() {\n        return this._reflectivityFresnel;\n    }\n\n    /**\n     * Sets the PhongMaterial's alpha rendering mode.\n     *\n     * This governs how alpha is treated. Alpha is the combined result of {@link PhongMaterial#alpha} and {@link PhongMaterial#alphaMap}.\n     *\n     * Supported values are:\n     *\n     * * \"opaque\" - The alpha value is ignored and the rendered output is fully opaque (default).\n     * * \"mask\" - The rendered output is either fully opaque or fully transparent depending on the alpha value and the specified alpha cutoff value.\n     * * \"blend\" - The alpha value is used to composite the source and destination areas. The rendered output is combined with the background using the normal painting operation (i.e. the Porter and Duff over operator).\n     *\n     *@type {String}\n     */\n    set alphaMode(alphaMode) {\n        alphaMode = alphaMode || \"opaque\";\n        let value = alphaModes$1[alphaMode];\n        if (value === undefined) {\n            this.error(\"Unsupported value for 'alphaMode': \" + alphaMode + \" - defaulting to 'opaque'\");\n            value = \"opaque\";\n        }\n        if (this._state.alphaMode === value) {\n            return;\n        }\n        this._state.alphaMode = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the PhongMaterial's alpha rendering mode.\n     *\n     *@type {String}\n     */\n    get alphaMode() {\n        return alphaModeNames$1[this._state.alphaMode];\n    }\n\n    /**\n     * Sets the PhongMaterial's alpha cutoff value.\n     *\n     * This specifies the cutoff threshold when {@link PhongMaterial#alphaMode} equals \"mask\". If the alpha is greater than or equal to this value then it is rendered as fully\n     * opaque, otherwise, it is rendered as fully transparent. A value greater than 1.0 will render the entire material as fully transparent. This value is ignored for other modes.\n     *\n     * Alpha is the combined result of {@link PhongMaterial#alpha} and {@link PhongMaterial#alphaMap}.\n     *\n     * Default value is ````0.5````.\n     *\n     * @type {Number}\n     */\n    set alphaCutoff(alphaCutoff) {\n        if (alphaCutoff === null || alphaCutoff === undefined) {\n            alphaCutoff = 0.5;\n        }\n        if (this._state.alphaCutoff === alphaCutoff) {\n            return;\n        }\n        this._state.alphaCutoff = alphaCutoff;\n    }\n\n    /**\n     * Gets the PhongMaterial's alpha cutoff value.\n     *\n     * @type {Number}\n     */\n    get alphaCutoff() {\n        return this._state.alphaCutoff;\n    }\n\n    /**\n     * Sets whether backfaces are visible on attached {@link Mesh}es.\n     *\n     * The backfaces will belong to {@link Geometry} compoents that are also attached to the {@link Mesh}es.\n     *\n     * Default is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set backfaces(value) {\n        value = !!value;\n        if (this._state.backfaces === value) {\n            return;\n        }\n        this._state.backfaces = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether backfaces are visible on attached {@link Mesh}es.\n     *\n     * Default is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get backfaces() {\n        return this._state.backfaces;\n    }\n\n    /**\n     * Sets the winding direction of geometry front faces.\n     *\n     * Default is ````\"ccw\"````.\n     * @type {String}\n     */\n    set frontface(value) {\n        value = value !== \"cw\";\n        if (this._state.frontface === value) {\n            return;\n        }\n        this._state.frontface = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the winding direction of front faces on attached {@link Mesh}es.\n     *\n     * Default is ````\"ccw\"````.\n     * @type {String}\n     */\n    get frontface() {\n        return this._state.frontface ? \"ccw\" : \"cw\";\n    }\n\n    /**\n     * Destroys this PhongMaterial.\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\n/**\n * @private\n */\nfunction getExtension (gl, name) {\n    if (gl._cachedExtensions === undefined) {\n        gl._cachedExtensions = {};\n    }\n    if (gl._cachedExtensions[name] !== undefined) {\n        return gl._cachedExtensions[name];\n    }\n    let extension;\n    switch (name) {\n        case 'WEBGL_depth_texture':\n            extension = gl.getExtension('WEBGL_depth_texture') || gl.getExtension('MOZ_WEBGL_depth_texture') || gl.getExtension('WEBKIT_WEBGL_depth_texture');\n            break;\n        case 'EXT_texture_filter_anisotropic':\n            extension = gl.getExtension('EXT_texture_filter_anisotropic') || gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic');\n            break;\n        case 'WEBGL_compressed_texture_s3tc':\n            extension = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('MOZ_WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc');\n            break;\n        case 'WEBGL_compressed_texture_pvrtc':\n            extension = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');\n            break;\n        default:\n            extension = gl.getExtension(name);\n    }\n    gl._cachedExtensions[name] = extension;\n    return extension;\n}\n\n/**\n * @private\n */\nfunction convertConstant(gl, constantVal, encoding = null) {\n\n    let extension;\n    const p = constantVal;\n\n    if (p === UnsignedByteType) return gl.UNSIGNED_BYTE;\n    if (p === UnsignedShort4444Type) return gl.UNSIGNED_SHORT_4_4_4_4;\n    if (p === UnsignedShort5551Type) return gl.UNSIGNED_SHORT_5_5_5_1;\n\n    if (p === ByteType) return gl.BYTE;\n    if (p === ShortType) return gl.SHORT;\n    if (p === UnsignedShortType) return gl.UNSIGNED_SHORT;\n    if (p === IntType) return gl.INT;\n    if (p === UnsignedIntType) return gl.UNSIGNED_INT;\n    if (p === FloatType) return gl.FLOAT;\n\n    if (p === HalfFloatType) {\n        return gl.HALF_FLOAT;\n    }\n\n    if (p === AlphaFormat) return gl.ALPHA;\n    if (p === RGBAFormat) return gl.RGBA;\n    if (p === LuminanceFormat) return gl.LUMINANCE;\n    if (p === LuminanceAlphaFormat) return gl.LUMINANCE_ALPHA;\n    if (p === DepthFormat) return gl.DEPTH_COMPONENT;\n    if (p === DepthStencilFormat) return gl.DEPTH_STENCIL;\n    if (p === RedFormat) return gl.RED;\n\n    if (p === RGBFormat) {\n        return gl.RGBA;\n    }\n\n    // WebGL2 formats.\n\n    if (p === RedIntegerFormat) return gl.RED_INTEGER;\n    if (p === RGFormat) return gl.RG;\n    if (p === RGIntegerFormat) return gl.RG_INTEGER;\n    if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER;\n\n    // S3TC\n\n    if (p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) {\n        if (encoding === sRGBEncoding) {\n            const extension = getExtension(gl, 'WEBGL_compressed_texture_s3tc_srgb');\n            if (extension !== null) {\n                if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT;\n                if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;\n                if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;\n                if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;\n            } else {\n                return null;\n            }\n        } else {\n            extension = getExtension(gl, 'WEBGL_compressed_texture_s3tc');\n            if (extension !== null) {\n                if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n                if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n                if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n                if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n            } else {\n                return null;\n            }\n        }\n    }\n\n    // PVRTC\n\n    if (p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format) {\n        const extension = getExtension(gl, 'WEBGL_compressed_texture_pvrtc');\n        if (extension !== null) {\n            if (p === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n            if (p === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n            if (p === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n            if (p === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n        } else {\n            return null;\n        }\n    }\n\n    // ETC1\n\n    if (p === RGB_ETC1_Format) {\n        const extension = getExtension(gl, 'WEBGL_compressed_texture_etc1');\n        if (extension !== null) {\n            return extension.COMPRESSED_RGB_ETC1_WEBGL;\n        } else {\n            return null;\n        }\n    }\n\n    // ETC2\n\n    if (p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format) {\n        const extension = getExtension(gl, 'WEBGL_compressed_texture_etc');\n        if (extension !== null) {\n            if (p === RGB_ETC2_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2;\n            if (p === RGBA_ETC2_EAC_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC;\n        } else {\n            return null;\n        }\n    }\n\n    // ASTC\n\n    if (p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format ||\n        p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format ||\n        p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format ||\n        p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format ||\n        p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format) {\n        const extension = getExtension(gl, 'WEBGL_compressed_texture_astc');\n        if (extension !== null) {\n            if (p === RGBA_ASTC_4x4_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR;\n            if (p === RGBA_ASTC_5x4_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR;\n            if (p === RGBA_ASTC_5x5_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR;\n            if (p === RGBA_ASTC_6x5_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR;\n            if (p === RGBA_ASTC_6x6_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR;\n            if (p === RGBA_ASTC_8x5_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR;\n            if (p === RGBA_ASTC_8x6_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR;\n            if (p === RGBA_ASTC_8x8_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR;\n            if (p === RGBA_ASTC_10x5_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR;\n            if (p === RGBA_ASTC_10x6_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR;\n            if (p === RGBA_ASTC_10x8_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR;\n            if (p === RGBA_ASTC_10x10_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR;\n            if (p === RGBA_ASTC_12x10_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR;\n            if (p === RGBA_ASTC_12x12_Format) return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR;\n        } else {\n            return null;\n        }\n    }\n\n    // BPTC\n\n    if (p === RGBA_BPTC_Format) {\n        const extension = getExtension(gl, 'EXT_texture_compression_bptc');\n        if (extension !== null) {\n            if (p === RGBA_BPTC_Format) {\n                return (encoding === sRGBEncoding) ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT;\n            }\n        } else {\n            return null;\n        }\n    }\n\n    //\n\n    if (p === UnsignedInt248Type) {\n        return gl.UNSIGNED_INT_24_8;\n    }\n    if (p === RepeatWrapping) {\n        return gl.REPEAT;\n    }\n    if (p === ClampToEdgeWrapping) {\n        return gl.CLAMP_TO_EDGE;\n    }\n    if (p === NearestMipMapNearestFilter) {\n        return gl.NEAREST_MIPMAP_LINEAR;\n    }\n    if (p === NearestMipMapLinearFilter) {\n        return gl.NEAREST_MIPMAP_LINEAR;\n    }\n    if (p === LinearMipMapNearestFilter) {\n        return gl.LINEAR_MIPMAP_NEAREST;\n    }\n    if (p === LinearMipMapLinearFilter) {\n        return gl.LINEAR_MIPMAP_LINEAR;\n    }\n    if (p === NearestFilter) {\n        return gl.NEAREST;\n    }\n    if (p === LinearFilter) {\n        return gl.LINEAR;\n    }\n\n    return null;\n}\n\nconst color$4 = new Uint8Array([0, 0, 0, 1]);\n\n/**\n * @desc A low-level component that represents a 2D WebGL texture.\n *\n * @private\n */\nclass Texture2D {\n\n    constructor({gl, target, format, type, wrapS, wrapT, wrapR, encoding, preloadColor, premultiplyAlpha, flipY}) {\n\n        this.gl = gl;\n\n        this.target = target || gl.TEXTURE_2D;\n        this.format = format || RGBAFormat;\n        this.type = type || UnsignedByteType;\n        this.internalFormat = null;\n        this.premultiplyAlpha = !!premultiplyAlpha;\n        this.flipY = !!flipY;\n        this.unpackAlignment = 4;\n        this.wrapS = wrapS || RepeatWrapping;\n        this.wrapT = wrapT || RepeatWrapping;\n        this.wrapR = wrapR || RepeatWrapping;\n        this.encoding = encoding || sRGBEncoding;\n        this.texture = gl.createTexture();\n\n        if (preloadColor) {\n            this.setPreloadColor(preloadColor); // Prevents \"there is no texture bound to the unit 0\" error\n        }\n\n        this.allocated = true;\n    }\n\n    setPreloadColor(value) {\n        if (!value) {\n            color$4[0] = 0;\n            color$4[1] = 0;\n            color$4[2] = 0;\n            color$4[3] = 255;\n        } else {\n            color$4[0] = Math.floor(value[0] * 255);\n            color$4[1] = Math.floor(value[1] * 255);\n            color$4[2] = Math.floor(value[2] * 255);\n            color$4[3] = Math.floor((value[3] !== undefined ? value[3] : 1) * 255);\n        }\n        const gl = this.gl;\n        gl.bindTexture(this.target, this.texture);\n        if (this.target === gl.TEXTURE_CUBE_MAP) {\n            const faces = [\n                gl.TEXTURE_CUBE_MAP_POSITIVE_X,\n                gl.TEXTURE_CUBE_MAP_NEGATIVE_X,\n                gl.TEXTURE_CUBE_MAP_POSITIVE_Y,\n                gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,\n                gl.TEXTURE_CUBE_MAP_POSITIVE_Z,\n                gl.TEXTURE_CUBE_MAP_NEGATIVE_Z\n            ];\n            for (let i = 0, len = faces.length; i < len; i++) {\n                gl.texImage2D(faces[i], 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, color$4);\n            }\n        } else {\n            gl.texImage2D(this.target, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, color$4);\n        }\n        gl.bindTexture(this.target, null);\n    }\n\n    setTarget(target) {\n        this.target = target || this.gl.TEXTURE_2D;\n    }\n\n    setImage(image, props = {}) {\n\n        const gl = this.gl;\n\n        if (props.format !== undefined) {\n            this.format = props.format;\n        }\n        if (props.internalFormat !== undefined) {\n            this.internalFormat = props.internalFormat;\n        }\n        if (props.encoding !== undefined) {\n            this.encoding = props.encoding;\n        }\n        if (props.type !== undefined) {\n            this.type = props.type;\n        }\n        if (props.flipY !== undefined) {\n            this.flipY = props.flipY;\n        }\n        if (props.premultiplyAlpha !== undefined) {\n            this.premultiplyAlpha = props.premultiplyAlpha;\n        }\n        if (props.unpackAlignment !== undefined) {\n            this.unpackAlignment = props.unpackAlignment;\n        }\n        if (props.minFilter !== undefined) {\n            this.minFilter = props.minFilter;\n        }\n        if (props.magFilter !== undefined) {\n            this.magFilter = props.magFilter;\n        }\n        if (props.wrapS !== undefined) {\n            this.wrapS = props.wrapS;\n        }\n        if (props.wrapT !== undefined) {\n            this.wrapT = props.wrapT;\n        }\n        if (props.wrapR !== undefined) {\n            this.wrapR = props.wrapR;\n        }\n\n        let generateMipMap = false;\n\n        gl.bindTexture(this.target, this.texture);\n\n        const bak1 = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL);\n        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.flipY);\n\n        const bak2 = gl.getParameter(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL);\n        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);\n\n        const bak3 = gl.getParameter(gl.UNPACK_ALIGNMENT);\n        gl.pixelStorei(gl.UNPACK_ALIGNMENT, this.unpackAlignment);\n\n        const bak4 = gl.getParameter(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL);        gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);\n\n        const minFilter = convertConstant(gl, this.minFilter);\n        gl.texParameteri(this.target, gl.TEXTURE_MIN_FILTER, minFilter);\n\n        if (minFilter === gl.NEAREST_MIPMAP_NEAREST\n            || minFilter === gl.LINEAR_MIPMAP_NEAREST\n            || minFilter === gl.NEAREST_MIPMAP_LINEAR\n            || minFilter === gl.LINEAR_MIPMAP_LINEAR) {\n            generateMipMap = true;\n        }\n\n        const magFilter = convertConstant(gl, this.magFilter);\n        if (magFilter) {\n            gl.texParameteri(this.target, gl.TEXTURE_MAG_FILTER, magFilter);\n        }\n\n        const wrapS = convertConstant(gl, this.wrapS);\n        if (wrapS) {\n            gl.texParameteri(this.target, gl.TEXTURE_WRAP_S, wrapS);\n        }\n\n        const wrapT = convertConstant(gl, this.wrapT);\n        if (wrapT) {\n            gl.texParameteri(this.target, gl.TEXTURE_WRAP_T, wrapT);\n        }\n\n        const glFormat = convertConstant(gl, this.format, this.encoding);\n        const glType = convertConstant(gl, this.type);\n        const glInternalFormat = getInternalFormat(gl, this.internalFormat, glFormat, glType, this.encoding, false);\n\n        if (this.target === gl.TEXTURE_CUBE_MAP) {\n            if (utils.isArray(image)) {\n                const images = image;\n                const faces = [\n                    gl.TEXTURE_CUBE_MAP_POSITIVE_X,\n                    gl.TEXTURE_CUBE_MAP_NEGATIVE_X,\n                    gl.TEXTURE_CUBE_MAP_POSITIVE_Y,\n                    gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,\n                    gl.TEXTURE_CUBE_MAP_POSITIVE_Z,\n                    gl.TEXTURE_CUBE_MAP_NEGATIVE_Z\n                ];\n                for (let i = 0, len = faces.length; i < len; i++) {\n                    gl.texImage2D(faces[i], 0, glInternalFormat, glFormat, glType, images[i]);\n                }\n            }\n        } else {\n            gl.texImage2D(gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image);\n        }\n\n        if (generateMipMap) {\n            gl.generateMipmap(this.target);\n        }\n\n        gl.bindTexture(this.target, null);\n\n        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, bak1);\n        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, bak2);\n        gl.pixelStorei(gl.UNPACK_ALIGNMENT, bak3);\n        gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, bak4);\n    }\n\n    setCompressedData({mipmaps, props = {}}) {\n\n        const gl = this.gl;\n        const levels = mipmaps.length;\n\n        // Cache props\n\n        if (props.format !== undefined) {\n            this.format = props.format;\n        }\n        if (props.internalFormat !== undefined) {\n            this.internalFormat = props.internalFormat;\n        }\n        if (props.encoding !== undefined) {\n            this.encoding = props.encoding;\n        }\n        if (props.type !== undefined) {\n            this.type = props.type;\n        }\n        if (props.flipY !== undefined) {\n            this.flipY = props.flipY;\n        }\n        if (props.premultiplyAlpha !== undefined) {\n            this.premultiplyAlpha = props.premultiplyAlpha;\n        }\n        if (props.unpackAlignment !== undefined) {\n            this.unpackAlignment = props.unpackAlignment;\n        }\n        if (props.minFilter !== undefined) {\n            this.minFilter = props.minFilter;\n        }\n        if (props.magFilter !== undefined) {\n            this.magFilter = props.magFilter;\n        }\n        if (props.wrapS !== undefined) {\n            this.wrapS = props.wrapS;\n        }\n        if (props.wrapT !== undefined) {\n            this.wrapT = props.wrapT;\n        }\n        if (props.wrapR !== undefined) {\n            this.wrapR = props.wrapR;\n        }\n\n        gl.activeTexture(gl.TEXTURE0 + 0);\n        gl.bindTexture(this.target, this.texture);\n\n        let supportsMips = mipmaps.length > 1;\n\n        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.flipY);\n        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);\n        gl.pixelStorei(gl.UNPACK_ALIGNMENT, this.unpackAlignment);\n        gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);\n\n        const wrapS = convertConstant(gl, this.wrapS);\n        if (wrapS) {\n            gl.texParameteri(this.target, gl.TEXTURE_WRAP_S, wrapS);\n        }\n\n        const wrapT = convertConstant(gl, this.wrapT);\n        if (wrapT) {\n            gl.texParameteri(this.target, gl.TEXTURE_WRAP_T, wrapT);\n        }\n\n        if (this.type === gl.TEXTURE_3D || this.type === gl.TEXTURE_2D_ARRAY) {\n            const wrapR = convertConstant(gl, this.wrapR);\n            if (wrapR) {\n                gl.texParameteri(this.target, gl.TEXTURE_WRAP_R, wrapR);\n            }\n            gl.texParameteri(this.type, gl.TEXTURE_WRAP_R, wrapR);\n        }\n\n        if (supportsMips) {\n            gl.texParameteri(this.target, gl.TEXTURE_MIN_FILTER, filterFallback(gl, this.minFilter));\n            gl.texParameteri(this.target, gl.TEXTURE_MAG_FILTER, filterFallback(gl, this.magFilter));\n\n        } else {\n            gl.texParameteri(this.target, gl.TEXTURE_MIN_FILTER, convertConstant(gl, this.minFilter));\n            gl.texParameteri(this.target, gl.TEXTURE_MAG_FILTER, convertConstant(gl, this.magFilter));\n        }\n\n        const glFormat = convertConstant(gl, this.format, this.encoding);\n        const glType = convertConstant(gl, this.type);\n        const glInternalFormat = getInternalFormat(gl, this.internalFormat, glFormat, glType, this.encoding, false);\n\n        gl.texStorage2D(gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);\n\n        for (let i = 0, len = mipmaps.length; i < len; i++) {\n\n            const mipmap = mipmaps[i];\n\n            if (this.format !== RGBAFormat) {\n                if (glFormat !== null) {\n                    gl.compressedTexSubImage2D(gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data);\n                } else {\n                    console.warn('Attempt to load unsupported compressed texture format in .setCompressedData()');\n                }\n            } else {\n                gl.texSubImage2D(gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);\n            }\n        }\n\n        //    if (generateMipMap) {\n        // //       gl.generateMipmap(this.target); // Only for roughness textures?\n        //    }\n\n        gl.bindTexture(this.target, null);\n    }\n\n    setProps(props) {\n        const gl = this.gl;\n        gl.bindTexture(this.target, this.texture);\n        this._uploadProps(props);\n        gl.bindTexture(this.target, null);\n    }\n\n    _uploadProps(props) {\n        const gl = this.gl;\n        if (props.format !== undefined) {\n            this.format = props.format;\n        }\n        if (props.internalFormat !== undefined) {\n            this.internalFormat = props.internalFormat;\n        }\n        if (props.encoding !== undefined) {\n            this.encoding = props.encoding;\n        }\n        if (props.type !== undefined) {\n            this.type = props.type;\n        }\n        if (props.minFilter !== undefined) {\n            const minFilter = convertConstant(gl, props.minFilter);\n            if (minFilter) {\n                this.minFilter = props.minFilter;\n                gl.texParameteri(this.target, gl.TEXTURE_MIN_FILTER, minFilter);\n                if (minFilter === gl.NEAREST_MIPMAP_NEAREST || minFilter === gl.LINEAR_MIPMAP_NEAREST || minFilter === gl.NEAREST_MIPMAP_LINEAR || minFilter === gl.LINEAR_MIPMAP_LINEAR) {\n                    gl.generateMipmap(this.target);\n                }\n            }\n        }\n        if (props.magFilter !== undefined) {\n            const magFilter = convertConstant(gl, props.magFilter);\n            if (magFilter) {\n                this.magFilter = props.magFilter;\n                gl.texParameteri(this.target, gl.TEXTURE_MAG_FILTER, magFilter);\n            }\n        }\n        if (props.wrapS !== undefined) {\n            const wrapS = convertConstant(gl, props.wrapS);\n            if (wrapS) {\n                this.wrapS = props.wrapS;\n                gl.texParameteri(this.target, gl.TEXTURE_WRAP_S, wrapS);\n            }\n        }\n        if (props.wrapT !== undefined) {\n            const wrapT = convertConstant(gl, props.wrapT);\n            if (wrapT) {\n                this.wrapT = props.wrapT;\n                gl.texParameteri(this.target, gl.TEXTURE_WRAP_T, wrapT);\n            }\n        }\n    }\n\n    bind(unit) {\n        if (!this.allocated) {\n            return;\n        }\n        if (this.texture) {\n            const gl = this.gl;\n            gl.activeTexture(gl[\"TEXTURE\" + unit]);\n            gl.bindTexture(this.target, this.texture);\n            return true;\n        }\n        return false;\n    }\n\n    unbind(unit) {\n        if (!this.allocated) {\n            return;\n        }\n        if (this.texture) {\n            const gl = this.gl;\n            gl.activeTexture(gl[\"TEXTURE\" + unit]);\n            gl.bindTexture(this.target, null);\n        }\n    }\n\n    destroy() {\n        if (!this.allocated) {\n            return;\n        }\n        if (this.texture) {\n            this.gl.deleteTexture(this.texture);\n            this.texture = null;\n        }\n    }\n}\n\nfunction getInternalFormat(gl, internalFormatName, glFormat, glType, encoding, isVideoTexture = false) {\n    if (internalFormatName !== null) {\n        if (gl[internalFormatName] !== undefined) {\n            return gl[internalFormatName];\n        }\n        console.warn('Attempt to use non-existing WebGL internal format \\'' + internalFormatName + '\\'');\n    }\n    let internalFormat = glFormat;\n    if (glFormat === gl.RED) {\n        if (glType === gl.FLOAT) internalFormat = gl.R32F;\n        if (glType === gl.HALF_FLOAT) internalFormat = gl.R16F;\n        if (glType === gl.UNSIGNED_BYTE) internalFormat = gl.R8;\n    }\n    if (glFormat === gl.RG) {\n        if (glType === gl.FLOAT) internalFormat = gl.RG32F;\n        if (glType === gl.HALF_FLOAT) internalFormat = gl.RG16F;\n        if (glType === gl.UNSIGNED_BYTE) internalFormat = gl.RG8;\n    }\n    if (glFormat === gl.RGBA) {\n        if (glType === gl.FLOAT) internalFormat = gl.RGBA32F;\n        if (glType === gl.HALF_FLOAT) internalFormat = gl.RGBA16F;\n        if (glType === gl.UNSIGNED_BYTE) internalFormat = (encoding === sRGBEncoding && isVideoTexture === false) ? gl.SRGB8_ALPHA8 : gl.RGBA8;\n        if (glType === gl.UNSIGNED_SHORT_4_4_4_4) internalFormat = gl.RGBA4;\n        if (glType === gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = gl.RGB5_A1;\n    }\n    if (internalFormat === gl.R16F || internalFormat === gl.R32F ||\n        internalFormat === gl.RG16F || internalFormat === gl.RG32F ||\n        internalFormat === gl.RGBA16F || internalFormat === gl.RGBA32F) {\n        getExtension(gl, 'EXT_color_buffer_float');\n    }\n    return internalFormat;\n}\n\nfunction filterFallback(gl, f) {\n    if (f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter) {\n        return gl.NEAREST;\n    }\n    return gl.LINEAR;\n\n}\n\nfunction ensureImageSizePowerOfTwo$1(image) {\n    if (!isPowerOfTwo$1(image.width) || !isPowerOfTwo$1(image.height)) {\n        const canvas = document.createElement(\"canvas\");\n        canvas.width = nextHighestPowerOfTwo$1(image.width);\n        canvas.height = nextHighestPowerOfTwo$1(image.height);\n        const ctx = canvas.getContext(\"2d\");\n        ctx.drawImage(image,\n            0, 0, image.width, image.height,\n            0, 0, canvas.width, canvas.height);\n        image = canvas;\n    }\n    return image;\n}\n\nfunction isPowerOfTwo$1(x) {\n    return (x & (x - 1)) === 0;\n}\n\nfunction nextHighestPowerOfTwo$1(x) {\n    --x;\n    for (let i = 1; i < 32; i <<= 1) {\n        x = x | x >> i;\n    }\n    return x + 1;\n}\n\n/**\n * @desc A 2D texture map.\n *\n * * Textures are attached to {@link Material}s, which are attached to {@link Mesh}es.\n * * To create a Texture from an image file, set {@link Texture#src} to the image file path.\n * * To create a Texture from an HTMLImageElement, set the Texture's {@link Texture#image} to the HTMLImageElement.\n *\n * ## Usage\n *\n * In this example we have a Mesh with a {@link PhongMaterial} which applies diffuse {@link Texture}, and a {@link buildTorusGeometry} which builds a {@link ReadableGeometry}.\n *\n * Note that xeokit will ignore {@link PhongMaterial#diffuse} and {@link PhongMaterial#specular}, since we override those\n * with {@link PhongMaterial#diffuseMap} and {@link PhongMaterial#specularMap}. The {@link Texture} pixel colors directly\n * provide the diffuse and specular components for each fragment across the {@link ReadableGeometry} surface.\n *\n * [[Run this example](/examples/index.html#materials_Texture)]\n *\n * ```` javascript\n * import {Viewer, Mesh, buildTorusGeometry,\n *      ReadableGeometry, PhongMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [0, 0, 5];\n * viewer.camera.look = [0, 0, 0];\n * viewer.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry({\n *          center: [0, 0, 0],\n *          radius: 1.5,\n *          tube: 0.5,\n *          radialSegments: 32,\n *          tubeSegments: 24,\n *          arc: Math.PI * 2.0\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *          ambient: [0.9, 0.3, 0.9],\n *          shininess: 30,\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse/uvGrid2.jpg\"\n *          })\n *      })\n * });\n *````\n */\nclass Texture extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Texture\";\n    }\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this Texture as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID for this Texture, unique among all components in the parent scene, generated automatically when omitted.\n     * @param {String} [cfg.src=null] Path to image file to load into this Texture. See the {@link Texture#src} property for more info.\n     * @param {HTMLImageElement} [cfg.image=null] HTML Image object to load into this Texture. See the {@link Texture#image} property for more info.\n     * @param {Number} [cfg.minFilter=LinearMipmapLinearFilter] How the texture is sampled when a texel covers less than one pixel.\n     * Supported values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}.\n     * @param {Number} [cfg.magFilter=LinearFilter] How the texture is sampled when a texel covers more than one pixel. Supported values are {@link LinearFilter} and {@link NearestFilter}.\n     * @param {Number} [cfg.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n     * @param {Number} [cfg.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}..\n     * @param {Boolean} [cfg.flipY=false] Flips this Texture's source data along its vertical axis when ````true````.\n     * @param  {Number} [cfg.encoding=LinearEncoding] Encoding format. Supported values are {@link LinearEncoding} and {@link sRGBEncoding}.\n     * @param {Number[]} [cfg.translate=[0,0]] 2D translation vector that will be added to texture's *S* and *T* coordinates.\n     * @param {Number[]} [cfg.scale=[1,1]] 2D scaling vector that will be applied to texture's *S* and *T* coordinates.\n     * @param {Number} [cfg.rotate=0] Rotation, in degrees, that will be applied to texture's *S* and *T* coordinates.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            texture: new Texture2D({gl: this.scene.canvas.gl}),\n            matrix: math.identityMat4(),\n            hasMatrix: (cfg.translate && (cfg.translate[0] !== 0 || cfg.translate[1] !== 0)) || (!!cfg.rotate) || (cfg.scale && (cfg.scale[0] !== 0 || cfg.scale[1] !== 0)),\n            minFilter: this._checkMinFilter(cfg.minFilter),\n            magFilter: this._checkMagFilter(cfg.magFilter),\n            wrapS: this._checkWrapS(cfg.wrapS),\n            wrapT: this._checkWrapT(cfg.wrapT),\n            flipY: this._checkFlipY(cfg.flipY),\n            encoding: this._checkEncoding(cfg.encoding)\n        });\n\n        // Data source\n\n        this._src = null;\n        this._image = null;\n\n        // Transformation\n\n        this._translate = math.vec2([0, 0]);\n        this._scale = math.vec2([1, 1]);\n        this._rotate = math.vec2([0, 0]);\n\n        this._matrixDirty = false;\n\n        // Transform\n\n        this.translate = cfg.translate;\n        this.scale = cfg.scale;\n        this.rotate = cfg.rotate;\n\n        // Data source\n\n        if (cfg.src) {\n            this.src = cfg.src; // Image file\n        } else if (cfg.image) {\n            this.image = cfg.image; // Image object\n        }\n\n        stats.memory.textures++;\n    }\n\n    _checkMinFilter(value) {\n        value = value || LinearMipMapLinearFilter;\n        if (value !== LinearFilter &&\n            value !== LinearMipMapNearestFilter &&\n            value !== LinearMipMapLinearFilter &&\n            value !== NearestMipMapLinearFilter &&\n            value !== NearestMipMapNearestFilter) {\n            this.error(\"Unsupported value for 'minFilter' - supported values are LinearFilter, LinearMipMapNearestFilter, NearestMipMapNearestFilter, \" +\n                \"NearestMipMapLinearFilter and LinearMipMapLinearFilter. Defaulting to LinearMipMapLinearFilter.\");\n            value = LinearMipMapLinearFilter;\n        }\n        return value;\n    }\n\n    _checkMagFilter(value) {\n        value = value || LinearFilter;\n        if (value !== LinearFilter && value !== NearestFilter) {\n            this.error(\"Unsupported value for 'magFilter' - supported values are LinearFilter and NearestFilter. Defaulting to LinearFilter.\");\n            value = LinearFilter;\n        }\n        return value;\n    }\n\n    _checkWrapS(value) {\n        value = value || RepeatWrapping;\n        if (value !== ClampToEdgeWrapping && value !== MirroredRepeatWrapping && value !== RepeatWrapping) {\n            this.error(\"Unsupported value for 'wrapS' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.\");\n            value = RepeatWrapping;\n        }\n        return value;\n    }\n\n    _checkWrapT(value) {\n        value = value || RepeatWrapping;\n        if (value !== ClampToEdgeWrapping && value !== MirroredRepeatWrapping && value !== RepeatWrapping) {\n            this.error(\"Unsupported value for 'wrapT' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.\");\n            value = RepeatWrapping;\n        }\n        return value;\n    }\n\n    _checkFlipY(value) {\n        return !!value;\n    }\n\n    _checkEncoding(value) {\n        value = value || LinearEncoding;\n        if (value !== LinearEncoding && value !== sRGBEncoding) {\n            this.error(\"Unsupported value for 'encoding' - supported values are LinearEncoding and sRGBEncoding. Defaulting to LinearEncoding.\");\n            value = LinearEncoding;\n        }\n        return value;\n    }\n\n    _update() {\n        const state = this._state;\n        if (this._matrixDirty) {\n            let matrix;\n            let t;\n            if (this._translate[0] !== 0 || this._translate[1] !== 0) {\n                matrix = math.translationMat4v([this._translate[0], this._translate[1], 0], this._state.matrix);\n            }\n            if (this._scale[0] !== 1 || this._scale[1] !== 1) {\n                t = math.scalingMat4v([this._scale[0], this._scale[1], 1]);\n                matrix = matrix ? math.mulMat4(matrix, t) : t;\n            }\n            if (this._rotate !== 0) {\n                t = math.rotationMat4v(this._rotate * 0.0174532925, [0, 0, 1]);\n                matrix = matrix ? math.mulMat4(matrix, t) : t;\n            }\n            if (matrix) {\n                state.matrix = matrix;\n            }\n            this._matrixDirty = false;\n        }\n        this.glRedraw();\n    }\n\n\n    /**\n     * Sets an HTML DOM Image object to source this Texture from.\n     *\n     * Sets {@link Texture#src} null.\n     *\n     * @type {HTMLImageElement}\n     */\n    set image(value) {\n        this._image = ensureImageSizePowerOfTwo$1(value);\n        this._image.crossOrigin = \"Anonymous\";\n        this._state.texture.setImage(this._image, this._state);\n        this._src = null;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets HTML DOM Image object this Texture is sourced from, if any.\n     *\n     * Returns null if not set.\n     *\n     * @type {HTMLImageElement}\n     */\n    get image() {\n        return this._image;\n    }\n\n    /**\n     * Sets path to an image file to source this Texture from.\n     *\n     * Sets {@link Texture#image} null.\n     *\n     * @type {String}\n     */\n    set src(src) {\n        this.scene.loading++;\n        this.scene.canvas.spinner.processes++;\n        const self = this;\n        let image = new Image();\n        image.onload = function () {\n            image = ensureImageSizePowerOfTwo$1(image);\n            self._state.texture.setImage(image, self._state);\n            self.scene.loading--;\n            self.glRedraw();\n            self.scene.canvas.spinner.processes--;\n        };\n        image.src = src;\n        this._src = src;\n        this._image = null;\n    }\n\n    /**\n     * Gets path to the image file this Texture from, if any.\n     *\n     * Returns null if not set.\n     *\n     * @type {String}\n     */\n    get src() {\n        return this._src;\n    }\n\n    /**\n     * Sets the 2D translation vector added to this Texture's *S* and *T* UV coordinates.\n     *\n     * Default value is ````[0, 0]````.\n     *\n     * @type {Number[]}\n     */\n    set translate(value) {\n        this._translate.set(value || [0, 0]);\n        this._matrixDirty = true;\n        this._needUpdate();\n    }\n\n    /**\n     * Gets the 2D translation vector added to this Texture's *S* and *T* UV coordinates.\n     *\n     * Default value is ````[0, 0]````.\n     *\n     * @type {Number[]}\n     */\n    get translate() {\n        return this._translate;\n    }\n\n    /**\n     * Sets the 2D scaling vector that will be applied to this Texture's *S* and *T* UV coordinates.\n     *\n     * Default value is ````[1, 1]````.\n     *\n     * @type {Number[]}\n     */\n    set scale(value) {\n        this._scale.set(value || [1, 1]);\n        this._matrixDirty = true;\n        this._needUpdate();\n    }\n\n    /**\n     * Gets the 2D scaling vector that will be applied to this Texture's *S* and *T* UV coordinates.\n     *\n     * Default value is ````[1, 1]````.\n     *\n     * @type {Number[]}\n     */\n    get scale() {\n        return this._scale;\n    }\n\n    /**\n     * Sets the rotation angles, in degrees, that will be applied to this Texture's *S* and *T* UV coordinates.\n     *\n     * Default value is ````0````.\n     *\n     * @type {Number}\n     */\n    set rotate(value) {\n        value = value || 0;\n        if (this._rotate === value) {\n            return;\n        }\n        this._rotate = value;\n        this._matrixDirty = true;\n        this._needUpdate();\n    }\n\n    /**\n     * Gets the rotation angles, in degrees, that will be applied to this Texture's *S* and *T* UV coordinates.\n     *\n     * Default value is ````0````.\n     *\n     * @type {Number}\n     */\n    get rotate() {\n        return this._rotate;\n    }\n\n    /**\n     * Gets how this Texture is sampled when a texel covers less than one pixel.\n     *\n     * Options are:\n     *\n     * * NearestFilter - Uses the value of the texture element that is nearest\n     * (in Manhattan distance) to the center of the pixel being textured.\n     *\n     * * LinearFilter - Uses the weighted average of the four texture elements that are\n     * closest to the center of the pixel being textured.\n     *\n     * * NearestMipMapNearestFilter - Chooses the mipmap that most closely matches the\n     * size of the pixel being textured and uses the \"nearest\" criterion (the texture\n     * element nearest to the center of the pixel) to produce a texture value.\n     *\n     * * LinearMipMapNearestFilter - Chooses the mipmap that most closely matches the size of\n     * the pixel being textured and uses the \"linear\" criterion (a weighted average of the\n     * four texture elements that are closest to the center of the pixel) to produce a\n     * texture value.\n     *\n     * * NearestMipMapLinearFilter - Chooses the two mipmaps that most closely\n     * match the size of the pixel being textured and uses the \"nearest\" criterion\n     * (the texture element nearest to the center of the pixel) to produce a texture\n     * value from each mipmap. The final texture value is a weighted average of those two\n     * values.\n     *\n     * * LinearMipMapLinearFilter - (default) - Chooses the two mipmaps that most closely match the size\n     * of the pixel being textured and uses the \"linear\" criterion (a weighted average\n     * of the four texture elements that are closest to the center of the pixel) to\n     * produce a texture value from each mipmap. The final texture value is a weighted\n     * average of those two values.\n     *\n     * Default value is LinearMipMapLinearFilter.\n     *\n     *  @type {Number}\n     */\n    get minFilter() {\n        return this._state.minFilter;\n    }\n\n    /**\n     * Gets how this Texture is sampled when a texel covers more than one pixel.\n     *\n     * * NearestFilter - Uses the value of the texture element that is nearest\n     * (in Manhattan distance) to the center of the pixel being textured.\n     * * LinearFilter - (default) - Uses the weighted average of the four texture elements that are\n     * closest to the center of the pixel being textured.\n     *\n     * Default value is LinearMipMapLinearFilter.\n     *\n     * @type {Number}\n     */\n    get magFilter() {\n        return this._state.magFilter;\n    }\n\n    /**\n     * Gets the wrap parameter for this Texture's *S* coordinate.\n     *\n     * Values can be:\n     *\n     * * ClampToEdgeWrapping -  causes *S* coordinates to be clamped to the size of the texture.\n     * * MirroredRepeatWrapping - causes the *S* coordinate to be set to the fractional part of the texture coordinate\n     * if the integer part of *S* is even; if the integer part of *S* is odd, then the *S* texture coordinate is\n     * set to *1 - frac ⁡ S* , where *frac ⁡ S* represents the fractional part of *S*.\n     * * RepeatWrapping - (default) - causes the integer part of the *S* coordinate to be ignored; xeokit uses only the\n     * fractional part, thereby creating a repeating pattern.\n     *\n     * Default value is RepeatWrapping.\n     *\n     * @type {Number}\n     */\n    get wrapS() {\n        return this._state.wrapS;\n    }\n\n    /**\n     * Gets the wrap parameter for this Texture's *T* coordinate.\n     *\n     * Values can be:\n     *\n     * * ClampToEdgeWrapping -  causes *S* coordinates to be clamped to the size of the texture.\n     *  * MirroredRepeatWrapping - causes the *S* coordinate to be set to the fractional part of the texture coordinate\n     * if the integer part of *S* is even; if the integer part of *S* is odd, then the *S* texture coordinate is\n     * set to *1 - frac ⁡ S* , where *frac ⁡ S* represents the fractional part of *S*.\n     * * RepeatWrapping - (default) - causes the integer part of the *S* coordinate to be ignored; xeokit uses only the\n     * fractional part, thereby creating a repeating pattern.\n     *\n     * Default value is RepeatWrapping.\n     *\n     * @type {Number}\n     */\n    get wrapT() {\n        return this._state.wrapT;\n    }\n\n    /**\n     * Gets if this Texture's source data is flipped along its vertical axis.\n     *\n     * @type {Number}\n     */\n    get flipY() {\n        return this._state.flipY;\n    }\n\n    /**\n     * Gets the Texture's encoding format.\n     *\n     * @type {Number}\n     */\n    get encoding() {\n        return this._state.encoding;\n    }\n\n    /**\n     * Destroys this Texture\n     */\n    destroy() {\n        super.destroy();\n        if (this._state.texture) {\n            this._state.texture.destroy();\n        }\n        this._state.destroy();\n        stats.memory.textures--;\n    }\n}\n\nconst tempVec3$7 = math.vec3();\nconst tempVec3b$a = math.vec3();\nmath.vec3();\nconst zeroVec$1 = math.vec3([0, -1, 0]);\nconst tempQuat = math.vec4([0, 0, 0, 1]);\n\n/**\n *  @desc A plane-shaped 3D object containing a bitmap image.\n *\n * Use ````ImagePlane```` to embed bitmap images in your scenes.\n *\n * As shown in the examples below, ````ImagePlane```` is useful for creating ground planes from satellite maps and embedding 2D plan\n * view images in cross-section slicing planes.\n *\n * # Example 1: Create a ground plane from a satellite image\n *\n * In our first example, we'll load the Schependomlaan model, then use\n * an ````ImagePlane```` to create a ground plane, which will contain\n * a satellite image sourced from Google Maps.\n *\n * <img src=\"http://xeokit.io/img/docs/ImagePlane/schependomlaanGoogleSatMapMed.png\">\n *\n * [<img src=\"http://xeokit.io/img/docs/ImagePlane/ImagePlane.png\">](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#ImagePlane_groundPlane)\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#ImagePlane_groundPlane)]\n *\n * ````javascript\n * import {Viewer, ImagePlane, XKTLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n *  });\n *\n * viewer.camera.eye = [-8.31, 42.21, 54.30];\n * viewer.camera.look = [-0.86, 15.40, 14.90];\n * viewer.camera.up = [0.10, 0.83, -0.54];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * xktLoader.load({             // Load IFC model\n *      id: \"myModel\",\n *      src: \"./models/xkt/Schependomlaan.xkt\",\n *      edges: true,\n *\n *      rotation: [0, 22, 0],   // Rotate, position and scale the model to align it correctly with the ImagePlane\n *      position: [-8, 0, 15],\n *      scale: [1.1, 1.1, 1.1]\n *  });\n *\n * new ImagePlane(viewer.scene, {\n *      src: \"./images/schependomlaanSatMap.png\",       // Google satellite image; accepted file types are PNG and JPEG\n *      visible: true,                                  // Show the ImagePlane\n *      gridVisible: true,                              // Show the grid - grid is only visible when ImagePlane is also visible\n *      size: 190,                                      // Size of ImagePlane's longest edge\n *      position: [0, -1, 0],                           // World-space position of ImagePlane's center\n *      rotation: [0, 0, 0],                            // Euler angles for X, Y and Z\n *      opacity: 1.0,                                   // Fully opaque\n *      collidable: false,                              // ImagePlane does not contribute to Scene boundary\n *      clippable: true,                                // ImagePlane can be clipped by SectionPlanes\n *      pickable: true                                  // Allow the ground plane to be picked\n * });\n * ````\n *<br>\n *\n * # Example 2: Embed an image in a cross-section plane\n *\n * In our second example, we'll load the Schependomlaan model again, then slice it in half with\n * a {@link SectionPlanesPlugin}, then use an ````ImagePlane```` to embed a 2D plan view image in the slicing plane.\n *\n * <img src=\"http://xeokit.io/img/docs/ImagePlane/schependomlaanPlanViewMed.png\">\n *\n * [<img src=\"http://xeokit.io/img/docs/ImagePlane/ImagePlane_planView.png\">](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#ImagePlane_imageInSectionPlane)\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#ImagePlane_imageInSectionPlane)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, SectionPlanesPlugin, ImagePlane} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.camera.eye = [-9.11, 20.01, 5.13];\n * viewer.camera.look = [9.07, 0.77, -9.78];\n * viewer.camera.up = [0.47, 0.76, -0.38];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const sectionPlanes = new SectionPlanesPlugin(viewer, {\n *     overviewVisible: false\n * });\n *\n * model = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/xkt/schependomlaan/schependomlaan.xkt\",\n *     metaModelSrc: \"./metaModels/schependomlaan/metaModel.json\",\n *     edges: true,\n * });\n *\n * const sectionPlane = sectionPlanes.createSectionPlane({\n *     id: \"mySectionPlane\",\n *     pos: [10.95, 1.95, -10.35],\n *     dir: [0.0, -1.0, 0.0]\n * });\n *\n * const imagePlane = new ImagePlane(viewer.scene, {\n *     src: \"./images/schependomlaanPlanView.png\",  // Plan view image; accepted file types are PNG and JPEG\n *     visible: true,\n *     gridVisible: true,\n *     size: 23.95,\n *     position: sectionPlane.pos,\n *     dir: sectionPlane.dir,\n *     collidable: false,\n *     opacity: 0.75,\n *     clippable: false,                            // Don't allow ImagePlane to be clipped by the SectionPlane\n *     pickable: false                              // Don't allow ImagePlane to be picked\n *  });\n * ````\n */\nclass ImagePlane extends Component {\n\n    /**\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this ````ImagePlane```` as well.\n     * @param {*} [cfg]  ````ImagePlane```` configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Boolean} [cfg.visible=true] Indicates whether or not this ````ImagePlane```` is visible.\n     * @param {Boolean} [cfg.gridVisible=true] Indicates whether or not the grid is visible.  Grid is only visible when ````ImagePlane```` is also visible.\n     * @param {Number[]} [cfg.position=[0,0,0]] World-space position of the ````ImagePlane````.\n     * @param {Number[]} [cfg.size=1] World-space size of the longest edge of the ````ImagePlane````. Note that\n     * ````ImagePlane```` sets its aspect ratio to match its image. If we set a value of ````1000````, and the image\n     * has size ````400x300````, then the ````ImagePlane```` will then have size ````1000 x 750````.\n     * @param {Number[]} [cfg.rotation=[0,0,0]] Local rotation of the ````ImagePlane````, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Modelling transform matrix for the ````ImagePlane````. Overrides the ````position````, ````size```, ````rotation```` and ````dir```` parameters.\n     * @param {Boolean} [cfg.collidable=true] Indicates if the ````ImagePlane```` is initially included in boundary calculations.\n     * @param {Boolean} [cfg.clippable=true] Indicates if the ````ImagePlane```` is initially clippable.\n     * @param {Boolean} [cfg.pickable=true] Indicates if the ````ImagePlane```` is initially pickable.\n     * @param {Number} [cfg.opacity=1.0] ````ImagePlane````'s initial opacity factor, multiplies by the rendered fragment alpha.\n     * @param {String} [cfg.src] URL of image. Accepted file types are PNG and JPEG.\n     * @param {HTMLImageElement} [cfg.image] An ````HTMLImageElement```` to source the image from. Overrides ````src````.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._src = null;\n        this._image = null;\n        this._pos = math.vec3();\n        this._origin = math.vec3();\n        this._rtcPos = math.vec3();\n        this._dir = math.vec3();\n        this._size = 1.0;\n        this._imageSize = math.vec2();\n\n        this._texture = new Texture(this);\n\n        this._plane = new Mesh(this, {\n\n            geometry: new ReadableGeometry(this, buildPlaneGeometry({\n                center: [0, 0, 0],\n                xSize: 1,\n                zSize: 1,\n                xSegments: 10,\n                zSegments: 10\n            })),\n\n            material: new PhongMaterial(this, {\n                diffuse: [0, 0, 0],\n                ambient: [0, 0, 0],\n                specular: [0, 0, 0],\n                diffuseMap: this._texture,\n                emissiveMap: this._texture,\n                backfaces: true\n            }),\n            clippable: cfg.clippable\n        });\n\n        this._grid = new Mesh(this, {\n            geometry: new ReadableGeometry(this, buildGridGeometry({\n                size: 1,\n                divisions: 10\n            })),\n            material: new PhongMaterial(this, {\n                diffuse: [0.0, 0.0, 0.0],\n                ambient: [0.0, 0.0, 0.0],\n                emissive: [0.2, 0.8, 0.2]\n            }),\n            position: [0, 0.001, 0.0],\n            clippable: cfg.clippable\n        });\n\n        this._node = new Node$1(this, {\n            rotation: [0, 0, 0],\n            position: [0, 0, 0],\n            scale: [1, 1, 1],\n            clippable: false,\n            children: [\n                this._plane,\n                this._grid\n            ]\n        });\n\n        this._gridVisible = false;\n\n        this.visible = true;\n        this.gridVisible = cfg.gridVisible;\n        this.position = cfg.position;\n        this.rotation = cfg.rotation;\n        this.dir = cfg.dir;\n        this.size = cfg.size;\n        this.collidable = cfg.collidable;\n        this.clippable = cfg.clippable;\n        this.pickable = cfg.pickable;\n        this.opacity = cfg.opacity;\n\n        if (cfg.image) {\n            this.image = cfg.image;\n        } else {\n            this.src = cfg.src;\n        }\n    }\n\n    /**\n     * Sets if this ````ImagePlane```` is visible or not.\n     *\n     * Default value is ````true````.\n     *\n     * @param {Boolean} visible Set ````true```` to make this ````ImagePlane```` visible.\n     */\n    set visible(visible) {\n        this._plane.visible = visible;\n        this._grid.visible = (this._gridVisible && visible);\n    }\n\n    /**\n     * Gets if this ````ImagePlane```` is visible or not.\n     *\n     * Default value is ````true````.\n     *\n     * @returns {Boolean} Returns ````true```` if visible.\n     */\n    get visible() {\n        return this._plane.visible;\n    }\n\n    /**\n     * Sets if this ````ImagePlane````'s grid  is visible or not.\n     *\n     * Default value is ````false````.\n     *\n     * Grid is only visible when ````ImagePlane```` is also visible.\n     *\n     * @param {Boolean} visible Set ````true```` to make this ````ImagePlane````'s grid visible.\n     */\n    set gridVisible(visible) {\n        visible = (visible !== false);\n        this._gridVisible = visible;\n        this._grid.visible = (this._gridVisible && this.visible);\n    }\n\n    /**\n     * Gets if this ````ImagePlane````'s grid is visible or not.\n     *\n     * Default value is ````false````.\n     *\n     * @returns {Boolean} Returns ````true```` if visible.\n     */\n    get gridVisible() {\n        return this._gridVisible;\n    }\n\n    /**\n     * Sets an ````HTMLImageElement```` to source the image from.\n     *\n     * Sets {@link Texture#src} null.\n     *\n     * @type {HTMLImageElement}\n     */\n    set image(image) {\n        this._image = image;\n        if (this._image) {\n            this._imageSize[0] = image.width;\n            this._imageSize[1] = image.height;\n            this._updatePlaneSizeFromImage();\n            this._src = null;\n            this._texture.image = this._image;\n        }\n    }\n\n    /**\n     * Gets the ````HTMLImageElement```` the ````ImagePlane````'s image is sourced from, if set.\n     *\n     * Returns null if not set.\n     *\n     * @type {HTMLImageElement}\n     */\n    get image() {\n        return this._image;\n    }\n\n    /**\n     * Sets an image file path that the ````ImagePlane````'s image is sourced from.\n     *\n     * Accepted file types are PNG and JPEG.\n     *\n     * Sets {@link Texture#image} null.\n     *\n     * @type {String}\n     */\n    set src(src) {\n        this._src = src;\n        if (this._src) {\n            this._image = null;\n            const image = new Image();\n            image.onload = () => {\n                this._texture.image = image;\n                this._imageSize[0] = image.width;\n                this._imageSize[1] = image.height;\n                this._updatePlaneSizeFromImage();\n            };\n            image.src = this._src;\n        }\n    }\n\n    /**\n     * Gets the image file path that the ````ImagePlane````'s image is sourced from, if set.\n     *\n     * Returns null if not set.\n     *\n     * @type {String}\n     */\n    get src() {\n        return this._src;\n    }\n\n    /**\n     * Sets the World-space position of this ````ImagePlane````.\n     *\n     * Default value is ````[0, 0, 0]````.\n     *\n     * @param {Number[]} value New position.\n     */\n    set position(value) {\n        this._pos.set(value || [0, 0, 0]);\n        worldToRTCPos(this._pos, this._origin, this._rtcPos);\n        this._node.origin = this._origin;\n        this._node.position = this._rtcPos;\n    }\n\n    /**\n     * Gets the World-space position of this ````ImagePlane````.\n     *\n     * Default value is ````[0, 0, 0]````.\n     *\n     * @returns {Number[]} Current position.\n     */\n    get position() {\n        return this._pos;\n    }\n\n    /**\n     * Sets the direction of this ````ImagePlane```` using Euler angles.\n     *\n     * Default value is ````[0, 0, 0]````.\n     *\n     * @param {Number[]} value Euler angles for ````X````, ````Y```` and ````Z```` axis rotations.\n     */\n    set rotation(value) {\n        this._node.rotation = value;\n    }\n\n    /**\n     * Gets the direction of this ````ImagePlane```` as Euler angles.\n     *\n     * @returns {Number[]} Euler angles for ````X````, ````Y```` and ````Z```` axis rotations.\n     */\n    get rotation() {\n        return this._node.rotation;\n    }\n\n    /**\n     * Sets the World-space size of the longest edge of the ````ImagePlane````.\n     *\n     * Note that ````ImagePlane```` sets its aspect ratio to match its image. If we set a value of ````1000````, and\n     * the image has size ````400x300````, then the ````ImagePlane```` will then have size ````1000 x 750````.\n     *\n     * Default value is ````1.0````.\n     *\n     * @param {Number} size New World-space size of the ````ImagePlane````.\n     */\n    set size(size) {\n        this._size = (size === undefined || size === null) ? 1.0 : size;\n        if (this._image) {\n            this._updatePlaneSizeFromImage();\n        }\n    }\n\n    /**\n     * Gets the World-space size of the longest edge of the ````ImagePlane````.\n     *\n     * Returns {Number} World-space size of the ````ImagePlane````.\n     */\n    get size() {\n        return this._size;\n    }\n\n    /**\n     * Sets the direction of this ````ImagePlane```` as a direction vector.\n     *\n     * Default value is ````[0, 0, -1]````.\n     *\n     * @param {Number[]} dir New direction vector.\n     */\n    set dir(dir) {\n\n        this._dir.set(dir || [0, 0, -1]);\n\n        if (dir) {\n\n            const origin = this.scene.center;\n            const negDir = [-this._dir[0], -this._dir[1], -this._dir[2]];\n\n            math.subVec3(origin, this.position, tempVec3$7);\n\n            const dist = -math.dotVec3(negDir, tempVec3$7);\n\n            math.normalizeVec3(negDir);\n            math.mulVec3Scalar(negDir, dist, tempVec3b$a);\n            math.vec3PairToQuaternion(zeroVec$1, dir, tempQuat);\n\n            this._node.quaternion = tempQuat;\n        }\n    }\n\n    /**\n     * Gets the direction of this ````ImagePlane```` as a direction vector.\n     *\n     * @returns {Number[]} value Current direction.\n     */\n    get dir() {\n        return this._dir;\n    }\n\n    /**\n     * Sets if this ````ImagePlane```` is included in boundary calculations.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set collidable(value) {\n        this._node.collidable = (value !== false);\n    }\n\n    /**\n     * Gets if this ````ImagePlane```` is included in boundary calculations.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get collidable() {\n        return this._node.collidable;\n    }\n\n    /**\n     * Sets if this ````ImagePlane```` is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set clippable(value) {\n        this._node.clippable = (value !== false);\n    }\n\n    /**\n     * Gets if this ````ImagePlane````  is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get clippable() {\n        return this._node.clippable;\n    }\n\n    /**\n     * Sets if this ````ImagePlane```` is pickable.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set pickable(value) {\n        this._node.pickable = (value !== false);\n    }\n\n    /**\n     * Gets if this ````ImagePlane````  is pickable.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get pickable() {\n        return this._node.pickable;\n    }\n\n    /**\n     * Sets the opacity factor for this ````ImagePlane````.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    set opacity(opacity) {\n        this._node.opacity = opacity;\n    }\n\n    /**\n     * Gets this ````ImagePlane````'s opacity factor.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    get opacity() {\n        return this._node.opacity;\n    }\n\n    /**\n     * @destroy\n     */\n    destroy() {\n        super.destroy();\n    }\n\n    _updatePlaneSizeFromImage() {\n        const size = this._size;\n        const width = this._imageSize[0];\n        const height = this._imageSize[1];\n        if (width > height) {\n            const aspect = height / width;\n            this._node.scale = [size, 1.0, size * aspect];\n        } else {\n            const aspect = width / height;\n            this._node.scale = [size * aspect, 1.0, size];\n        }\n    }\n}\n\n/**\n * @desc Configures the normal rendered appearance of {@link Mesh}es using the non-realistic but GPU-efficient <a href=\"https://en.wikipedia.org/wiki/Lambertian_reflectance\">Lambertian</a> flat shading model for calculating reflectance.\n *\n * * Useful for efficiently rendering non-realistic objects for high-detail CAD.\n * * Use  {@link PhongMaterial} when you need specular highlights.\n * * Use the physically-based {@link MetallicMaterial} or {@link SpecularMaterial} when you need more realism.\n * * For LambertMaterial, the illumination calculation is performed at each triangle vertex, and the resulting color is interpolated across the face of the triangle. For {@link PhongMaterial}, {@link MetallicMaterial} and\n * {@link SpecularMaterial}, vertex normals are interpolated across the surface of the triangle, and the illumination calculation is performed at each texel.\n *\n * ## Usage\n *\n * [[Run this example](/examples/index.html#materials_LambertMaterial)]\n *\n * In the example below we'll create a {@link Mesh} with a shape defined by a {@link buildTorusGeometry} and normal rendering appearance configured with a LambertMaterial.\n *\n * ```` javascript\n * import {Viewer, Mesh, buildTorusGeometry, ReadableGeometry, LambertMaterial} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry({\n *          center: [0, 0, 0],\n *          radius: 1.5,\n *          tube: 0.5,\n *          radialSegments: 12,\n *          tubeSegments: 8,\n *          arc: Math.PI * 2.0\n *      }),\n *      material: new LambertMaterial(viewer.scene, {\n *          ambient: [0.3, 0.3, 0.3],\n *          color: [0.5, 0.5, 0.0],\n *          alpha: 1.0, // Default\n *          lineWidth: 1,\n *          pointSize: 1,\n *          backfaces: false,\n *          frontFace: \"ccw\"\n *      })\n *  });\n * ````\n *\n * ## LambertMaterial Properties\n *\n * The following table summarizes LambertMaterial properties:\n *\n *  | Property | Type | Range | Default Value | Space | Description |\n *  |:--------:|:----:|:-----:|:-------------:|:-----:|:-----------:|\n *  | {@link LambertMaterial#ambient} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the ambient light reflected by the material. |\n *  | {@link LambertMaterial#color} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the diffuse light reflected by the material. |\n *  | {@link LambertMaterial#emissive} | Array | [0, 1] for all components | [0,0,0] | linear | The RGB components of the light emitted by the material. |\n *  | {@link LambertMaterial#alpha} | Number | [0, 1] | 1 | linear | The transparency of the material surface (0 fully transparent, 1 fully opaque). |\n *  | {@link LambertMaterial#lineWidth} | Number | [0..100] | 1 |  | Line width in pixels. |\n *  | {@link LambertMaterial#pointSize} | Number | [0..100] | 1 |  | Point size in pixels. |\n *  | {@link LambertMaterial#backfaces} | Boolean |  | false |  | Whether to render {@link Geometry} backfaces. |\n *  | {@link LambertMaterial#frontface} | String | \"ccw\", \"cw\" | \"ccw\" |  | The winding order for {@link Geometry} frontfaces - \"cw\" for clockwise, or \"ccw\" for counter-clockwise. |\n *\n */\nclass LambertMaterial extends Material {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"LambertMaterial\";\n    }\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] The LambertMaterial configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {String:Object} [cfg.meta=null]  Metadata to attach to this LambertMaterial.\n     * @param {Number[]} [cfg.ambient=[1.0, 1.0, 1.0 ]] LambertMaterial ambient color.\n     * @param {Number[]} [cfg.color=[ 1.0, 1.0, 1.0 ]] LambertMaterial diffuse color.\n     * @param {Number[]} [cfg.emissive=[ 0.0, 0.0, 0.0 ]] LambertMaterial emissive color.\n     * @param {Number} [cfg.alpha=1]Scalar in range 0-1 that controls alpha, where 0 is completely transparent and 1 is completely opaque.\n     * @param {Number} [cfg.reflectivity=1]Scalar in range 0-1 that controls how much {@link ReflectionMap} is reflected.\n     * @param {Number} [cfg.lineWidth=1] Scalar that controls the width of {@link Geometry} lines.\n     * @param {Number} [cfg.pointSize=1] Scalar that controls the size of points for {@link Geometry} with {@link Geometry#primitive} set to \"points\".\n     * @param {Boolean} [cfg.backfaces=false] Whether to render {@link Geometry} backfaces.\n     * @param {Boolean} [cfg.frontface=\"ccw\"] The winding order for {@link Geometry} front faces - \"cw\" for clockwise, or \"ccw\" for counter-clockwise.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            type: \"LambertMaterial\",\n            ambient: math.vec3([1.0, 1.0, 1.0]),\n            color: math.vec3([1.0, 1.0, 1.0]),\n            emissive: math.vec3([0.0, 0.0, 0.0]),\n            alpha: null,\n            alphaMode: 0, // 2 (\"blend\") when transparent, so renderer knows when to add to transparency bin\n            lineWidth: null,\n            pointSize: null,\n            backfaces: null,\n            frontface: null, // Boolean for speed; true == \"ccw\", false == \"cw\"\n            hash: \"/lam;\"\n        });\n\n        this.ambient = cfg.ambient;\n        this.color = cfg.color;\n        this.emissive = cfg.emissive;\n        this.alpha = cfg.alpha;\n        this.lineWidth = cfg.lineWidth;\n        this.pointSize = cfg.pointSize;\n        this.backfaces = cfg.backfaces;\n        this.frontface = cfg.frontface;\n    }\n\n    /**\n     * Sets the LambertMaterial's ambient color.\n     *\n     * Default value is ````[0.3, 0.3, 0.3]````.\n     *\n     * @type {Number[]}\n     */\n    set ambient(value) {\n        let ambient = this._state.ambient;\n        if (!ambient) {\n            ambient = this._state.ambient = new Float32Array(3);\n        } else if (value && ambient[0] === value[0] && ambient[1] === value[1] && ambient[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            ambient[0] = value[0];\n            ambient[1] = value[1];\n            ambient[2] = value[2];\n        } else {\n            ambient[0] = .2;\n            ambient[1] = .2;\n            ambient[2] = .2;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the LambertMaterial's ambient color.\n     *\n     * Default value is ````[0.3, 0.3, 0.3]````.\n     *\n     * @type {Number[]}\n     */\n    get ambient() {\n        return this._state.ambient;\n    }\n\n    /**\n     * Sets the LambertMaterial's diffuse color.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @type {Number[]}\n     */\n    set color(value) {\n        let color = this._state.color;\n        if (!color) {\n            color = this._state.color = new Float32Array(3);\n        } else if (value && color[0] === value[0] && color[1] === value[1] && color[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            color[0] = value[0];\n            color[1] = value[1];\n            color[2] = value[2];\n        } else {\n            color[0] = 1;\n            color[1] = 1;\n            color[2] = 1;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the LambertMaterial's diffuse color.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @type {Number[]}\n     */\n    get color() {\n        return this._state.color;\n    }\n\n    /**\n     * Sets the LambertMaterial's emissive color.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @type {Number[]}\n     */\n    set emissive(value) {\n        let emissive = this._state.emissive;\n        if (!emissive) {\n            emissive = this._state.emissive = new Float32Array(3);\n        } else if (value && emissive[0] === value[0] && emissive[1] === value[1] && emissive[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            emissive[0] = value[0];\n            emissive[1] = value[1];\n            emissive[2] = value[2];\n        } else {\n            emissive[0] = 0;\n            emissive[1] = 0;\n            emissive[2] = 0;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the LambertMaterial's emissive color.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @type {Number[]}\n     */\n    get emissive() {\n        return this._state.emissive;\n    }\n\n    /**\n     * Sets factor in the range ````[0..1]```` indicating how transparent the LambertMaterial is.\n     *\n     * A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     *\n     * Default value is ````1.0````\n     *\n     * @type {Number}\n     */\n    set alpha(value) {\n        value = (value !== undefined && value !== null) ? value : 1.0;\n        if (this._state.alpha === value) {\n            return;\n        }\n        this._state.alpha = value;\n        this._state.alphaMode = value < 1.0 ? 2 /* blend */ : 0;\n        /* opaque */\n        this.glRedraw();\n    }\n\n    /**\n     * Gets factor in the range ````[0..1]```` indicating how transparent the LambertMaterial is.\n     *\n     * A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     *\n     * Default value is ````1.0````\n     *\n     * @type {Number}\n     */\n    get alpha() {\n        return this._state.alpha;\n    }\n\n    /**\n     * Sets the LambertMaterial's line width.\n     *\n     * This is not supported by WebGL implementations based on DirectX [2019].\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set lineWidth(value) {\n        this._state.lineWidth = value || 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the LambertMaterial's line width.\n     *\n     * This is not supported by WebGL implementations based on DirectX [2019].\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    get lineWidth() {\n        return this._state.lineWidth;\n    }\n\n    /**\n     * Sets the LambertMaterial's point size.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set pointSize(value) {\n        this._state.pointSize = value || 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the LambertMaterial's point size.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    get pointSize() {\n        return this._state.pointSize;\n    }\n\n    /**\n     * Sets whether backfaces are visible on attached {@link Mesh}es.\n     *\n     * @type {Boolean}\n     */\n    set backfaces(value) {\n        value = !!value;\n        if (this._state.backfaces === value) {\n            return;\n        }\n        this._state.backfaces = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether backfaces are visible on attached {@link Mesh}es.\n     *\n     * @type {Boolean}\n     */\n    get backfaces() {\n        return this._state.backfaces;\n    }\n\n    /**\n     * Sets the winding direction of front faces of {@link Geometry} of attached {@link Mesh}es.\n     *\n     * Default value is ````\"ccw\"````.\n     *\n     * @type {String}\n     */\n    set frontface(value) {\n        value = value !== \"cw\";\n        if (this._state.frontface === value) {\n            return;\n        }\n        this._state.frontface = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the winding direction of front faces of {@link Geometry} of attached {@link Mesh}es.\n     *\n     * Default value is ````\"ccw\"````.\n     *\n     * @type {String}\n     */\n    get frontface() {\n        return this._state.frontface ? \"ccw\" : \"cw\";\n    }\n\n    _getState() {\n        return this._state;\n    }\n\n    /**\n     * Destroys this LambertMaterial.\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\nconst modes = {\"opaque\": 0, \"mask\": 1, \"blend\": 2};\nconst modeNames = [\"opaque\", \"mask\", \"blend\"];\n\n/**\n * @desc Configures the normal rendered appearance of {@link Mesh}es using the physically-accurate *metallic-roughness* shading model.\n *\n * * Useful for conductive materials, such as metal, but also appropriate for insulators.\n * * {@link SpecularMaterial} is best for insulators, such as wood, ceramics and plastic.\n * * {@link PhongMaterial} is appropriate for non-realistic objects.\n * * {@link LambertMaterial} is appropriate for high-detail models that need to render as efficiently as possible.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with {@link MetallicMaterial} and {@link ReadableGeometry} loaded from OBJ.\n *\n * Note that in this example we're providing separate {@link Texture} for the {@link MetallicMaterial#metallic} and {@link MetallicMaterial#roughness}\n * channels, which allows us a little creative flexibility. Then, in the next example further down, we'll combine those channels\n * within the same {@link Texture} for efficiency.\n *\n * [[Run this example](/examples/index.html#materials_MetallicMaterial)]\n *\n * ````javascript\n * import {Viewer, Mesh, loadOBJGeometry, ReadableGeometry, MetallicMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [0.57, 1.37, 1.14];\n * viewer.scene.camera.look = [0.04, 0.58, 0.00];\n * viewer.scene.camera.up = [-0.22, 0.84, -0.48];\n *\n * loadOBJGeometry(viewer.scene, {\n *      src: \"models/obj/fireHydrant/FireHydrantMesh.obj\"\n * })\n * .then(function (geometry) {\n *\n *      // Success\n *\n *      new Mesh(viewer.scene, {\n *\n *          geometry: new ReadableGeometry(viewer.scene, geometry),\n *\n *          material: new MetallicMaterial(viewer.scene, {\n *\n *              baseColor: [1, 1, 1],\n *              metallic: 1.0,\n *              roughness: 1.0,\n *\n *              baseColorMap: new Texture(viewer.scene, {\n *                  src: \"models/obj/fireHydrant/fire_hydrant_Base_Color.png\",\n *                  encoding: \"sRGB\"\n *              }),\n *              normalMap: new Texture(viewer.scene, {\n *                  src: \"models/obj/fireHydrant/fire_hydrant_Normal_OpenGL.png\"\n *              }),\n *              roughnessMap: new Texture(viewer.scene, {\n *                  src: \"models/obj/fireHydrant/fire_hydrant_Roughness.png\"\n *              }),\n *              metallicMap: new Texture(viewer.scene, {\n *                  src: \"models/obj/fireHydrant/fire_hydrant_Metallic.png\"\n *              }),\n *              occlusionMap: new Texture(viewer.scene, {\n *                  src: \"models/obj/fireHydrant/fire_hydrant_Mixed_AO.png\"\n *              }),\n *\n *              specularF0: 0.7\n *          })\n *      });\n * }, function () {\n *          // Error\n *      });\n * ````\n *\n * ## Background Theory\n *\n * For an introduction to physically-based rendering (PBR) concepts, try these articles:\n *\n * * Joe Wilson's [Basic Theory of Physically-Based Rendering](https://www.marmoset.co/posts/basic-theory-of-physically-based-rendering/)\n * * Jeff Russel's [Physically-based Rendering, and you can too!](https://www.marmoset.co/posts/physically-based-rendering-and-you-can-too/)\n * * Sebastien Legarde's [Adapting a physically-based shading model](http://seblagarde.wordpress.com/tag/physically-based-rendering/)\n *\n * ## MetallicMaterial Properties\n *\n * The following table summarizes MetallicMaterial properties:\n *\n * | Property | Type | Range | Default Value | Space | Description |\n * |:--------:|:----:|:-----:|:-------------:|:-----:|:-----------:|\n * | {@link MetallicMaterial#baseColor} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the base color of the material. |\n * | {@link MetallicMaterial#metallic} | Number | [0, 1] | 1 | linear | The metallic-ness the material (1 for metals, 0 for non-metals). |\n * | {@link MetallicMaterial#roughness} | Number | [0, 1] | 1 | linear | The roughness of the material surface. |\n * | {@link MetallicMaterial#specularF0} | Number | [0, 1] | 1 | linear | The specular Fresnel of the material surface. |\n * | {@link MetallicMaterial#emissive} | Array | [0, 1] for all components | [0,0,0] | linear | The RGB components of the emissive color of the material. |\n * | {@link MetallicMaterial#alpha} | Number | [0, 1] | 1 | linear | The transparency of the material surface (0 fully transparent, 1 fully opaque). |\n * | {@link MetallicMaterial#baseColorMap} | {@link Texture} |  | null | sRGB | Texture RGB components multiplying by {@link MetallicMaterial#baseColor}. If the fourth component (A) is present, it multiplies by {@link MetallicMaterial#alpha}. |\n * | {@link MetallicMaterial#metallicMap} | {@link Texture} |  | null | linear | Texture with first component multiplying by {@link MetallicMaterial#metallic}. |\n * | {@link MetallicMaterial#roughnessMap} | {@link Texture} |  | null | linear | Texture with first component multiplying by {@link MetallicMaterial#roughness}. |\n * | {@link MetallicMaterial#metallicRoughnessMap} | {@link Texture} |  | null | linear | Texture with first component multiplying by {@link MetallicMaterial#metallic} and second component multiplying by {@link MetallicMaterial#roughness}. |\n * | {@link MetallicMaterial#emissiveMap} | {@link Texture} |  | null | linear | Texture with RGB components multiplying by {@link MetallicMaterial#emissive}. |\n * | {@link MetallicMaterial#alphaMap} | {@link Texture} |  | null | linear | Texture with first component multiplying by {@link MetallicMaterial#alpha}. |\n * | {@link MetallicMaterial#occlusionMap} | {@link Texture} |  | null | linear | Ambient occlusion texture multiplying by surface's reflected diffuse and specular light. |\n * | {@link MetallicMaterial#normalMap} | {@link Texture} |  | null | linear | Tangent-space normal map. |\n * | {@link MetallicMaterial#alphaMode} | String | \"opaque\", \"blend\", \"mask\" | \"blend\" |  | Alpha blend mode. |\n * | {@link MetallicMaterial#alphaCutoff} | Number | [0..1] | 0.5 |  | Alpha cutoff value. |\n * | {@link MetallicMaterial#backfaces} | Boolean |  | false |  | Whether to render {@link ReadableGeometry} backfaces. |\n * | {@link MetallicMaterial#frontface} | String | \"ccw\", \"cw\" | \"ccw\" |  | The winding order for {@link ReadableGeometry} frontfaces - \"cw\" for clockwise, or \"ccw\" for counter-clockwise. |\n *\n *\n * ## Combining Channels Within the Same Textures\n *\n * In the previous example we provided separate {@link Texture} for the {@link MetallicMaterial#metallic} and\n * {@link MetallicMaterial#roughness} channels, but we can combine those channels into the same {@link Texture} to\n * reduce download time, memory footprint and rendering time (and also for glTF compatibility).\n *\n * Here's the {@link Mesh} again, with our MetallicMaterial with those channels combined in the {@link MetallicMaterial#metallicRoughnessMap}\n * {@link Texture}, where the *R* component multiplies by {@link MetallicMaterial#metallic} and *G* multiplies\n * by {@link MetallicMaterial#roughness}.\n *\n * ````javascript\n * new Mesh(viewer.scene, {\n *\n *     geometry: geometry,\n *\n *     material: new MetallicMaterial(viewer.scene, {\n *\n *         baseColor: [1, 1, 1],\n *         metallic: 1.0,\n *         roughness: 1.0,\n *\n *         baseColorMap: new Texture(viewer.scene, {\n *             src: \"models/obj/fireHydrant/fire_hydrant_Base_Color.png\",\n *             encoding: \"sRGB\"\n *         }),\n *         normalMap: new Texture(viewer.scene, {\n *             src: \"models/obj/fireHydrant/fire_hydrant_Normal_OpenGL.png\"\n *         }),\n *         metallicRoughnessMap: new Texture(viewer.scene, {\n *             src: \"models/obj/fireHydrant/fire_hydrant_MetallicRoughness.png\"\n *         }),\n *         metallicRoughnessMap : new Texture(viewer.scene, {                  // <<----------- Added\n *             src: \"models/obj/fireHydrant/fire_hydrant_MetallicRoughness.png\"  // R component multiplies by metallic\n *         }),                                                                   // G component multiplies by roughness\n *         occlusionMap: new Texture(viewer.scene, {\n *             src: \"models/obj/fireHydrant/fire_hydrant_Mixed_AO.png\"\n *         }),\n *\n *         specularF0: 0.7\n *  })\n * ````\n *\n * Although not shown in this example, we can also texture {@link MetallicMaterial#alpha} with the *A* component of\n * {@link MetallicMaterial#baseColorMap}'s {@link Texture}, if required.\n *\n * ## Alpha Blending\n *\n * Let's make our {@link Mesh} transparent.\n *\n * We'll update the {@link MetallicMaterial#alpha} and {@link MetallicMaterial#alphaMode}, causing it to blend 50%\n * with the background:\n *\n * ````javascript\n * hydrant.material.alpha = 0.5;\n * hydrant.material.alphaMode = \"blend\";\n * ````\n *\n * ## Alpha Masking\n *\n * Let's apply an alpha mask to our {@link Mesh}.\n *\n * We'll configure an {@link MetallicMaterial#alphaMap} to multiply by {@link MetallicMaterial#alpha},\n * with {@link MetallicMaterial#alphaMode} and {@link MetallicMaterial#alphaCutoff} to treat it as an alpha mask:\n *\n * ````javascript\n * new Mesh(viewer.scene, {\n *\n *     geometry: geometry,\n *\n *     material: new MetallicMaterial(viewer.scene, {\n *\n *         baseColor: [1, 1, 1],\n *         metallic: 1.0,\n *         roughness: 1.0,\n *         alpha: 1.0,\n *         alphaMode : \"mask\",  // <<---------------- Added\n *         alphaCutoff : 0.2,   // <<---------------- Added\n *\n *         alphaMap : new Texture(viewer.scene{ // <<---------------- Added\n *              src: \"textures/alphaMap.jpg\"\n *         }),\n *         baseColorMap: new Texture(viewer.scene, {\n *             src: \"models/obj/fireHydrant/fire_hydrant_Base_Color.png\",\n *             encoding: \"sRGB\"\n *         }),\n *         normalMap: new Texture(viewer.scene, {\n *             src: \"models/obj/fireHydrant/fire_hydrant_Normal_OpenGL.png\"\n *         }),\n *         metallicRoughnessMap: new Texture(viewer.scene, {\n *             src: \"models/obj/fireHydrant/fire_hydrant_MetallicRoughness.png\"\n *         }),\n *         metallicRoughnessMap : new Texture(viewer.scene, {                  // <<----------- Added\n *             src: \"models/obj/fireHydrant/fire_hydrant_MetallicRoughness.png\"  // R component multiplies by metallic\n *         }),                                                                   // G component multiplies by roughness\n *         occlusionMap: new Texture(viewer.scene, {\n *             src: \"models/obj/fireHydrant/fire_hydrant_Mixed_AO.png\"\n *         }),\n *\n *         specularF0: 0.7\n *  })\n * ````\n */\nclass MetallicMaterial extends Material {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"MetallicMaterial\";\n    }\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this MetallicMaterial as well.\n     * @param {*} [cfg] The MetallicMaterial configuration.\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number[]} [cfg.baseColor=[1,1,1]] RGB diffuse color of this MetallicMaterial. Multiplies by the RGB components of {@link MetallicMaterial#baseColorMap}.\n     * @param {Number} [cfg.metallic=1.0] Factor in the range ````[0..1]```` indicating how metallic this MetallicMaterial is.  ````1```` is metal, ````0```` is non-metal. Multiplies by the *R* component of {@link MetallicMaterial#metallicMap} and the *A* component of {@link MetallicMaterial#metallicRoughnessMap}.\n     * @param {Number} [cfg.roughness=1.0] Factor in the range ````[0..1]```` indicating the roughness of this MetallicMaterial.  ````0```` is fully smooth, ````1```` is fully rough. Multiplies by the *R* component of {@link MetallicMaterial#roughnessMap}.\n     * @param {Number} [cfg.specularF0=0.0] Factor in the range ````[0..1]```` indicating specular Fresnel.\n     * @param {Number[]} [cfg.emissive=[0,0,0]]  RGB emissive color of this MetallicMaterial. Multiplies by the RGB components of {@link MetallicMaterial#emissiveMap}.\n     * @param {Number} [cfg.alpha=1.0] Factor in the range ````[0..1]```` indicating the alpha of this MetallicMaterial.  Multiplies by the *R* component of {@link MetallicMaterial#alphaMap} and the *A* component,  if present, of {@link MetallicMaterial#baseColorMap}. The value of  {@link MetallicMaterial#alphaMode} indicates how alpha is interpreted when rendering.\n     * @param {Texture} [cfg.baseColorMap=undefined] RGBA {@link Texture} containing the diffuse color of this MetallicMaterial, with optional *A* component for alpha. The RGB components multiply by the {@link MetallicMaterial#baseColor} property, while the *A* component, if present, multiplies by the {@link MetallicMaterial#alpha} property.\n     * @param {Texture} [cfg.alphaMap=undefined] RGB {@link Texture} containing this MetallicMaterial's alpha in its *R* component. The *R* component multiplies by the {@link MetallicMaterial#alpha} property. Must be within the same {@link Scene} as this MetallicMaterial.\n     * @param {Texture} [cfg.metallicMap=undefined] RGB {@link Texture} containing this MetallicMaterial's metallic factor in its *R* component. The *R* component multiplies by the {@link MetallicMaterial#metallic} property. Must be within the same {@link Scene} as this MetallicMaterial.\n     * @param {Texture} [cfg.roughnessMap=undefined] RGB {@link Texture} containing this MetallicMaterial's roughness factor in its *R* component. The *R* component multiplies by the  {@link MetallicMaterial#roughness} property. Must be within the same {@link Scene} as this MetallicMaterial.\n     * @param {Texture} [cfg.metallicRoughnessMap=undefined] RGB {@link Texture} containing this MetallicMaterial's metalness in its *R* component and roughness in its *G* component. Its *R* component multiplies by the {@link MetallicMaterial#metallic} property, while its *G* component multiplies by the {@link MetallicMaterial#roughness} property. Must be within the same {@link Scene} as this MetallicMaterial.\n     * @param {Texture} [cfg.emissiveMap=undefined] RGB {@link Texture} containing the emissive color of this MetallicMaterial. Multiplies by the {@link MetallicMaterial#emissive} property. Must be within the same {@link Scene} as this MetallicMaterial.\n     * @param {Texture} [cfg.occlusionMap=undefined] RGB ambient occlusion {@link Texture}. Within shaders, multiplies by the specular and diffuse light reflected by surfaces. Must be within the same {@link Scene} as this MetallicMaterial.\n     * @param {Texture} [cfg.normalMap=undefined] RGB tangent-space normal {@link Texture}. Must be within the same {@link Scene} as this MetallicMaterial.\n     * @param {String} [cfg.alphaMode=\"opaque\"] The alpha blend mode, which specifies how alpha is to be interpreted. Accepted values are \"opaque\", \"blend\" and \"mask\". See the {@link MetallicMaterial#alphaMode} property for more info.\n     * @param {Number} [cfg.alphaCutoff=0.5] The alpha cutoff value. See the {@link MetallicMaterial#alphaCutoff} property for more info.\n     * @param {Boolean} [cfg.backfaces=false] Whether to render {@link ReadableGeometry} backfaces.\n     * @param {Boolean} [cfg.frontface=\"ccw\"] The winding order for {@link ReadableGeometry} front faces - ````\"cw\"```` for clockwise, or ````\"ccw\"```` for counter-clockwise.\n     * @param {Number} [cfg.lineWidth=1] Scalar that controls the width of lines for {@link ReadableGeometry} with {@link ReadableGeometry#primitive} set to \"lines\".\n     * @param {Number} [cfg.pointSize=1] Scalar that controls the size of points for {@link ReadableGeometry} with {@link ReadableGeometry#primitive} set to \"points\".\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            type: \"MetallicMaterial\",\n            baseColor: math.vec4([1.0, 1.0, 1.0]),\n            emissive: math.vec4([0.0, 0.0, 0.0]),\n            metallic: null,\n            roughness: null,\n            specularF0: null,\n            alpha: null,\n            alphaMode: null, // \"opaque\"\n            alphaCutoff: null,\n            lineWidth: null,\n            pointSize: null,\n            backfaces: null,\n            frontface: null, // Boolean for speed; true == \"ccw\", false == \"cw\"\n            hash: null\n        });\n\n        this.baseColor = cfg.baseColor;\n        this.metallic = cfg.metallic;\n        this.roughness = cfg.roughness;\n        this.specularF0 = cfg.specularF0;\n        this.emissive = cfg.emissive;\n        this.alpha = cfg.alpha;\n\n        if (cfg.baseColorMap) {\n            this._baseColorMap = this._checkComponent(\"Texture\", cfg.baseColorMap);\n        }\n        if (cfg.metallicMap) {\n            this._metallicMap = this._checkComponent(\"Texture\", cfg.metallicMap);\n\n        }\n        if (cfg.roughnessMap) {\n            this._roughnessMap = this._checkComponent(\"Texture\", cfg.roughnessMap);\n        }\n        if (cfg.metallicRoughnessMap) {\n            this._metallicRoughnessMap = this._checkComponent(\"Texture\", cfg.metallicRoughnessMap);\n        }\n        if (cfg.emissiveMap) {\n            this._emissiveMap = this._checkComponent(\"Texture\", cfg.emissiveMap);\n        }\n        if (cfg.occlusionMap) {\n            this._occlusionMap = this._checkComponent(\"Texture\", cfg.occlusionMap);\n        }\n        if (cfg.alphaMap) {\n            this._alphaMap = this._checkComponent(\"Texture\", cfg.alphaMap);\n        }\n        if (cfg.normalMap) {\n            this._normalMap = this._checkComponent(\"Texture\", cfg.normalMap);\n        }\n\n        this.alphaMode = cfg.alphaMode;\n        this.alphaCutoff = cfg.alphaCutoff;\n        this.backfaces = cfg.backfaces;\n        this.frontface = cfg.frontface;\n        this.lineWidth = cfg.lineWidth;\n        this.pointSize = cfg.pointSize;\n\n        this._makeHash();\n    }\n\n    _makeHash() {\n        const state = this._state;\n        const hash = [\"/met\"];\n        if (this._baseColorMap) {\n            hash.push(\"/bm\");\n            if (this._baseColorMap._state.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n            hash.push(\"/\" + this._baseColorMap._state.encoding);\n        }\n        if (this._metallicMap) {\n            hash.push(\"/mm\");\n            if (this._metallicMap._state.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._roughnessMap) {\n            hash.push(\"/rm\");\n            if (this._roughnessMap._state.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._metallicRoughnessMap) {\n            hash.push(\"/mrm\");\n            if (this._metallicRoughnessMap._state.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._emissiveMap) {\n            hash.push(\"/em\");\n            if (this._emissiveMap._state.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._occlusionMap) {\n            hash.push(\"/ocm\");\n            if (this._occlusionMap._state.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._alphaMap) {\n            hash.push(\"/am\");\n            if (this._alphaMap._state.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._normalMap) {\n            hash.push(\"/nm\");\n            if (this._normalMap._state.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        hash.push(\";\");\n        state.hash = hash.join(\"\");\n    }\n\n\n    /**\n     * Sets the RGB diffuse color.\n     *\n     * Multiplies by the RGB components of {@link MetallicMaterial#baseColorMap}.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     * @type {Number[]}\n     */\n    set baseColor(value) {\n        let baseColor = this._state.baseColor;\n        if (!baseColor) {\n            baseColor = this._state.baseColor = new Float32Array(3);\n        } else if (value && baseColor[0] === value[0] && baseColor[1] === value[1] && baseColor[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            baseColor[0] = value[0];\n            baseColor[1] = value[1];\n            baseColor[2] = value[2];\n        } else {\n            baseColor[0] = 1;\n            baseColor[1] = 1;\n            baseColor[2] = 1;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the RGB diffuse color.\n     *\n     * Multiplies by the RGB components of {@link MetallicMaterial#baseColorMap}.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     * @type {Number[]}\n     */\n    get baseColor() {\n        return this._state.baseColor;\n    }\n\n\n    /**\n     * Gets the RGB {@link Texture} containing the diffuse color of this MetallicMaterial, with optional *A* component for alpha.\n     *\n     * The RGB components multiply by {@link MetallicMaterial#baseColor}, while the *A* component, if present, multiplies by {@link MetallicMaterial#alpha}.\n     *\n     * @type {Texture}\n     */\n    get baseColorMap() {\n        return this._baseColorMap;\n    }\n\n    /**\n     * Sets the metallic factor.\n     *\n     * This is in the range ````[0..1]```` and indicates how metallic this MetallicMaterial is.\n     *\n     * ````1```` is metal, ````0```` is non-metal.\n     *\n     * Multiplies by the *R* component of {@link MetallicMaterial#metallicMap} and the *A* component of {@link MetallicMaterial#metallicRoughnessMap}.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set metallic(value) {\n        value = (value !== undefined && value !== null) ? value : 1.0;\n        if (this._state.metallic === value) {\n            return;\n        }\n        this._state.metallic = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the metallic factor.\n     *\n     * @type {Number}\n     */\n    get metallic() {\n        return this._state.metallic;\n    }\n\n    /**\n     * Gets the RGB {@link Texture} containing this MetallicMaterial's metallic factor in its *R* component.\n     *\n     * The *R* component multiplies by {@link MetallicMaterial#metallic}.\n     *\n     * @type {Texture}\n     */\n    get metallicMap() {\n        return this._attached.metallicMap;\n    }\n\n    /**\n     *  Sets the roughness factor.\n     *\n     *  This factor is in the range ````[0..1]````, where ````0```` is fully smooth,````1```` is fully rough.\n     *\n     * Multiplies by the *R* component of {@link MetallicMaterial#roughnessMap}.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set roughness(value) {\n        value = (value !== undefined && value !== null) ? value : 1.0;\n        if (this._state.roughness === value) {\n            return;\n        }\n        this._state.roughness = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the roughness factor.\n     *\n     * @type {Number}\n     */\n    get roughness() {\n        return this._state.roughness;\n    }\n\n    /**\n     * Gets the RGB {@link Texture} containing this MetallicMaterial's roughness factor in its *R* component.\n     *\n     * The *R* component multiplies by {@link MetallicMaterial#roughness}.\n     *\n     * @type {Texture}\n     */\n    get roughnessMap() {\n        return this._attached.roughnessMap;\n    }\n\n    /**\n     * Gets the RGB {@link Texture} containing this MetallicMaterial's metalness in its *R* component and roughness in its *G* component.\n     *\n     * Its *B* component multiplies by the {@link MetallicMaterial#metallic} property, while its *G* component multiplies by the {@link MetallicMaterial#roughness} property.\n     *\n     * @type {Texture}\n     */\n    get metallicRoughnessMap() {\n        return this._attached.metallicRoughnessMap;\n    }\n\n    /**\n     * Sets the factor in the range [0..1] indicating specular Fresnel value.\n     *\n     * Default value is ````0.0````.\n     *\n     * @type {Number}\n     */\n    set specularF0(value) {\n        value = (value !== undefined && value !== null) ? value : 0.0;\n        if (this._state.specularF0 === value) {\n            return;\n        }\n        this._state.specularF0 = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the factor in the range [0..1] indicating specular Fresnel value.\n     *\n     * @type {Number}\n     */\n    get specularF0() {\n        return this._state.specularF0;\n    }\n\n    /**\n     * Sets the RGB emissive color.\n     *\n     * Multiplies by {@link MetallicMaterial#emissiveMap}.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @type {Number[]}\n     */\n    set emissive(value) {\n        let emissive = this._state.emissive;\n        if (!emissive) {\n            emissive = this._state.emissive = new Float32Array(3);\n        } else if (value && emissive[0] === value[0] && emissive[1] === value[1] && emissive[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            emissive[0] = value[0];\n            emissive[1] = value[1];\n            emissive[2] = value[2];\n        } else {\n            emissive[0] = 0;\n            emissive[1] = 0;\n            emissive[2] = 0;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the RGB emissive color.\n     *\n     * @type {Number[]}\n     */\n    get emissive() {\n        return this._state.emissive;\n    }\n\n    /**\n     * Gets the RGB emissive map.\n     *\n     * Multiplies by {@link MetallicMaterial#emissive}.\n     *\n     * @type {Texture}\n     */\n    get emissiveMap() {\n        return this._attached.emissiveMap;\n    }\n\n    /**\n     * Gets the RGB ambient occlusion map.\n     *\n     * Multiplies by the specular and diffuse light reflected by surfaces.\n     *\n     * @type {Texture}\n     */\n    get occlusionMap() {\n        return this._attached.occlusionMap;\n    }\n\n    /**\n     * Sets factor in the range ````[0..1]```` that indicates the alpha value.\n     *\n     * Multiplies by the *R* component of {@link MetallicMaterial#alphaMap} and the *A* component, if present, of {@link MetallicMaterial#baseColorMap}.\n     *\n     * The value of {@link MetallicMaterial#alphaMode} indicates how alpha is interpreted when rendering.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set alpha(value) {\n        value = (value !== undefined && value !== null) ? value : 1.0;\n        if (this._state.alpha === value) {\n            return;\n        }\n        this._state.alpha = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets factor in the range ````[0..1]```` that indicates the alpha value.\n     *\n     * @type {Number}\n     */\n    get alpha() {\n        return this._state.alpha;\n    }\n\n    /**\n     * Gets the RGB {@link Texture} containing this MetallicMaterial's alpha in its *R* component.\n     *\n     * The *R* component multiplies by the {@link MetallicMaterial#alpha} property.\n     *\n     * @type {Texture}\n     */\n    get alphaMap() {\n        return this._attached.alphaMap;\n    }\n\n    /**\n     * Gets the RGB tangent-space normal map {@link Texture}.\n     *\n     * @type {Texture}\n     */\n    get normalMap() {\n        return this._attached.normalMap;\n    }\n\n    /**\n     * Sets the alpha rendering mode.\n     *\n     * This specifies how alpha is interpreted. Alpha is the combined result of the {@link MetallicMaterial#alpha} and {@link MetallicMaterial#alphaMap} properties.\n     *\n     * Accepted values are:\n     *\n     * * \"opaque\" - The alpha value is ignored and the rendered output is fully opaque (default).\n     * * \"mask\" - The rendered output is either fully opaque or fully transparent depending on the alpha and {@link MetallicMaterial#alphaCutoff}.\n     * * \"blend\" - The alpha value is used to composite the source and destination areas. The rendered output is combined with the background using the normal painting operation (i.e. the Porter and Duff over operator).\n     *\n     * @type {String}\n     */\n    set alphaMode(alphaMode) {\n        alphaMode = alphaMode || \"opaque\";\n        let value = modes[alphaMode];\n        if (value === undefined) {\n            this.error(\"Unsupported value for 'alphaMode': \" + alphaMode + \" defaulting to 'opaque'\");\n            value = \"opaque\";\n        }\n        if (this._state.alphaMode === value) {\n            return;\n        }\n        this._state.alphaMode = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the alpha rendering mode.\n     *\n     * @type {String}\n     */\n    get alphaMode() {\n        return modeNames[this._state.alphaMode];\n    }\n\n    /**\n     * Sets the alpha cutoff value.\n     *\n     * Specifies the cutoff threshold when {@link MetallicMaterial#alphaMode} equals \"mask\". If the alpha is greater than or equal to this value then it is rendered as fully opaque, otherwise, it is rendered as fully transparent. A value greater than 1.0 will render the entire\n     * material as fully transparent. This value is ignored for other modes.\n     *\n     * Alpha is the combined result of the {@link MetallicMaterial#alpha} and {@link MetallicMaterial#alphaMap} properties.\n     *\n     * Default value is ````0.5````.\n     *\n     * @type {Number}\n     */\n    set alphaCutoff(alphaCutoff) {\n        if (alphaCutoff === null || alphaCutoff === undefined) {\n            alphaCutoff = 0.5;\n        }\n        if (this._state.alphaCutoff === alphaCutoff) {\n            return;\n        }\n        this._state.alphaCutoff = alphaCutoff;\n    }\n\n    /**\n     * Gets the alpha cutoff value.\n     *\n     * @type {Number}\n     */\n    get alphaCutoff() {\n        return this._state.alphaCutoff;\n    }\n\n    /**\n     * Sets whether backfaces are visible on attached {@link Mesh}es.\n     *\n     * The backfaces will belong to {@link ReadableGeometry} compoents that are also attached to the {@link Mesh}es.\n     *\n     * Default is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set backfaces(value) {\n        value = !!value;\n        if (this._state.backfaces === value) {\n            return;\n        }\n        this._state.backfaces = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether backfaces are visible on attached {@link Mesh}es.\n     *\n     * @type {Boolean}\n     */\n    get backfaces() {\n        return this._state.backfaces;\n    }\n\n    /**\n     * Sets the winding direction of front faces of {@link Geometry} of attached {@link Mesh}es.\n     *\n     * Default value is ````\"ccw\"````.\n     *\n     * @type {String}\n     */\n    set frontface(value) {\n        value = value !== \"cw\";\n        if (this._state.frontface === value) {\n            return;\n        }\n        this._state.frontface = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the winding direction of front faces of {@link Geometry} of attached {@link Mesh}es.\n*\n     * @type {String}\n     */\n    get frontface() {\n        return this._state.frontface ? \"ccw\" : \"cw\";\n    }\n\n    /**\n     * Sets the MetallicMaterial's line width.\n     *\n     * This is not supported by WebGL implementations based on DirectX [2019].\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set lineWidth(value) {\n        this._state.lineWidth = value || 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the MetallicMaterial's line width.\n     *\n     * @type {Number}\n     */\n    get lineWidth() {\n        return this._state.lineWidth;\n    }\n\n    /**\n     * Sets the MetallicMaterial's point size.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set pointSize(value) {\n        this._state.pointSize = value || 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the MetallicMaterial's point size.\n     *\n     * @type {Number}\n     */\n    get pointSize() {\n        return this._state.pointSize;\n    }\n\n    /**\n     * Destroys this MetallicMaterial.\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\nconst alphaModes = {\"opaque\": 0, \"mask\": 1, \"blend\": 2};\nconst alphaModeNames = [\"opaque\", \"mask\", \"blend\"];\n\n/**\n * @desc Configures the normal rendered appearance of {@link Mesh}es using the physically-accurate *specular-glossiness* shading model.\n *\n * * Useful for insulators, such as wood, ceramics and plastic.\n * * {@link MetallicMaterial} is best for conductive materials, such as metal.\n * * {@link PhongMaterial} is appropriate for non-realistic objects.\n * * {@link LambertMaterial} is appropriate for high-detail models that need to render as efficiently as possible.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with a {@link buildTorusGeometry} and a SpecularMaterial.\n *\n * Note that in this example we're providing separate {@link Texture} for the {@link SpecularMaterial#specular} and {@link SpecularMaterial#glossiness}\n * channels, which allows us a little creative flexibility. Then, in the next example further down, we'll combine those channels\n * within the same {@link Texture} for efficiency.\n *\n * ````javascript\n * import {Viewer, Mesh, buildTorusGeometry, SpecularMaterial, Texture} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({ canvasId: \"myCanvas\" });\n *\n * const myMesh = new Mesh(viewer.scene,{\n *\n *      geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry()),\n *\n *      material: new SpecularMaterial(viewer.scene,{\n *\n *          // Channels with default values, just to show them\n *\n *          diffuse: [1.0, 1.0, 1.0],\n *          specular: [1.0, 1.0, 1.0],\n *          glossiness: 1.0,\n *          emissive: [0.0, 0.0, 0.0]\n *          alpha: 1.0,\n *\n *          // Textures to multiply some of the channels\n *\n *          diffuseMap: new Texture(viewer.scene, { // RGB components multiply by diffuse\n *              src: \"textures/diffuse.jpg\"\n *          }),\n *          specularMap: new Texture(viewer.scene, { // RGB component multiplies by specular\n *              src: \"textures/specular.jpg\"\n *          }),\n *          glossinessMap: new Texture(viewer.scene, { // R component multiplies by glossiness\n *              src: \"textures/glossiness.jpg\"\n *          }),\n *          normalMap: new Texture(viewer.scene, {\n *              src: \"textures/normalMap.jpg\"\n *          })\n *      })\n * });\n * ````\n *\n * ## Combining Channels Within the Same Textures\n *\n *  In the previous example we provided separate {@link Texture} for the {@link SpecularMaterial#specular} and\n * {@link SpecularMaterial#glossiness} channels, but we can combine those channels into the same {@link Texture} to reduce\n * download time, memory footprint and rendering time (and also for glTF compatibility).\n *\n * Here's our SpecularMaterial again with those channels combined in the {@link SpecularMaterial#specularGlossinessMap}\n * {@link Texture}, where the *RGB* component multiplies by {@link SpecularMaterial#specular} and *A* multiplies by {@link SpecularMaterial#glossiness}.\n *\n * ````javascript\n * const myMesh = new Mesh(viewer.scene,{\n *\n *      geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry()),\n *\n *      material: new SpecularMaterial(viewer.scene,{\n *\n *          // Channels with default values, just to show them\n *\n *          diffuse: [1.0, 1.0, 1.0],\n *          specular: [1.0, 1.0, 1.0],\n *          glossiness: 1.0,\n *          emissive: [0.0, 0.0, 0.0]\n *          alpha: 1.0,\n *\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse.jpg\"\n *          }),\n *          specularGlossinessMap: new Texture(viewer.scene, { // RGB multiplies by specular, A by glossiness\n *              src: \"textures/specularGlossiness.jpg\"\n *          }),\n *          normalMap: new Texture(viewer.scene, {\n *              src: \"textures/normalMap.jpg\"\n *          })\n *      })\n * });\n * ````\n *\n * Although not shown in this example, we can also texture {@link SpecularMaterial#alpha} with\n * the *A* component of {@link SpecularMaterial#diffuseMap}'s {@link Texture}, if required.\n *\n * ## Alpha Blending\n *\n * Let's make our {@link Mesh} transparent. We'll redefine {@link SpecularMaterial#alpha}\n * and {@link SpecularMaterial#alphaMode}, causing it to blend 50% with the background:\n *\n * ````javascript\n * const myMesh = new Mesh(viewer.scene,{\n *\n *      geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry()),\n *\n *      material: new SpecularMaterial(viewer.scene,{\n *\n *          // Channels with default values, just to show them\n *\n *          diffuse: [1.0, 1.0, 1.0],\n *          specular: [1.0, 1.0, 1.0],\n *          glossiness: 1.0,\n *          emissive: [0.0, 0.0, 0.0]\n *          alpha: 0.5,         // <<----------- Changed\n *          alphaMode: \"blend\", // <<----------- Added\n *\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse.jpg\"\n *          }),\n *          specularGlossinessMap: new Texture(viewer.scene, { // RGB multiplies by specular, A by glossiness\n *              src: \"textures/specularGlossiness.jpg\"\n *          }),\n *          normalMap: new Texture(viewer.scene, {\n *              src: \"textures/normalMap.jpg\"\n *          })\n *      })\n * });\n * ````\n *\n * ## Alpha Masking\n *\n * Now let's make holes in our {@link Mesh}. We'll give its SpecularMaterial an {@link SpecularMaterial#alphaMap}\n * and configure {@link SpecularMaterial#alpha}, {@link SpecularMaterial#alphaMode},\n * and {@link SpecularMaterial#alphaCutoff} to treat it as an alpha mask:\n *\n * ````javascript\n * const myMesh = new Mesh(viewer.scene,{\n *\n *     geometry: buildTorusGeometry(viewer.scene, ReadableGeometry, {}),\n *\n *      material: new SpecularMaterial(viewer.scene, {\n *\n *          // Channels with default values, just to show them\n *\n *          diffuse: [1.0, 1.0, 1.0],\n *          specular: [1.0, 1.0, 1.0],\n *          glossiness: 1.0,\n *          emissive: [0.0, 0.0, 0.0]\n *          alpha: 1.0,         // <<----------- Changed\n *          alphaMode: \"mask\",  // <<----------- Changed\n *          alphaCutoff: 0.2,   // <<----------- Added\n *\n *          alphaMap: new Texture(viewer.scene, { // <<---------- Added\n *              src: \"textures/diffuse/crossGridColorMap.jpg\"\n *          }),\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse.jpg\"\n *          }),\n *          specularGlossinessMap: new Texture(viewer.scene, { // RGB multiplies by specular, A by glossiness\n *              src: \"textures/specularGlossiness.jpg\"\n *          }),\n *          normalMap: new Texture(viewer.scene, {\n *              src: \"textures/normalMap.jpg\"\n *          })\n *      })\n * });\n * ````\n *\n * ## Background Theory\n *\n * For an introduction to physically-based rendering (PBR) concepts, try these articles:\n *\n * * Joe Wilson's [Basic Theory of Physically-Based Rendering](https://www.marmoset.co/posts/basic-theory-of-physically-based-rendering/)\n * * Jeff Russel's [Physically-based Rendering, and you can too!](https://www.marmoset.co/posts/physically-based-rendering-and-you-can-too/)\n * * Sebastien Legarde's [Adapting a physically-based shading model](http://seblagarde.wordpress.com/tag/physically-based-rendering/)\n *\n * ## SpecularMaterial Properties\n *\n * The following table summarizes SpecularMaterial properties:\n *\n * | Property | Type | Range | Default Value | Space | Description |\n * |:--------:|:----:|:-----:|:-------------:|:-----:|:-----------:|\n * | {@link SpecularMaterial#diffuse} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the diffuse color of the material. |\n * | {@link SpecularMaterial#specular} | Array | [0, 1] for all components | [1,1,1,1] | linear | The RGB components of the specular color of the material. |\n * | {@link SpecularMaterial#glossiness} | Number | [0, 1] | 1 | linear | The glossiness the material. |\n * | {@link SpecularMaterial#specularF0} | Number | [0, 1] | 1 | linear | The specularF0 of the material surface. |\n * | {@link SpecularMaterial#emissive} | Array | [0, 1] for all components | [0,0,0] | linear | The RGB components of the emissive color of the material. |\n * | {@link SpecularMaterial#alpha} | Number | [0, 1] | 1 | linear | The transparency of the material surface (0 fully transparent, 1 fully opaque). |\n * | {@link SpecularMaterial#diffuseMap} | {@link Texture} |  | null | sRGB | Texture RGB components multiplying by {@link SpecularMaterial#diffuse}. If the fourth component (A) is present, it multiplies by {@link SpecularMaterial#alpha}. |\n * | {@link SpecularMaterial#specularMap} | {@link Texture} |  | null | sRGB | Texture RGB components multiplying by {@link SpecularMaterial#specular}. If the fourth component (A) is present, it multiplies by {@link SpecularMaterial#alpha}. |\n * | {@link SpecularMaterial#glossinessMap} | {@link Texture} |  | null | linear | Texture with first component multiplying by {@link SpecularMaterial#glossiness}. |\n * | {@link SpecularMaterial#specularGlossinessMap} | {@link Texture} |  | null | linear | Texture with first three components multiplying by {@link SpecularMaterial#specular} and fourth component multiplying by {@link SpecularMaterial#glossiness}. |\n * | {@link SpecularMaterial#emissiveMap} | {@link Texture} |  | null | linear | Texture with RGB components multiplying by {@link SpecularMaterial#emissive}. |\n * | {@link SpecularMaterial#alphaMap} | {@link Texture} |  | null | linear | Texture with first component multiplying by {@link SpecularMaterial#alpha}. |\n * | {@link SpecularMaterial#occlusionMap} | {@link Texture} |  | null | linear | Ambient occlusion texture multiplying by surface's reflected diffuse and specular light. |\n * | {@link SpecularMaterial#normalMap} | {@link Texture} |  | null | linear | Tangent-space normal map. |\n * | {@link SpecularMaterial#alphaMode} | String | \"opaque\", \"blend\", \"mask\" | \"blend\" |  | Alpha blend mode. |\n * | {@link SpecularMaterial#alphaCutoff} | Number | [0..1] | 0.5 |  | Alpha cutoff value. |\n * | {@link SpecularMaterial#backfaces} | Boolean |  | false |  | Whether to render {@link Geometry} backfaces. |\n * | {@link SpecularMaterial#frontface} | String | \"ccw\", \"cw\" | \"ccw\" |  | The winding order for {@link Geometry} frontfaces - \"cw\" for clockwise, or \"ccw\" for counter-clockwise. |\n *\n */\nclass SpecularMaterial extends Material {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"SpecularMaterial\";\n    }\n\n    /**\n     *\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] The SpecularMaterial configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number[]} [cfg.diffuse=[1,1,1]] RGB diffuse color of this SpecularMaterial. Multiplies by the RGB components of {@link SpecularMaterial#diffuseMap}.\n     * @param {Texture} [cfg.diffuseMap=undefined] RGBA {@link Texture} containing the diffuse color of this SpecularMaterial, with optional *A* component for alpha. The RGB components multiply by {@link SpecularMaterial#diffuse}, while the *A* component, if present, multiplies by {@link SpecularMaterial#alpha}.\n     * @param {Number} [cfg.specular=[1,1,1]] RGB specular color of this SpecularMaterial. Multiplies by the {@link SpecularMaterial#specularMap} and the *RGB* components of {@link SpecularMaterial#specularGlossinessMap}.\n     * @param {Texture} [cfg.specularMap=undefined] RGB texture containing the specular color of this SpecularMaterial. Multiplies by the {@link SpecularMaterial#specular} property. Must be within the same {@link Scene} as this SpecularMaterial.\n     * @param {Number} [cfg.glossiness=1.0] Factor in the range [0..1] indicating how glossy this SpecularMaterial is. 0 is no glossiness, 1 is full glossiness. Multiplies by the *R* component of {@link SpecularMaterial#glossinessMap} and the *A* component of {@link SpecularMaterial#specularGlossinessMap}.\n     * @param {Texture} [cfg.specularGlossinessMap=undefined] RGBA {@link Texture} containing this SpecularMaterial's specular color in its *RGB* component and glossiness in its *A* component. Its *RGB* components multiply by {@link SpecularMaterial#specular}, while its *A* component multiplies by {@link SpecularMaterial#glossiness}. Must be within the same {@link Scene} as this SpecularMaterial.\n     * @param {Number} [cfg.specularF0=0.0] Factor in the range 0..1 indicating how reflective this SpecularMaterial is.\n     * @param {Number[]} [cfg.emissive=[0,0,0]]  RGB emissive color of this SpecularMaterial. Multiplies by the RGB components of {@link SpecularMaterial#emissiveMap}.\n     * @param {Texture} [cfg.emissiveMap=undefined] RGB {@link Texture} containing the emissive color of this SpecularMaterial. Multiplies by the {@link SpecularMaterial#emissive} property. Must be within the same {@link Scene} as this SpecularMaterial.\n     * @param {Texture} [cfg.occlusionMap=undefined] RGB ambient occlusion {@link Texture}. Within shaders, multiplies by the specular and diffuse light reflected by surfaces. Must be within the same {@link Scene} as this SpecularMaterial.\n     * @param {Texture} [cfg.normalMap=undefined] {Texture} RGB tangent-space normal {@link Texture}. Must be within the same {@link Scene} as this SpecularMaterial.\n     * @param {Number} [cfg.alpha=1.0] Factor in the range 0..1 indicating how transparent this SpecularMaterial is. A value of 0.0 indicates fully transparent, 1.0 is fully opaque. Multiplies by the *R* component of {@link SpecularMaterial#alphaMap} and the *A* component, if present, of {@link SpecularMaterial#diffuseMap}.\n     * @param {Texture} [cfg.alphaMap=undefined] RGB {@link Texture} containing this SpecularMaterial's alpha in its *R* component. The *R* component multiplies by the {@link SpecularMaterial#alpha} property. Must be within the same {@link Scene} as this SpecularMaterial.\n     * @param {String} [cfg.alphaMode=\"opaque\"] The alpha blend mode - accepted values are \"opaque\", \"blend\" and \"mask\". See the {@link SpecularMaterial#alphaMode} property for more info.\n     * @param {Number} [cfg.alphaCutoff=0.5] The alpha cutoff value. See the {@link SpecularMaterial#alphaCutoff} property for more info.\n     * @param {Boolean} [cfg.backfaces=false] Whether to render {@link Geometry} backfaces.\n     * @param {Boolean} [cfg.frontface=\"ccw\"] The winding order for {@link Geometry} front faces - \"cw\" for clockwise, or \"ccw\" for counter-clockwise.\n     * @param {Number} [cfg.lineWidth=1] Scalar that controls the width of {@link Geometry lines.\n     * @param {Number} [cfg.pointSize=1] Scalar that controls the size of {@link Geometry} points.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            type: \"SpecularMaterial\",\n            diffuse: math.vec3([1.0, 1.0, 1.0]),\n            emissive: math.vec3([0.0, 0.0, 0.0]),\n            specular: math.vec3([1.0, 1.0, 1.0]),\n            glossiness: null,\n            specularF0: null,\n            alpha: null,\n            alphaMode: null,\n            alphaCutoff: null,\n            lineWidth: null,\n            pointSize: null,\n            backfaces: null,\n            frontface: null, // Boolean for speed; true == \"ccw\", false == \"cw\"\n            hash: null\n        });\n\n        this.diffuse = cfg.diffuse;\n        this.specular = cfg.specular;\n        this.glossiness = cfg.glossiness;\n        this.specularF0 = cfg.specularF0;\n        this.emissive = cfg.emissive;\n        this.alpha = cfg.alpha;\n\n        if (cfg.diffuseMap) {\n            this._diffuseMap = this._checkComponent(\"Texture\", cfg.diffuseMap);\n        }\n        if (cfg.emissiveMap) {\n            this._emissiveMap = this._checkComponent(\"Texture\", cfg.emissiveMap);\n        }\n        if (cfg.specularMap) {\n            this._specularMap = this._checkComponent(\"Texture\", cfg.specularMap);\n        }\n        if (cfg.glossinessMap) {\n            this._glossinessMap = this._checkComponent(\"Texture\", cfg.glossinessMap);\n        }\n        if (cfg.specularGlossinessMap) {\n            this._specularGlossinessMap = this._checkComponent(\"Texture\", cfg.specularGlossinessMap);\n        }\n        if (cfg.occlusionMap) {\n            this._occlusionMap = this._checkComponent(\"Texture\", cfg.occlusionMap);\n        }\n        if (cfg.alphaMap) {\n            this._alphaMap = this._checkComponent(\"Texture\", cfg.alphaMap);\n        }\n        if (cfg.normalMap) {\n            this._normalMap = this._checkComponent(\"Texture\", cfg.normalMap);\n        }\n\n        this.alphaMode = cfg.alphaMode;\n        this.alphaCutoff = cfg.alphaCutoff;\n        this.backfaces = cfg.backfaces;\n        this.frontface = cfg.frontface;\n\n        this.lineWidth = cfg.lineWidth;\n        this.pointSize = cfg.pointSize;\n\n        this._makeHash();\n    }\n\n    _makeHash() {\n        const state = this._state;\n        const hash = [\"/spe\"];\n        if (this._diffuseMap) {\n            hash.push(\"/dm\");\n            if (this._diffuseMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n            hash.push(\"/\" + this._diffuseMap.encoding);\n        }\n        if (this._emissiveMap) {\n            hash.push(\"/em\");\n            if (this._emissiveMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._glossinessMap) {\n            hash.push(\"/gm\");\n            if (this._glossinessMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._specularMap) {\n            hash.push(\"/sm\");\n            if (this._specularMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._specularGlossinessMap) {\n            hash.push(\"/sgm\");\n            if (this._specularGlossinessMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._occlusionMap) {\n            hash.push(\"/ocm\");\n            if (this._occlusionMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._normalMap) {\n            hash.push(\"/nm\");\n            if (this._normalMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        if (this._alphaMap) {\n            hash.push(\"/opm\");\n            if (this._alphaMap.hasMatrix) {\n                hash.push(\"/mat\");\n            }\n        }\n        hash.push(\";\");\n        state.hash = hash.join(\"\");\n    }\n\n    /**\n     * Sets the RGB diffuse color of this SpecularMaterial.\n     *\n     * Multiplies by the *RGB* components of {@link SpecularMaterial#diffuseMap}.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     * @type {Number[]}\n     */\n    set diffuse(value) {\n        let diffuse = this._state.diffuse;\n        if (!diffuse) {\n            diffuse = this._state.diffuse = new Float32Array(3);\n        } else if (value && diffuse[0] === value[0] && diffuse[1] === value[1] && diffuse[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            diffuse[0] = value[0];\n            diffuse[1] = value[1];\n            diffuse[2] = value[2];\n        } else {\n            diffuse[0] = 1;\n            diffuse[1] = 1;\n            diffuse[2] = 1;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the RGB diffuse color of this SpecularMaterial.\n     *\n     * @type {Number[]}\n     */\n    get diffuse() {\n        return this._state.diffuse;\n    }\n\n    /**\n     * Gets the RGB {@link Texture} containing the diffuse color of this SpecularMaterial, with optional *A* component for alpha.\n     *\n     * The *RGB* components multipliues by the {@link SpecularMaterial#diffuse} property, while the *A* component, if present, multiplies by the {@link SpecularMaterial#alpha} property.\n     *\n     * @type {Texture}\n     */\n    get diffuseMap() {\n        return this._diffuseMap;\n    }\n\n    /**\n     * Sets the RGB specular color of this SpecularMaterial.\n     *\n     * Multiplies by {@link SpecularMaterial#specularMap} and the *A* component of {@link SpecularMaterial#specularGlossinessMap}.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @type {Number[]}\n     */\n    set specular(value) {\n        let specular = this._state.specular;\n        if (!specular) {\n            specular = this._state.specular = new Float32Array(3);\n        } else if (value && specular[0] === value[0] && specular[1] === value[1] && specular[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            specular[0] = value[0];\n            specular[1] = value[1];\n            specular[2] = value[2];\n        } else {\n            specular[0] = 1;\n            specular[1] = 1;\n            specular[2] = 1;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the RGB specular color of this SpecularMaterial.\n     *\n     * @type {Number[]}\n     */\n    get specular() {\n        return this._state.specular;\n    }\n\n    /**\n     * Gets the RGB texture containing the specular color of this SpecularMaterial.\n     *\n     * Multiplies by {@link SpecularMaterial#specular}.\n     *\n     * @type {Texture}\n     */\n    get specularMap() {\n        return this._specularMap;\n    }\n\n    /**\n     * Gets the RGBA texture containing this SpecularMaterial's specular color in its *RGB* components and glossiness in its *A* component.\n     *\n     * The *RGB* components multiplies {@link SpecularMaterial#specular}, while the *A* component multiplies by {@link SpecularMaterial#glossiness}.\n     *\n     * @type {Texture}\n     */\n    get specularGlossinessMap() {\n        return this._specularGlossinessMap;\n    }\n\n    /**\n     * Sets the Factor in the range [0..1] indicating how glossy this SpecularMaterial is.\n     *\n     * ````0```` is no glossiness, ````1```` is full glossiness.\n     *\n     * Multiplies by the *R* component of {@link SpecularMaterial#glossinessMap} and the *A* component of {@link SpecularMaterial#specularGlossinessMap}.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set glossiness(value) {\n        value = (value !== undefined && value !== null) ? value : 1.0;\n        if (this._state.glossiness === value) {\n            return;\n        }\n        this._state.glossiness = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Factor in the range ````[0..1]```` indicating how glossy this SpecularMaterial is.\n\n     * @type {Number}\n     */\n    get glossiness() {\n        return this._state.glossiness;\n    }\n\n    /**\n     * Gets the RGB texture containing this SpecularMaterial's glossiness in its *R* component.\n     *\n     * The *R* component multiplies by {@link SpecularMaterial#glossiness}.\n     ** @type {Texture}\n     */\n    get glossinessMap() {\n        return this._glossinessMap;\n    }\n\n    /**\n     * Sets the factor in the range ````[0..1]```` indicating amount of specular Fresnel.\n     *\n     * Default value is ````0.0````.\n     *\n     * @type {Number}\n     */\n    set specularF0(value) {\n        value = (value !== undefined && value !== null) ? value : 0.0;\n        if (this._state.specularF0 === value) {\n            return;\n        }\n        this._state.specularF0 = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the factor in the range ````[0..1]```` indicating amount of specular Fresnel.\n     *\n     * @type {Number}\n     */\n    get specularF0() {\n        return this._state.specularF0;\n    }\n\n    /**\n     * Sets the RGB emissive color of this SpecularMaterial.\n     *\n     * Multiplies by {@link SpecularMaterial#emissiveMap}.\n\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @type {Number[]}\n     */\n    set emissive(value) {\n        let emissive = this._state.emissive;\n        if (!emissive) {\n            emissive = this._state.emissive = new Float32Array(3);\n        } else if (value && emissive[0] === value[0] && emissive[1] === value[1] && emissive[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            emissive[0] = value[0];\n            emissive[1] = value[1];\n            emissive[2] = value[2];\n        } else {\n            emissive[0] = 0;\n            emissive[1] = 0;\n            emissive[2] = 0;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the RGB emissive color of this SpecularMaterial.\n     *\n     * @type {Number[]}\n     */\n    get emissive() {\n        return this._state.emissive;\n    }\n\n    /**\n     * Gets the RGB texture containing the emissive color of this SpecularMaterial.\n     *\n     * Multiplies by {@link SpecularMaterial#emissive}.\n     *\n     * @type {Texture}\n     */\n    get emissiveMap() {\n        return this._emissiveMap;\n    }\n\n    /**\n     * Sets the factor in the range [0..1] indicating how transparent this SpecularMaterial is.\n     *\n     * A value of ````0.0```` is fully transparent, while ````1.0```` is fully opaque.\n     *\n     * Multiplies by the *R* component of {@link SpecularMaterial#alphaMap} and the *A* component, if present, of {@link SpecularMaterial#diffuseMap}.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set alpha(value) {\n        value = (value !== undefined && value !== null) ? value : 1.0;\n        if (this._state.alpha === value) {\n            return;\n        }\n        this._state.alpha = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the factor in the range [0..1] indicating how transparent this SpecularMaterial is.\n     *\n     * @type {Number}\n     */\n    get alpha() {\n        return this._state.alpha;\n    }\n\n    /**\n     * Gets the RGB {@link Texture} with alpha in its *R* component.\n     *\n     * The *R* component multiplies by the {@link SpecularMaterial#alpha} property.\n     *\n     * @type {Texture}\n     */\n    get alphaMap() {\n        return this._alphaMap;\n    }\n\n    /**\n     * Gets the RGB tangent-space normal {@link Texture} attached to this SpecularMaterial.\n     *\n     * @type {Texture}\n     */\n    get normalMap() {\n        return this._normalMap;\n    }\n\n    /**\n     * Gets the RGB ambient occlusion {@link Texture} attached to this SpecularMaterial.\n     *\n     * Multiplies by the specular and diffuse light reflected by surfaces.\n     *\n     * @type {Texture}\n     */\n    get occlusionMap() {\n        return this._occlusionMap;\n    }\n\n    /**\n     * Sets the alpha rendering mode.\n     *\n     * This governs how alpha is treated. Alpha is the combined result of the {@link SpecularMaterial#alpha} and {@link SpecularMaterial#alphaMap} properties.\n     *\n     * Accepted values are:\n     *\n     * * \"opaque\" - The alpha value is ignored and the rendered output is fully opaque (default).\n     * * \"mask\" - The rendered output is either fully opaque or fully transparent depending on the alpha value and the specified alpha cutoff value.\n     * * \"blend\" - The alpha value is used to composite the source and destination areas. The rendered output is combined with the background using the normal painting operation (i.e. the Porter and Duff over operator)\n     *\n     * @type {String}\n     */\n    set alphaMode(alphaMode) {\n        alphaMode = alphaMode || \"opaque\";\n        let value = alphaModes[alphaMode];\n        if (value === undefined) {\n            this.error(\"Unsupported value for 'alphaMode': \" + alphaMode + \" defaulting to 'opaque'\");\n            value = \"opaque\";\n        }\n        if (this._state.alphaMode === value) {\n            return;\n        }\n        this._state.alphaMode = value;\n        this.glRedraw();\n    }\n\n    get alphaMode() {\n        return alphaModeNames[this._state.alphaMode];\n    }\n\n    /**\n     * Sets the alpha cutoff value.\n     *\n     * Specifies the cutoff threshold when {@link SpecularMaterial#alphaMode} equals \"mask\". If the alpha is greater than or equal to this value then it is rendered as fully opaque, otherwise, it is rendered as fully transparent. A value greater than 1.0 will render the entire material as fully transparent. This value is ignored for other modes.\n     *\n     * Alpha is the combined result of the {@link SpecularMaterial#alpha} and {@link SpecularMaterial#alphaMap} properties.\n     *\n     * Default value is ````0.5````.\n     *\n     * @type {Number}\n     */\n    set alphaCutoff(alphaCutoff) {\n        if (alphaCutoff === null || alphaCutoff === undefined) {\n            alphaCutoff = 0.5;\n        }\n        if (this._state.alphaCutoff === alphaCutoff) {\n            return;\n        }\n        this._state.alphaCutoff = alphaCutoff;\n    }\n\n    /**\n     * Gets the alpha cutoff value.\n\n     * @type {Number}\n     */\n    get alphaCutoff() {\n        return this._state.alphaCutoff;\n    }\n\n    /**\n     * Sets whether backfaces are visible on attached {@link Mesh}es.\n     *\n     * The backfaces will belong to {@link ReadableGeometry} compoents that are also attached to the {@link Mesh}es.\n     *\n     * Default is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set backfaces(value) {\n        value = !!value;\n        if (this._state.backfaces === value) {\n            return;\n        }\n        this._state.backfaces = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether backfaces are visible on attached {@link Mesh}es.\n     *\n     * @type {Boolean}\n     */\n    get backfaces() {\n        return this._state.backfaces;\n    }\n\n    /**\n     * Sets the winding direction of front faces of {@link Geometry} of attached {@link Mesh}es.\n     *\n     * Default value is ````\"ccw\"````.\n     *\n     * @type {String}\n     */\n    set frontface(value) {\n        value = value !== \"cw\";\n        if (this._state.frontface === value) {\n            return;\n        }\n        this._state.frontface = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the winding direction of front faces of {@link Geometry} of attached {@link Mesh}es.\n     *\n     * @type {String}\n     */\n    get frontface() {\n        return this._state.frontface ? \"ccw\" : \"cw\";\n    }\n\n    /**\n     * Sets the SpecularMaterial's line width.\n     *\n     * This is not supported by WebGL implementations based on DirectX [2019].\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set lineWidth(value) {\n        this._state.lineWidth = value || 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the SpecularMaterial's line width.\n     *\n     * @type {Number}\n     */\n    get lineWidth() {\n        return this._state.lineWidth;\n    }\n\n    /**\n     * Sets the SpecularMaterial's point size.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set pointSize(value) {\n        this._state.pointSize = value || 1;\n        this.glRedraw();\n    }\n\n    /**\n     * Sets the SpecularMaterial's point size.\n     *\n     * @type {Number}\n     */\n    get pointSize() {\n        return this._state.pointSize;\n    }\n\n    /**\n     * Destroys this SpecularMaterial.\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\nconst PRESETS$3 = {\n    \"default\": {\n        fill: true,\n        fillColor: [0.4, 0.4, 0.4],\n        fillAlpha: 0.2,\n        edges: true,\n        edgeColor: [0.2, 0.2, 0.2],\n        edgeAlpha: 0.5,\n        edgeWidth: 1\n    },\n    \"defaultWhiteBG\": {\n        fill: true,\n        fillColor: [1, 1, 1],\n        fillAlpha: 0.6,\n        edgeColor: [0.2, 0.2, 0.2],\n        edgeAlpha: 1.0,\n        edgeWidth: 1\n    },\n    \"defaultLightBG\": {\n        fill: true,\n        fillColor: [0.4, 0.4, 0.4],\n        fillAlpha: 0.2,\n        edges: true,\n        edgeColor: [0.2, 0.2, 0.2],\n        edgeAlpha: 0.5,\n        edgeWidth: 1\n    },\n    \"defaultDarkBG\": {\n        fill: true,\n        fillColor: [0.4, 0.4, 0.4],\n        fillAlpha: 0.2,\n        edges: true,\n        edgeColor: [0.5, 0.5, 0.5],\n        edgeAlpha: 0.5,\n        edgeWidth: 1\n    },\n    \"phosphorous\": {\n        fill: true,\n        fillColor: [0.0, 0.0, 0.0],\n        fillAlpha: 0.4,\n        edges: true,\n        edgeColor: [0.9, 0.9, 0.9],\n        edgeAlpha: 0.5,\n        edgeWidth: 2\n    },\n    \"sunset\": {\n        fill: true,\n        fillColor: [0.9, 0.9, 0.6],\n        fillAlpha: 0.2,\n        edges: true,\n        edgeColor: [0.9, 0.9, 0.9],\n        edgeAlpha: 0.5,\n        edgeWidth: 1\n    },\n    \"vectorscope\": {\n        fill: true,\n        fillColor: [0.0, 0.0, 0.0],\n        fillAlpha: 0.7,\n        edges: true,\n        edgeColor: [0.2, 1.0, 0.2],\n        edgeAlpha: 1,\n        edgeWidth: 2\n    },\n    \"battlezone\": {\n        fill: true,\n        fillColor: [0.0, 0.0, 0.0],\n        fillAlpha: 1.0,\n        edges: true,\n        edgeColor: [0.2, 1.0, 0.2],\n        edgeAlpha: 1,\n        edgeWidth: 3\n    },\n    \"sepia\": {\n        fill: true,\n        fillColor: [0.970588207244873, 0.7965892553329468, 0.6660899519920349],\n        fillAlpha: 0.4,\n        edges: true,\n        edgeColor: [0.529411792755127, 0.4577854573726654, 0.4100345969200134],\n        edgeAlpha: 1.0,\n        edgeWidth: 1\n    },\n    \"yellowHighlight\": {\n        fill: true,\n        fillColor: [1.0, 1.0, 0.0],\n        fillAlpha: 0.5,\n        edges: true,\n        edgeColor: [1.0, 1.0, 1.0],\n        edgeAlpha: 1.0,\n        edgeWidth: 1\n    },\n    \"greenSelected\": {\n        fill: true,\n        fillColor: [0.0, 1.0, 0.0],\n        fillAlpha: 0.5,\n        edges: true,\n        edgeColor: [1.0, 1.0, 1.0],\n        edgeAlpha: 1.0,\n        edgeWidth: 1\n    },\n    \"gamegrid\": {\n        fill: true,\n        fillColor: [0.2, 0.2, 0.7],\n        fillAlpha: 0.9,\n        edges: true,\n        edgeColor: [0.4, 0.4, 1.6],\n        edgeAlpha: 0.8,\n        edgeWidth: 3\n    }\n};\n\n/**\n * Configures the appearance of {@link Entity}s when they are xrayed, highlighted or selected.\n *\n * * XRay an {@link Entity} by setting {@link Entity#xrayed} ````true````.\n * * Highlight an {@link Entity} by setting {@link Entity#highlighted} ````true````.\n * * Select an {@link Entity} by setting {@link Entity#selected} ````true````.\n * * When {@link Entity}s are within the subtree of a root {@link Entity}, then setting {@link Entity#xrayed}, {@link Entity#highlighted} or {@link Entity#selected}\n * on the root will collectively set those properties on all sub-{@link Entity}s.\n * * EmphasisMaterial provides several presets. Select a preset by setting {@link EmphasisMaterial#preset} to the ID of a preset in {@link EmphasisMaterial#presets}.\n * * By default, a {@link Mesh} uses the default EmphasisMaterials in {@link Scene#xrayMaterial}, {@link Scene#highlightMaterial} and {@link Scene#selectedMaterial}\n * but you can assign each {@link Mesh#xrayMaterial}, {@link Mesh#highlightMaterial} or {@link Mesh#selectedMaterial} to a custom EmphasisMaterial, if required.\n *\n * ## Usage\n *\n * In the example below, we'll create a {@link Mesh} with its own XRayMaterial and set {@link Mesh#xrayed} ````true```` to xray it.\n *\n * Recall that {@link Mesh} is a concrete subtype of the abstract {@link Entity} base class.\n *\n * ````javascript\n * new Mesh(viewer.scene, {\n *     geometry: new BoxGeometry(viewer.scene, {\n *         edgeThreshold: 1\n *     }),\n *     material: new PhongMaterial(viewer.scene, {\n *         diffuse: [0.2, 0.2, 1.0]\n *     }),\n *     xrayMaterial: new EmphasisMaterial(viewer.scene, {\n *         fill: true,\n *         fillColor: [0, 0, 0],\n *         fillAlpha: 0.7,\n *         edges: true,\n *         edgeColor: [0.2, 1.0, 0.2],\n *         edgeAlpha: 1.0,\n *         edgeWidth: 2\n *     }),\n *     xrayed: true\n * });\n * ````\n *\n * Note the ````edgeThreshold```` configuration for the {@link ReadableGeometry} on our {@link Mesh}.  EmphasisMaterial configures\n * a wireframe representation of the {@link ReadableGeometry} for the selected emphasis mode, which will have inner edges (those edges between\n * adjacent co-planar triangles) removed for visual clarity. The ````edgeThreshold```` indicates that, for\n * this particular {@link ReadableGeometry}, an inner edge is one where the angle between the surface normals of adjacent triangles\n * is not greater than ````5```` degrees. That's set to ````2```` by default, but we can override it to tweak the effect\n * as needed for particular Geometries.\n *\n * Here's the example again, this time implicitly defaulting to the {@link Scene#edgeMaterial}. We'll also modify that EdgeMaterial\n * to customize the effect.\n *\n * ````javascript\n * new Mesh({\n *     geometry: new TeapotGeometry(viewer.scene, {\n *         edgeThreshold: 5\n *     }),\n *     material: new PhongMaterial(viewer.scene, {\n *         diffuse: [0.2, 0.2, 1.0]\n *     }),\n *     xrayed: true\n * });\n *\n * var xrayMaterial = viewer.scene.xrayMaterial;\n *\n * xrayMaterial.fillColor = [0.2, 1.0, 0.2];\n * xrayMaterial.fillAlpha = 1.0;\n * ````\n *\n * ## Presets\n *\n * Let's switch the {@link Scene#xrayMaterial} to one of the presets in {@link EmphasisMaterial#presets}:\n *\n * ````javascript\n * viewer.xrayMaterial.preset = EmphasisMaterial.presets[\"sepia\"];\n * ````\n *\n * We can also create an EmphasisMaterial from a preset, while overriding properties of the preset as required:\n *\n * ````javascript\n * var myEmphasisMaterial = new EMphasisMaterial(viewer.scene, {\n *      preset: \"sepia\",\n *      fillColor = [1.0, 0.5, 0.5]\n * });\n * ````\n */\nclass EmphasisMaterial extends Material {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"EmphasisMaterial\";\n    }\n\n    /**\n     * Gets available EmphasisMaterial presets.\n     *\n     * @type {Object}\n     */\n    get presets() {\n        return PRESETS$3;\n    };\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] The EmphasisMaterial configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Boolean} [cfg.fill=true] Indicates if xray surfaces are filled with color.\n     * @param {Number[]} [cfg.fillColor=[0.4,0.4,0.4]] EmphasisMaterial fill color.\n     * @param  {Number} [cfg.fillAlpha=0.2] Transparency of filled xray faces. A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     * @param {Boolean} [cfg.edges=true] Indicates if xray edges are visible.\n     * @param {Number[]} [cfg.edgeColor=[0.2,0.2,0.2]]  RGB color of xray edges.\n     * @param {Number} [cfg.edgeAlpha=0.5] Transparency of xray edges. A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     * @param {Number} [cfg.edgeWidth=1] Width of xray edges, in pixels.\n     * @param {String} [cfg.preset] Deprecated - will be removed in future releases - Selects a preset EmphasisMaterial configuration - see {@link EmphasisMaterial#presets}.\n     * @param {Boolean} [cfg.backfaces=false] Whether to render geometry backfaces when emphasising.\n     * @param {Boolean} [cfg.glowThrough=true] Whether to make the emphasized object appear to float on top of other objects, as if it were \"glowing through\" them.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            type: \"EmphasisMaterial\",\n            fill: null,\n            fillColor: null,\n            fillAlpha: null,\n            edges: null,\n            edgeColor: null,\n            edgeAlpha: null,\n            edgeWidth: null,\n            backfaces: true,\n            glowThrough: true\n        });\n\n        this._preset = \"default\";\n\n        if (cfg.preset) { // Apply preset then override with configs where provided\n            this.preset = cfg.preset;\n            if (cfg.fill !== undefined) {\n                this.fill = cfg.fill;\n            }\n            if (cfg.fillColor) {\n                this.fillColor = cfg.fillColor;\n            }\n            if (cfg.fillAlpha !== undefined) {\n                this.fillAlpha = cfg.fillAlpha;\n            }\n            if (cfg.edges !== undefined) {\n                this.edges = cfg.edges;\n            }\n            if (cfg.edgeColor) {\n                this.edgeColor = cfg.edgeColor;\n            }\n            if (cfg.edgeAlpha !== undefined) {\n                this.edgeAlpha = cfg.edgeAlpha;\n            }\n            if (cfg.edgeWidth !== undefined) {\n                this.edgeWidth = cfg.edgeWidth;\n            }\n            if (cfg.backfaces !== undefined) {\n                this.backfaces = cfg.backfaces;\n            }\n            if (cfg.glowThrough !== undefined) {\n                this.glowThrough = cfg.glowThrough;\n            }\n        } else {\n            this.fill = cfg.fill;\n            this.fillColor = cfg.fillColor;\n            this.fillAlpha = cfg.fillAlpha;\n            this.edges = cfg.edges;\n            this.edgeColor = cfg.edgeColor;\n            this.edgeAlpha = cfg.edgeAlpha;\n            this.edgeWidth = cfg.edgeWidth;\n            this.backfaces = cfg.backfaces;\n            this.glowThrough = cfg.glowThrough;\n        }\n    }\n\n    /**\n     * Sets if surfaces are filled with color.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set fill(value) {\n        value = value !== false;\n        if (this._state.fill === value) {\n            return;\n        }\n        this._state.fill = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if surfaces are filled with color.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get fill() {\n        return this._state.fill;\n    }\n\n    /**\n     * Sets the RGB color of filled faces.\n     *\n     * Default is ````[0.4, 0.4, 0.4]````.\n     *\n     * @type {Number[]}\n     */\n    set fillColor(value) {\n        let fillColor = this._state.fillColor;\n        if (!fillColor) {\n            fillColor = this._state.fillColor = new Float32Array(3);\n        } else if (value && fillColor[0] === value[0] && fillColor[1] === value[1] && fillColor[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            fillColor[0] = value[0];\n            fillColor[1] = value[1];\n            fillColor[2] = value[2];\n        } else {\n            fillColor[0] = 0.4;\n            fillColor[1] = 0.4;\n            fillColor[2] = 0.4;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the RGB color of filled faces.\n     *\n     * Default is ````[0.4, 0.4, 0.4]````.\n     *\n     * @type {Number[]}\n     */\n    get fillColor() {\n        return this._state.fillColor;\n    }\n\n    /**\n     * Sets the transparency of filled faces.\n     *\n     * A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     *\n     * Default is ````0.2````.\n     *\n     * @type {Number}\n     */\n    set fillAlpha(value) {\n        value = (value !== undefined && value !== null) ? value : 0.2;\n        if (this._state.fillAlpha === value) {\n            return;\n        }\n        this._state.fillAlpha = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the transparency of filled faces.\n     *\n     * A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     *\n     * Default is ````0.2````.\n     *\n     * @type {Number}\n     */\n    get fillAlpha() {\n        return this._state.fillAlpha;\n    }\n\n    /**\n     * Sets if edges are visible.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set edges(value) {\n        value = value !== false;\n        if (this._state.edges === value) {\n            return;\n        }\n        this._state.edges = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if edges are visible.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get edges() {\n        return this._state.edges;\n    }\n\n    /**\n     * Sets the RGB color of edges.\n     *\n     * Default is ```` [0.2, 0.2, 0.2]````.\n     *\n     * @type {Number[]}\n     */\n    set edgeColor(value) {\n        let edgeColor = this._state.edgeColor;\n        if (!edgeColor) {\n            edgeColor = this._state.edgeColor = new Float32Array(3);\n        } else if (value && edgeColor[0] === value[0] && edgeColor[1] === value[1] && edgeColor[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            edgeColor[0] = value[0];\n            edgeColor[1] = value[1];\n            edgeColor[2] = value[2];\n        } else {\n            edgeColor[0] = 0.2;\n            edgeColor[1] = 0.2;\n            edgeColor[2] = 0.2;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the RGB color of edges.\n     *\n     * Default is ```` [0.2, 0.2, 0.2]````.\n     *\n     * @type {Number[]}\n     */\n    get edgeColor() {\n        return this._state.edgeColor;\n    }\n\n    /**\n     * Sets the transparency of edges.\n     *\n     * A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     *\n     * Default is ````0.2````.\n     *\n     * @type {Number}\n     */\n    set edgeAlpha(value) {\n        value = (value !== undefined && value !== null) ? value : 0.5;\n        if (this._state.edgeAlpha === value) {\n            return;\n        }\n        this._state.edgeAlpha = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the transparency of edges.\n     *\n     * A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     *\n     * Default is ````0.2````.\n     *\n     * @type {Number}\n     */\n    get edgeAlpha() {\n        return this._state.edgeAlpha;\n    }\n\n    /**\n     * Sets edge width.\n     *\n     * This is not supported by WebGL implementations based on DirectX [2019].\n     *\n     * Default value is ````1.0```` pixels.\n     *\n     * @type {Number}\n     */\n    set edgeWidth(value) {\n        this._state.edgeWidth = value || 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets edge width.\n     *\n     * This is not supported by WebGL implementations based on DirectX [2019].\n     *\n     * Default value is ````1.0```` pixels.\n     *\n     * @type {Number}\n     */\n    get edgeWidth() {\n        return this._state.edgeWidth;\n    }\n\n    /**\n     * Sets whether to render backfaces when {@link EmphasisMaterial#fill} is ````true````.\n     *\n     * Default is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set backfaces(value) {\n        value = !!value;\n        if (this._state.backfaces === value) {\n            return;\n        }\n        this._state.backfaces = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether to render backfaces when {@link EmphasisMaterial#fill} is ````true````.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get backfaces() {\n        return this._state.backfaces;\n    }\n\n    /**\n     * Sets whether to render emphasized objects over the top of other objects, as if they were \"glowing through\".\n     *\n     * Default is ````true````.\n     *\n     * Note: updating this property will not affect the appearance of objects that are already emphasized.\n     *\n     * @type {Boolean}\n     */\n    set glowThrough(value) {\n        value = (value !== false);\n        if (this._state.glowThrough === value) {\n            return;\n        }\n        this._state.glowThrough = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Sets whether to render emphasized objects over the top of other objects, as if they were \"glowing through\".\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get glowThrough() {\n        return this._state.glowThrough;\n    }\n\n    /**\n     * @deprecated\n     * Selects a preset EmphasisMaterial configuration.\n     *\n     * Default value is \"default\".\n     *\n     * @type {String}\n     */\n    set preset(value) {\n        console.warn(\"EmphasisMaterial.preset is deprecated and will be removed in future versions.\");\n        value = value || \"default\";\n        if (this._preset === value) {\n            return;\n        }\n        const preset = PRESETS$3[value];\n        if (!preset) {\n            this.error(\"unsupported preset: '\" + value + \"' - supported values are \" + Object.keys(PRESETS$3).join(\", \"));\n            return;\n        }\n        this.fill = preset.fill;\n        this.fillColor = preset.fillColor;\n        this.fillAlpha = preset.fillAlpha;\n        this.edges = preset.edges;\n        this.edgeColor = preset.edgeColor;\n        this.edgeAlpha = preset.edgeAlpha;\n        this.edgeWidth = preset.edgeWidth;\n        this.glowThrough = preset.glowThrough;\n        this._preset = value;\n    }\n\n    /**\n     * @deprecated\n     * Gets the current preset EmphasisMaterial configuration.\n     *\n     * Default value is \"default\".\n     *\n     * @type {String}\n     */\n    get preset() {\n        console.warn(\"EmphasisMaterial.preset is deprecated and will be removed in future versions.\");\n        return this._preset;\n    }\n\n    /**\n     * Destroys this EmphasisMaterial.\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\nconst PRESETS$2 = {\n    \"default\": {\n        edgeColor: [0.0, 0.0, 0.0],\n        edgeAlpha: 1.0,\n        edgeWidth: 1\n    },\n    \"defaultWhiteBG\": {\n        edgeColor: [0.2, 0.2, 0.2],\n        edgeAlpha: 1.0,\n        edgeWidth: 1\n    },\n    \"defaultLightBG\": {\n        edgeColor: [0.2, 0.2, 0.2],\n        edgeAlpha: 1.0,\n        edgeWidth: 1\n    },\n    \"defaultDarkBG\": {\n        edgeColor: [0.5, 0.5, 0.5],\n        edgeAlpha: 1.0,\n        edgeWidth: 1\n    }\n};\n\n/**\n * @desc Configures the appearance of {@link Entity}s when their edges are emphasised.\n *\n * * Emphasise edges of an {@link Entity} by setting {@link Entity#edges} ````true````.\n * * When {@link Entity}s are within the subtree of a root {@link Entity}, then setting {@link Entity#edges} on the root\n * will collectively set that property on all sub-{@link Entity}s.\n * * EdgeMaterial provides several presets. Select a preset by setting {@link EdgeMaterial#preset} to the ID of a preset in {@link EdgeMaterial#presets}.\n * * By default, a {@link Mesh} uses the default EdgeMaterial in {@link Scene#edgeMaterial}, but you can assign each {@link Mesh#edgeMaterial} to a custom EdgeMaterial if required.\n *\n * ## Usage\n *\n * In the example below, we'll create a {@link Mesh} with its own EdgeMaterial and set {@link Mesh#edges} ````true```` to emphasise its edges.\n *\n * Recall that {@link Mesh} is a concrete subtype of the abstract {@link Entity} base class.\n *\n * [[Run this example](/examples/index.html#materials_EdgeMaterial)]\n *\n * ````javascript\n * import {Viewer, Mesh, buildSphereGeometry,\n *      ReadableGeometry, PhongMaterial, EdgeMaterial} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *\n *      geometry: new ReadableGeometry(viewer.scene, buildSphereGeometry({\n *          radius: 1.5,\n *          heightSegments: 24,\n *          widthSegments: 16,\n *          edgeThreshold: 2 // Default is 10\n *      })),\n *\n *      material: new PhongMaterial(viewer.scene, {\n *          diffuse: [0.4, 0.4, 1.0],\n *          ambient: [0.9, 0.3, 0.9],\n *          shininess: 30,\n *          alpha: 0.5,\n *          alphaMode: \"blend\"\n *      }),\n *\n *      edgeMaterial: new EdgeMaterial(viewer.scene, {\n *          edgeColor: [0.0, 0.0, 1.0]\n *          edgeAlpha: 1.0,\n *          edgeWidth: 2\n *      }),\n *\n *      edges: true\n * });\n * ````\n *\n * Note the ````edgeThreshold```` configuration for the {@link ReadableGeometry} on our {@link Mesh}.  EdgeMaterial configures\n * a wireframe representation of the {@link ReadableGeometry}, which will have inner edges (those edges between\n * adjacent co-planar triangles) removed for visual clarity. The ````edgeThreshold```` indicates that, for\n * this particular {@link ReadableGeometry}, an inner edge is one where the angle between the surface normals of adjacent triangles\n * is not greater than ````5```` degrees. That's set to ````2```` by default, but we can override it to tweak the effect\n * as needed for particular Geometries.\n *\n * Here's the example again, this time implicitly defaulting to the {@link Scene#edgeMaterial}. We'll also modify that EdgeMaterial\n * to customize the effect.\n *\n * ````javascript\n * new Mesh({\n *     geometry: new ReadableGeometry(viewer.scene, buildSphereGeometry({\n *          radius: 1.5,\n *          heightSegments: 24,\n *          widthSegments: 16,\n *          edgeThreshold: 2 // Default is 10\n *      })),\n *     material: new PhongMaterial(viewer.scene, {\n *         diffuse: [0.2, 0.2, 1.0]\n *     }),\n *     edges: true\n * });\n *\n * var edgeMaterial = viewer.scene.edgeMaterial;\n *\n * edgeMaterial.edgeColor = [0.2, 1.0, 0.2];\n * edgeMaterial.edgeAlpha = 1.0;\n * edgeMaterial.edgeWidth = 2;\n * ````\n *\n *  ## Presets\n *\n * Let's switch the {@link Scene#edgeMaterial} to one of the presets in {@link EdgeMaterial#presets}:\n *\n * ````javascript\n * viewer.edgeMaterial.preset = EdgeMaterial.presets[\"sepia\"];\n * ````\n *\n * We can also create an EdgeMaterial from a preset, while overriding properties of the preset as required:\n *\n * ````javascript\n * var myEdgeMaterial = new EdgeMaterial(viewer.scene, {\n *      preset: \"sepia\",\n *      edgeColor = [1.0, 0.5, 0.5]\n * });\n * ````\n */\nclass EdgeMaterial extends Material {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"EdgeMaterial\";\n    }\n\n    /**\n     * Gets available EdgeMaterial presets.\n     *\n     * @type {Object}\n     */\n    get presets() {\n        return PRESETS$2;\n    };\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] The EdgeMaterial configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number[]} [cfg.edgeColor=[0.2,0.2,0.2]] RGB edge color.\n     * @param {Number} [cfg.edgeAlpha=1.0] Edge transparency. A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     * @param {Number} [cfg.edgeWidth=1] Edge width in pixels.\n     * @param {String} [cfg.preset] Selects a preset EdgeMaterial configuration - see {@link EdgeMaterial#presets}.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            type: \"EdgeMaterial\",\n            edges: null,\n            edgeColor: null,\n            edgeAlpha: null,\n            edgeWidth: null\n        });\n\n        this._preset = \"default\";\n\n        if (cfg.preset) { // Apply preset then override with configs where provided\n            this.preset = cfg.preset;\n            if (cfg.edgeColor) {\n                this.edgeColor = cfg.edgeColor;\n            }\n            if (cfg.edgeAlpha !== undefined) {\n                this.edgeAlpha = cfg.edgeAlpha;\n            }\n            if (cfg.edgeWidth !== undefined) {\n                this.edgeWidth = cfg.edgeWidth;\n            }\n        } else {\n            this.edgeColor = cfg.edgeColor;\n            this.edgeAlpha = cfg.edgeAlpha;\n            this.edgeWidth = cfg.edgeWidth;\n        }\n        this.edges = (cfg.edges !== false);\n    }\n\n\n    /**\n     * Sets if edges are visible.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set edges(value) {\n        value = value !== false;\n        if (this._state.edges === value) {\n            return;\n        }\n        this._state.edges = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if edges are visible.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get edges() {\n        return this._state.edges;\n    }\n\n    /**\n     * Sets RGB edge color.\n     *\n     * Default value is ````[0.2, 0.2, 0.2]````.\n     *\n     * @type {Number[]}\n     */\n    set edgeColor(value) {\n        let edgeColor = this._state.edgeColor;\n        if (!edgeColor) {\n            edgeColor = this._state.edgeColor = new Float32Array(3);\n        } else if (value && edgeColor[0] === value[0] && edgeColor[1] === value[1] && edgeColor[2] === value[2]) {\n            return;\n        }\n        if (value) {\n            edgeColor[0] = value[0];\n            edgeColor[1] = value[1];\n            edgeColor[2] = value[2];\n        } else {\n            edgeColor[0] = 0.2;\n            edgeColor[1] = 0.2;\n            edgeColor[2] = 0.2;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets RGB edge color.\n     *\n     * Default value is ````[0.2, 0.2, 0.2]````.\n     *\n     * @type {Number[]}\n     */\n    get edgeColor() {\n        return this._state.edgeColor;\n    }\n\n    /**\n     * Sets edge transparency.\n     *\n     * A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set edgeAlpha(value) {\n        value = (value !== undefined && value !== null) ? value : 1.0;\n        if (this._state.edgeAlpha === value) {\n            return;\n        }\n        this._state.edgeAlpha = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets edge transparency.\n     *\n     * A value of ````0.0```` indicates fully transparent, ````1.0```` is fully opaque.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    get edgeAlpha() {\n        return this._state.edgeAlpha;\n    }\n\n    /**\n     * Sets edge width.\n     *\n     * This is not supported by WebGL implementations based on DirectX [2019].\n     *\n     * Default value is ````1.0```` pixels.\n     *\n     * @type {Number}\n     */\n    set edgeWidth(value) {\n        this._state.edgeWidth = value || 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets edge width.\n     *\n     * This is not supported by WebGL implementations based on DirectX [2019].\n     *\n     * Default value is ````1.0```` pixels.\n     *\n     * @type {Number}\n     */\n    get edgeWidth() {\n        return this._state.edgeWidth;\n    }\n\n    /**\n     * Selects a preset EdgeMaterial configuration.\n     *\n     * Default value is ````\"default\"````.\n     *\n     * @type {String}\n     */\n    set preset(value) {\n        value = value || \"default\";\n        if (this._preset === value) {\n            return;\n        }\n        const preset = PRESETS$2[value];\n        if (!preset) {\n            this.error(\"unsupported preset: '\" + value + \"' - supported values are \" + Object.keys(PRESETS$2).join(\", \"));\n            return;\n        }\n        this.edgeColor = preset.edgeColor;\n        this.edgeAlpha = preset.edgeAlpha;\n        this.edgeWidth = preset.edgeWidth;\n        this._preset = value;\n    }\n\n    /**\n     * The current preset EdgeMaterial configuration.\n     *\n     * Default value is ````\"default\"````.\n     *\n     * @type {String}\n     */\n    get preset() {\n        return this._preset;\n    }\n\n    /**\n     * Destroys this EdgeMaterial.\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\n/**\n * @desc Configures Fresnel effects for {@link PhongMaterial}s.\n *\n * Fresnels are attached to {@link PhongMaterial}s, which are attached to {@link Mesh}es.\n *\n * ## Usage\n *\n * In the example below we'll create a {@link Mesh} with a {@link PhongMaterial} that applies a Fresnel to its alpha channel to give a glasss-like effect.\n *\n * [[Run this example](/examples/index.html#materials_Fresnel)]\n *\n * ````javascript\n * import {Viewer, Mesh, buildTorusGeometry,\n *      ReadableGeometry, PhongMaterial, Texture, Fresnel} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *       canvasId: \"myCanvas\",\n *       transparent: true\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry({\n *          center: [0, 0, 0],\n *          radius: 1.5,\n *          tube: 0.5,\n *          radialSegments: 32,\n *          tubeSegments: 24,\n *          arc: Math.PI * 2.0\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *          alpha: 0.9,\n *          alphaMode: \"blend\",\n *          ambient: [0.0, 0.0, 0.0],\n *          shininess: 30,\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse/uvGrid2.jpg\"\n *          }),\n *          alphaFresnel: new Fresnel(viewer.scene, {\nv               edgeBias: 0.2,\n *              centerBias: 0.8,\n *              edgeColor: [1.0, 1.0, 1.0],\n *              centerColor: [0.0, 0.0, 0.0],\n *              power: 2\n *          })\n *      })\n * });\n * ````\n */\nclass Fresnel extends Component {\n\n    /**\n     * JavaScript class name for this Component.\n     *\n     * @type {String}\n     */\n    get type() {\n        return \"Fresnel\";\n    }\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this Fresnel as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent scene, generated automatically when omitted.\n     * @param {Number[]} [cfg.edgeColor=[ 0.0, 0.0, 0.0 ]]  Color used on edges.\n     * @param {Number[]} [cfg.centerColor=[ 1.0, 1.0, 1.0 ]]  Color used on center.\n     * @param {Number} [cfg.edgeBias=0]  Bias at the edge.\n     * @param {Number} [cfg.centerBias=1]  Bias at the center.\n     * @param {Number} [cfg.power=0]  The power.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            edgeColor: math.vec3([0, 0, 0]),\n            centerColor: math.vec3([1, 1, 1]),\n            edgeBias: 0,\n            centerBias: 1,\n            power: 1\n        });\n\n        this.edgeColor = cfg.edgeColor;\n        this.centerColor = cfg.centerColor;\n        this.edgeBias = cfg.edgeBias;\n        this.centerBias = cfg.centerBias;\n        this.power = cfg.power;\n    }\n\n    /**\n     * Sets the Fresnel's edge color.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @type {Number[]}\n     */\n    set edgeColor(value) {\n        this._state.edgeColor.set(value || [0.0, 0.0, 0.0]);\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Fresnel's edge color.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @type {Number[]}\n     */\n    get edgeColor() {\n        return this._state.edgeColor;\n    }\n\n    /**\n     * Sets the Fresnel's center color.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @type {Number[]}\n     */\n    set centerColor(value) {\n        this._state.centerColor.set(value || [1.0, 1.0, 1.0]);\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Fresnel's center color.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @type {Number[]}\n     */\n    get centerColor() {\n        return this._state.centerColor;\n    }\n\n    /**\n     * Sets the Fresnel's edge bias.\n     *\n     * Default value is ````0````.\n     *\n     * @type {Number}\n     */\n    set edgeBias(value) {\n        this._state.edgeBias = value || 0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Fresnel's edge bias.\n     *\n     * Default value is ````0````.\n     *\n     * @type {Number}\n     */\n    get edgeBias() {\n        return this._state.edgeBias;\n    }\n\n    /**\n     * Sets the Fresnel's center bias.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    set centerBias(value) {\n        this._state.centerBias = (value !== undefined && value !== null) ? value : 1;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Fresnel's center bias.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    get centerBias() {\n        return this._state.centerBias;\n    }\n\n    /**\n     * Sets the Fresnel's power.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    set power(value) {\n        this._state.power = (value !== undefined && value !== null) ? value : 1;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the Fresnel's power.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    get power() {\n        return this._state.power;\n    }\n\n    /**\n     * Destroys this Fresnel.\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\n/**\n *  A plane-shaped 3D object containing a bitmap image.\n *\n * * Creates a 3D quad containing our bitmap, located and oriented using ````pos````, ````normal```` and ````up```` vectors.\n * * Registered by {@link Bitmap#id} in {@link Scene#bitmaps}.\n * * {@link BCFViewpointsPlugin} will save and load Bitmaps in BCF viewpoints.\n *\n * ## Usage\n *\n * In the example below, we'll load the Schependomlaan model, then use\n * an ````Bitmap```` to show a storey plan next to the model.\n *\n * [<img src=\"http://xeokit.github.io/xeokit-sdk/assets/images/Bitmap_storeyPlan.png\">](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#ImagePlane_imageInSectionPlane)\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#ImagePlane_imageInSectionPlane)]\n *\n * ````javascript\n * import {Viewer, Bitmap, XKTLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n *  });\n *\n * viewer.camera.eye = [-24.65, 21.69, 8.16];\n * viewer.camera.look = [-14.62, 2.16, -1.38];\n * viewer.camera.up = [0.59, 0.57, -0.56];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * xktLoader.load({\n *      id: \"myModel\",\n *      src: \"./models/xkt/Schependomlaan.xkt\",\n *      edges: true\n *  });\n *\n * new Bitmap(viewer.scene, {\n *      src: \"./images/schependomlaanPlanView.png\",\n *      visible: true,                             // Show the Bitmap\n *      height: 24.0,                              // Height of Bitmap\n *      pos: [-15, 0, -10],                        // World-space position of Bitmap's center\n *      normal: [0, -1, 0],                        // Vector perpendicular to Bitmap\n *      up: [0, 0, 1],                             // Direction of Bitmap \"up\"\n *      collidable: false,                         // Bitmap does not contribute to Scene boundary\n *      clippable: true,                           // Bitmap can be clipped by SectionPlanes\n *      pickable: true                             // Allow the ground plane to be picked\n * });\n * ````\n */\nclass Bitmap extends Component {\n\n    /**\n     * Creates a new Bitmap.\n     *\n     * Registers the Bitmap in {@link Scene#bitmaps}; causes Scene to fire a \"bitmapCreated\" event.\n     *\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this ````Bitmap```` as well.\n     * @param {*} [cfg]  ````Bitmap```` configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Boolean} [cfg.visible=true] Indicates whether or not this ````Bitmap```` is visible.\n     * @param {Number[]} [cfg.pos=[0,0,0]] World-space position of the ````Bitmap````.\n     * @param {Number[]} [cfg.normal=[0,0,1]] Normal vector indicating the direction the ````Bitmap```` faces.\n     * @param {Number[]} [cfg.up=[0,1,0]] Direction of \"up\" for the ````Bitmap````.\n     * @param {Number[]} [cfg.height=1] World-space height of the ````Bitmap````.\n     * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Modelling transform matrix for the ````Bitmap````. Overrides the ````position````, ````height```, ````rotation```` and ````normal```` parameters.\n     * @param {Boolean} [cfg.collidable=true] Indicates if the ````Bitmap```` is initially included in boundary calculations.\n     * @param {Boolean} [cfg.clippable=true] Indicates if the ````Bitmap```` is initially clippable.\n     * @param {Boolean} [cfg.pickable=true] Indicates if the ````Bitmap```` is initially pickable.\n     * @param {Number} [cfg.opacity=1.0] ````Bitmap````'s initial opacity factor, multiplies by the rendered fragment alpha.\n     * @param {String} [cfg.src] URL of image. Accepted file types are PNG and JPEG.\n     * @param {HTMLImageElement} [cfg.image] An ````HTMLImageElement```` to source the image from. Overrides ````src````.\n     * @param {String} [cfg.imageData]    Image data as a base64 encoded string.\n     * @param {String} [cfg.type=\"jpg\"] Image MIME type. Accepted values are \"jpg\" and \"png\". Default is \"jpg\". Normally only needed with ````image```` or ````imageData````. Automatically inferred from file extension of ````src````, if the file has a recognized extension.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._type = cfg.type || (cfg.src ? cfg.src.split('.').pop() : null) || \"jpg\";\n        this._pos = math.vec3(cfg.pos || [0, 0, 0]);\n        this._up = math.vec3(cfg.up || [0, 1, 0]);\n        this._normal = math.vec3(cfg.normal || [0, 0, 1]);\n        this._height = cfg.height || 1.0;\n\n        this._origin = math.vec3();\n        this._rtcPos = math.vec3();\n        this._imageSize = math.vec2();\n\n        this._texture = new Texture(this, {\n            flipY: true\n        });\n\n        this._image = new Image();\n\n        if (this._type !== \"jpg\" && this._type !== \"png\") {\n            this.error(`Unsupported type - defaulting to \"jpg\"`);\n            this._type = \"jpg\";\n        }\n\n        this._node = new Node$1(this, {\n            matrix: math.inverseMat4(\n                math.lookAtMat4v(this._pos, math.subVec3(this._pos, this._normal, math.mat4()),\n                    this._up,\n                    math.mat4())),\n            children: [\n\n                this._bitmapMesh = new Mesh(this, {\n                    scale: [1, 1, 1],\n                    rotation: [-90, 0, 0],\n                    collidable: cfg.collidable,\n                    pickable: cfg.pickable,\n                    opacity: cfg.opacity,\n                    clippable: cfg.clippable,\n\n                    geometry: new ReadableGeometry(this, buildPlaneGeometry({\n                        center: [0, 0, 0],\n                        xSize: 1,\n                        zSize: 1,\n                        xSegments: 2,\n                        zSegments: 2\n                    })),\n\n                    material: new PhongMaterial(this, {\n                        diffuse: [0, 0, 0],\n                        ambient: [0, 0, 0],\n                        specular: [0, 0, 0],\n                        diffuseMap: this._texture,\n                        emissiveMap: this._texture,\n                        backfaces: true\n                    })\n                })\n            ]\n        });\n\n        if (cfg.image) {\n            this.image = cfg.image;\n        } else if (cfg.src) {\n            this.src = cfg.src;\n        } else if (cfg.imageData) {\n            this.imageData = cfg.imageData;\n        }\n\n        this.scene._bitmapCreated(this);\n    }\n\n    /**\n     * Sets if this ````Bitmap```` is visible or not.\n     *\n     * Default value is ````true````.\n     *\n     * @param {Boolean} visible Set ````true```` to make this ````Bitmap```` visible.\n     */\n    set visible(visible) {\n        this._bitmapMesh.visible = visible;\n    }\n\n    /**\n     * Gets if this ````Bitmap```` is visible or not.\n     *\n     * Default value is ````true````.\n     *\n     * @returns {Boolean} Returns ````true```` if visible.\n     */\n    get visible() {\n        return this._bitmapMesh.visible;\n    }\n\n    /**\n     * Sets an ````HTMLImageElement```` to source the image from.\n     *\n     * Sets {@link Texture#src} null.\n     *\n     * You may also need to set {@link Bitmap#type}, if you want to read the image data with {@link Bitmap#imageData}.\n     *\n     * @type {HTMLImageElement}\n     */\n    set image(image) {\n        this._image = image;\n        if (this._image) {\n            this._texture.image = this._image;\n            this._imageSize[0] = this._image.width;\n            this._imageSize[1] = this._image.height;\n            this._updateBitmapMeshScale();\n        }\n    }\n\n    /**\n     * Gets the ````HTMLImageElement```` the ````Bitmap````'s image is sourced from, if set.\n     *\n     * Returns null if not set.\n     *\n     * @type {HTMLImageElement}\n     */\n    get image() {\n        return this._image;\n    }\n\n    /**\n     * Sets an image file path that the ````Bitmap````'s image is sourced from.\n     *\n     * If the file extension is a recognized MIME type, also sets {@link Bitmap#type} to that MIME type.\n     *\n     * Accepted file types are PNG and JPEG.\n     *\n     * @type {String}\n     */\n    set src(src) {\n        if (src) {\n            this._image.onload = () => {\n                this._texture.image = this._image;\n                this._imageSize[0] = this._image.width;\n                this._imageSize[1] = this._image.height;\n                this._updateBitmapMeshScale();\n            };\n            this._image.src = src;\n            const ext = src.split('.').pop();\n            switch (ext) {\n                case \"jpeg\":\n                case \"jpg\":\n                    this._type = \"jpg\";\n                    break;\n                case \"png\":\n                    this._type = \"png\";\n            }\n        }\n    }\n\n    /**\n     * Gets the image file path that the ````Bitmap````'s image is sourced from, if set.\n     *\n     * Returns null if not set.\n     *\n     * @type {String}\n     */\n    get src() {\n        return this._image.src;\n    }\n\n    /**\n     * Sets an image file path that the ````Bitmap````'s image is sourced from.\n     *\n     * Accepted file types are PNG and JPEG.\n     *\n     * Sets {@link Texture#image} null.\n     *\n     * You may also need to set {@link Bitmap#type}, if you want to read the image data with {@link Bitmap#imageData}.\n     *\n     * @type {String}\n     */\n    set imageData(imageData) {\n        this._image.onload = () => {\n            this._texture.image = image;\n            this._imageSize[0] = image.width;\n            this._imageSize[1] = image.height;\n            this._updateBitmapMeshScale();\n        };\n        this._image.src = imageData;\n    }\n\n    /**\n     * Gets the image file path that the ````Bitmap````'s image is sourced from, if set.\n     *\n     * Returns null if not set.\n     *\n     * @type {String}\n     */\n    get imageData() {\n        const canvas = document.createElement('canvas');\n        const context = canvas.getContext('2d');\n        canvas.width = this._image.width;\n        canvas.height = this._image.height;\n        context.drawImage(this._image, 0, 0);\n        return canvas.toDataURL(this._type === \"jpg\" ? 'image/jpeg' : 'image/png');\n    }\n\n    /**\n     * Sets the MIME type of this Bitmap.\n     *\n     * This is used by ````Bitmap```` when getting image data with {@link Bitmap#imageData}.\n     *\n     * Supported values are \"jpg\" and \"png\",\n     *\n     * Default is \"jpg\".\n     *\n     * @type {String}\n     */\n    set type(type) {\n        type = type || \"jpg\";\n        if (type !== \"png\" || type !== \"jpg\") {\n            this.error(\"Unsupported value for `type` - supported types are `jpg` and `png` - defaulting to `jpg`\");\n            type = \"jpg\";\n        }\n        this._type = type;\n    }\n\n    /**\n     * Gets the MIME type of this Bitmap.\n     *\n     * @type {String}\n     */\n    get type() {\n        return this._type;\n    }\n\n    /**\n     * Gets the World-space position of this ````Bitmap````.\n     *\n     * Default value is ````[0, 0, 0]````.\n     *\n     * @returns {Number[]} Current position.\n     */\n    get pos() {\n        return this._pos;\n    }\n\n    /**\n     * Gets the direction of the normal vector that is perpendicular to this ````Bitmap````.\n     *\n     * @returns {Number[]} value Current normal direction.\n     */\n    get normal() {\n        return this._normal;\n    }\n\n    /**\n     * Gets the \"up\" direction of this ````Bitmap````.\n     *\n     * @returns {Number[]} value Current \"up\" direction.\n     */\n    get up() {\n        return this._up;\n    }\n\n    /**\n     * Sets the World-space height of the ````Bitmap````.\n     *\n     * Default value is ````1.0````.\n     *\n     * @param {Number} height New World-space height of the ````Bitmap````.\n     */\n    set height(height) {\n        this._height = (height === undefined || height === null) ? 1.0 : height;\n        if (this._image) {\n            this._updateBitmapMeshScale();\n        }\n    }\n\n    /**\n     * Gets the World-space height of the ````Bitmap````.\n     *\n     * Returns {Number} World-space height of the ````Bitmap````.\n     */\n    get height() {\n        return this._height;\n    }\n\n    /**\n     * Sets if this ````Bitmap```` is included in boundary calculations.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set collidable(value) {\n        this._bitmapMesh.collidable = (value !== false);\n    }\n\n    /**\n     * Gets if this ````Bitmap```` is included in boundary calculations.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get collidable() {\n        return this._bitmapMesh.collidable;\n    }\n\n    /**\n     * Sets if this ````Bitmap```` is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set clippable(value) {\n        this._bitmapMesh.clippable = (value !== false);\n    }\n\n    /**\n     * Gets if this ````Bitmap````  is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get clippable() {\n        return this._bitmapMesh.clippable;\n    }\n\n    /**\n     * Sets if this ````Bitmap```` is pickable.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set pickable(value) {\n        this._bitmapMesh.pickable = (value !== false);\n    }\n\n    /**\n     * Gets if this ````Bitmap````  is pickable.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get pickable() {\n        return this._bitmapMesh.pickable;\n    }\n\n    /**\n     * Sets the opacity factor for this ````Bitmap````.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    set opacity(opacity) {\n        this._bitmapMesh.opacity = opacity;\n    }\n\n    /**\n     * Gets this ````Bitmap````'s opacity factor.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    get opacity() {\n        return this._bitmapMesh.opacity;\n    }\n\n    /**\n     * Destroys this ````Bitmap````.\n     *\n     * Removes the ```Bitmap```` from {@link Scene#bitmaps}; causes Scene to fire a \"bitmapDestroyed\" event.\n     */\n    destroy() {\n        super.destroy();\n        this.scene._bitmapDestroyed(this);\n    }\n\n    _updateBitmapMeshScale() {\n        const aspect = this._imageSize[1] / this._imageSize[0];\n        this._bitmapMesh.scale = [this._height / aspect, 1.0, this._height];\n    }\n}\n\n/**\n * Uses edge adjacency counts to identify if the given triangle mesh can be rendered with backface culling enabled.\n *\n * If all edges are connected to exactly two triangles, then the mesh will likely be a closed solid, and we can safely\n * render it with backface culling enabled.\n *\n * Otherwise, the mesh is a surface, and we must render it with backface culling disabled.\n *\n * @private\n */\nconst isTriangleMeshSolid = (indices, positions) => {\n\n    const vertexIndexMapping = [];\n    let edges = [];\n\n    function compareIndexPositions(a, b) {\n        let posA, posB;\n\n        for (let i = 0; i < 3; i++) {\n            posA = positions [a * 3 + i];\n            posB = positions [b * 3 + i];\n\n            if (posA !== posB) {\n                return posB - posA;\n            }\n        }\n\n        return 0;\n    }\n    // Group together indices corresponding to same position coordinates\n    let newIndices = indices.slice().sort(compareIndexPositions);\n\n    // Calculate the mapping:\n    // - from original index in indices array\n    // - to indices-for-unique-positions\n    let uniqueVertexIndex = null;\n\n    for (let i = 0, len = newIndices.length; i < len; i++) {\n        if (i === 0 || 0 !== compareIndexPositions(\n            newIndices[i],\n            newIndices[i - 1],\n        )) {\n            // different position\n            uniqueVertexIndex = newIndices [i];\n        }\n\n        vertexIndexMapping [\n            newIndices[i]\n            ] = uniqueVertexIndex;\n    }\n\n    // Generate the list of edges\n    for (let i = 0, len = indices.length; i < len; i += 3) {\n\n        const a = vertexIndexMapping[indices[i]];\n        const b = vertexIndexMapping[indices[i + 1]];\n        const c = vertexIndexMapping[indices[i + 2]];\n\n        let a2 = a;\n        let b2 = b;\n        let c2 = c;\n\n        if (a > b && a > c) {\n            if (b > c) {\n                a2 = a;\n                b2 = b;\n                c2 = c;\n            } else {\n                a2 = a;\n                b2 = c;\n                c2 = b;\n            }\n        } else if (b > a && b > c) {\n            if (a > c) {\n                a2 = b;\n                b2 = a;\n                c2 = c;\n            } else {\n                a2 = b;\n                b2 = c;\n                c2 = a;\n            }\n        } else if (c > a && c > b) {\n            if (a > b) {\n                a2 = c;\n                b2 = a;\n                c2 = b;\n            } else {\n                a2 = c;\n                b2 = b;\n                c2 = a;\n            }\n        }\n\n        edges[i + 0] = [\n            a2, b2\n        ];\n        edges[i + 1] = [\n            b2, c2\n        ];\n\n        if (a2 > c2) {\n            const temp = c2;\n            c2 = a2;\n            a2 = temp;\n        }\n\n        edges[i + 2] = [\n            c2, a2\n        ];\n    }\n\n    // Group semantically equivalent edgdes together\n    function compareEdges(e1, e2) {\n        let a, b;\n\n        for (let i = 0; i < 2; i++) {\n            a = e1[i];\n            b = e2[i];\n\n            if (b !== a) {\n                return b - a;\n            }\n        }\n\n        return 0;\n    }\n\n    edges = edges.slice(0, indices.length);\n\n    edges.sort(compareEdges);\n\n    // Make sure each edge is used exactly twice\n    let sameEdgeCount = 0;\n\n    for (let i = 0; i < edges.length; i++) {\n        if (i === 0 || 0 !== compareEdges(\n            edges[i], edges[i - 1]\n        )) {\n            // different edge\n            if (0 !== i && sameEdgeCount !== 2) {\n                return false;\n            }\n\n            sameEdgeCount = 1;\n        } else {\n            // same edge\n            sameEdgeCount++;\n        }\n    }\n\n    if (edges.length > 0 && sameEdgeCount !== 2) {\n        return false;\n    }\n\n    // Each edge is used exactly twice, this is a\n    // watertight surface and hence a solid geometry.\n    return true;\n};\n\nconst v1$1 = math.vec3();\nconst v2$1 = math.vec3();\nconst v3$1 = math.vec3();\n\n/**\n * Calculates the volume of triangle meshes.\n */\nclass MeshVolume {\n    constructor() {\n        this.vertices = [];\n        this.indices = [];\n        this.reset();\n    }\n\n    /**\n     * Resets, ready to add vertices and indices for a new mesh.\n     */\n    reset() {\n        this.lenVertices = 0;\n        this.lenIndices = 0;\n        this.primitive = null;\n    }\n\n    setPrimitive(primitive) {\n        this.primitive = primitive;\n    }\n\n    /**\n     * Adds a vertex.\n     * @param vertex\n     */\n    addVertex(vertex) {\n        this.vertices[this.lenVertices++] = vertex[0];\n        this.vertices[this.lenVertices++] = vertex[1];\n        this.vertices[this.lenVertices++] = vertex[2];\n    }\n\n    /**\n     * Adds an index.\n     * @param index\n     */\n    addIndex(index) {\n        this.indices[this.lenIndices++] = index;\n    }\n\n    /**\n     * Gets the volume of the mesh.\n     *\n     * The mesh must be a closed solid.\n     *\n     * @returns {number} The volume of the mesh, or -1 if the mesh is not solid, in which case volume cannot be determined.\n     */\n    get volume() {\n\n        const vertices = this.vertices;\n        const indices = this.indices;\n\n        if (this.primitive !== \"solid\" && this.primitive !== \"surface\" && this.primitive !== \"triangles\") {\n            return -1;\n        }\n\n        if (this.primitive !== \"solid\" && !isTriangleMeshSolid(indices, vertices)) {\n            return -1;\n        }\n\n        let volume = 0;\n\n        for (let i = 0; i < this.lenIndices; i += 3) {\n\n            const index1 = indices[i] * 3;\n            const index2 = indices[i + 1] * 3;\n            const index3 = indices[i + 2] * 3;\n\n            v1$1[0] = vertices[index1];\n            v1$1[1] = vertices[index1 + 1];\n            v1$1[2] = vertices[index1 + 2];\n\n            v2$1[0] = vertices[index2];\n            v2$1[1] = vertices[index2 + 1];\n            v2$1[2] = vertices[index2 + 2];\n\n            v3$1[0] = vertices[index3];\n            v3$1[1] = vertices[index3 + 1];\n            v3$1[2] = vertices[index3 + 2];\n\n            math.cross3Vec3(v1$1, v2$1, v1$1);\n\n            volume += math.dotVec3(v1$1, v3$1);\n        }\n\n        return volume / 6;\n    }\n}\n\n/**\n * Singleton instance of {@link MeshVolume}.\n * @type {MeshVolume}\n */\nconst meshVolume = new MeshVolume();\n\nconst v1 = math.vec3();\nconst v2 = math.vec3();\nconst v3 = math.vec3();\nconst v4 = math.vec3();\nconst v5 = math.vec3();\nconst v6 = math.vec3();\n\n/**\n * Calculates the surface area of triangle meshes.\n */\nclass MeshSurfaceArea {\n    constructor() {\n        this.vertices = [];\n        this.indices = [];\n        this.reset();\n    }\n\n    /**\n     * Resets, ready to add vertices and indices for a new mesh.\n     */\n    reset() {\n        this.lenVertices = 0;\n        this.lenIndices = 0;\n    }\n\n    /**\n     * Adds a vertex.\n     * @param vertex\n     */\n    addVertex(vertex) {\n        this.vertices[this.lenVertices++] = vertex[0];\n        this.vertices[this.lenVertices++] = vertex[1];\n        this.vertices[this.lenVertices++] = vertex[2];\n    }\n\n    /**\n     * Adds an index.\n     * @param index\n     */\n    addIndex(index) {\n        this.indices[this.lenIndices++] = index;\n    }\n\n    /**\n     * Gets the surface area of the mesh.\n     *\n     * @returns {number}\n     */\n    get surfaceArea() {\n\n        const vertices = this.vertices;\n        const indices = this.indices;\n\n        let surfaceArea = 0;\n\n        for (let i = 0; i < this.lenIndices; i += 3) {\n\n            const index1 = indices[i] * 3;\n            const index2 = indices[i + 1] * 3;\n            const index3 = indices[i + 2] * 3;\n\n            v1[0] = vertices[index1];\n            v1[1] = vertices[index1 + 1];\n            v1[2] = vertices[index1 + 2];\n\n            v2[0] = vertices[index2];\n            v2[1] = vertices[index2 + 1];\n            v2[2] = vertices[index2 + 2];\n\n            v3[0] = vertices[index3];\n            v3[1] = vertices[index3 + 1];\n            v3[2] = vertices[index3 + 2];\n\n            math.subVec3(v1, v2, v4);\n            math.subVec3(v3, v2, v5);\n\n            surfaceArea += math.lenVec3(math.cross3Vec3(v4, v5, v6)) * 0.5;\n        }\n\n        return surfaceArea;\n    }\n}\n\n/**\n * Singleton instance of {@link MeshSurfaceArea}.\n * @type {MeshSurfaceArea}\n */\nconst meshSurfaceArea = new MeshSurfaceArea();\n\nconst tempOBB3$1 = math.OBB3();\nconst tempOBB3b = math.OBB3();\nconst tempOBB3c = math.OBB3();\n\n\n/**\n * A mesh within a {@link SceneModel}.\n *\n * * Created with {@link SceneModel#createMesh}\n * * Belongs to exactly one {@link SceneModelEntity}\n * * Stored by ID in {@link SceneModel#meshes}\n * * Referenced by {@link SceneModelEntity#meshes}\n * * Can have a {@link SceneModelTransform} to dynamically scale, rotate and translate it.\n */\nclass SceneModelMesh {\n\n    /**\n     * @private\n     */\n    constructor(model, id, color, opacity, transform, textureSet, layer = null, portionId = 0) {\n\n        /**\n         * The {@link SceneModel} that owns this SceneModelMesh.\n         *\n         * @type {SceneModel}\n         */\n        this.model = model;\n\n        /**\n         * The {@link SceneModelEntity} that owns this SceneModelMesh.\n         *\n         * @type {SceneModelEntity}\n         */\n        this.object = null;\n\n        /**\n         * @private\n         */\n        this.parent = null;\n\n        /**\n         * The {@link SceneModelTransform} that transforms this SceneModelMesh.\n         *\n         * * This only exists when the SceneModelMesh is instancing its geometry.\n         * * These are created with {@link SceneModel#createTransform}\n         * * Each of these is also registered in {@link SceneModel#transforms}.\n         *\n         * @type {SceneModelTransform}\n         */\n        this.transform = transform;\n\n        /**\n         * The {@link SceneModelTextureSet} that optionally textures this SceneModelMesh.\n         *\n         * * This only exists when the SceneModelMesh has texture.\n         * * These are created with {@link SceneModel#createTextureSet}\n         * * Each of these is also registered in {@link SceneModel#textureSets}.\n         *\n         * @type {SceneModelTextureSet}\n         */\n        this.textureSet = textureSet;\n\n        this._matrixDirty = false;\n        this._matrixUpdateScheduled = false;\n\n        /**\n         * Unique ID of this SceneModelMesh.\n         *\n         * The SceneModelMesh is registered against this ID in {@link SceneModel#meshes}.\n         */\n        this.id = id;\n\n        /**\n         * @private\n         */\n        this.obb = null;\n\n        this._aabbLocal = null;\n        this._aabbWorld = math.AABB3();\n        this._aabbWorldDirty = false;\n\n        /**\n         * @private\n         */\n        this.layer = layer;\n\n        /**\n         * @private\n         */\n        this.portionId = portionId;\n\n        this._color = new Uint8Array([color[0], color[1], color[2], opacity]); // [0..255]\n        this._colorize = new Uint8Array([color[0], color[1], color[2], opacity]); // [0..255]\n        this._colorizing = false;\n        this._transparent = (opacity < 255);\n\n        /**\n         * @private\n         */\n        this.numTriangles = 0;\n\n        /**\n         * @private\n         * @type {null}\n         */\n        this.origin = null; // Set By SceneModel\n\n        /**\n         * The {@link SceneModelEntity} that owns this SceneModelMesh.\n         *\n         * @type {SceneModelEntity}\n         */\n        this.entity = null;\n\n        if (transform) {\n            transform._addMesh(this);\n        }\n\n        this._volume = null;\n        this._surfaceArea = null;\n    }\n\n    _sceneModelDirty() {\n        this._aabbWorldDirty = true;\n        this.layer.aabbChanged();\n    }\n\n    _transformDirty() {\n        if (!this._matrixDirty && !this._matrixUpdateScheduled) {\n            this.model._meshMatrixDirty(this);\n            this._matrixDirty = true;\n            this._matrixUpdateScheduled = true;\n        }\n        this._aabbWorldDirty = true;\n        this.layer.aabbChanged();\n        if (this.entity) {\n            this.entity._transformDirty();\n        }\n    }\n\n    _updateMatrix() {\n        if (this.transform && this._matrixDirty) {\n            this.layer.setMatrix(this.portionId, this.transform.worldMatrix);\n        }\n        this._matrixDirty = false;\n        this._matrixUpdateScheduled = false;\n    }\n\n    _finalize(entityFlags) {\n        this.layer.initFlags(this.portionId, entityFlags, this._transparent);\n    }\n\n    _finalize2() {\n        if (this.layer.flushInitFlags) {\n            this.layer.flushInitFlags();\n        }\n    }\n\n    _setVisible(entityFlags) {\n        this.layer.setVisible(this.portionId, entityFlags, this._transparent);\n    }\n\n    _setColor(color) {\n        this._color[0] = color[0];\n        this._color[1] = color[1];\n        this._color[2] = color[2];\n        if (!this._colorizing) {\n            this.layer.setColor(this.portionId, this._color, false);\n        }\n    }\n\n    _setColorize(colorize) {\n        const setOpacity = false;\n        if (colorize) {\n            this._colorize[0] = colorize[0];\n            this._colorize[1] = colorize[1];\n            this._colorize[2] = colorize[2];\n            this.layer.setColor(this.portionId, this._colorize, setOpacity);\n            this._colorizing = true;\n        } else {\n            this.layer.setColor(this.portionId, this._color, setOpacity);\n            this._colorizing = false;\n        }\n    }\n\n    _setOpacity(opacity, entityFlags) {\n        const newTransparent = (opacity < 255);\n        const lastTransparent = this._transparent;\n        const changingTransparency = (lastTransparent !== newTransparent);\n        this._color[3] = opacity;\n        this._colorize[3] = opacity;\n        this._transparent = newTransparent;\n        if (this._colorizing) {\n            this.layer.setColor(this.portionId, this._colorize);\n        } else {\n            this.layer.setColor(this.portionId, this._color);\n        }\n        if (changingTransparency) {\n            this.layer.setTransparent(this.portionId, entityFlags, newTransparent);\n        }\n    }\n\n    _setOffset(offset) {\n        this.layer.setOffset(this.portionId, offset);\n    }\n\n    _setHighlighted(entityFlags) {\n        this.layer.setHighlighted(this.portionId, entityFlags, this._transparent);\n    }\n\n    _setXRayed(entityFlags) {\n        this.layer.setXRayed(this.portionId, entityFlags, this._transparent);\n    }\n\n    _setSelected(entityFlags) {\n        this.layer.setSelected(this.portionId, entityFlags, this._transparent);\n    }\n\n    _setEdges(entityFlags) {\n        this.layer.setEdges(this.portionId, entityFlags, this._transparent);\n    }\n\n    _setClippable(entityFlags) {\n        this.layer.setClippable(this.portionId, entityFlags, this._transparent);\n    }\n\n    _setCollidable(entityFlags) {\n        this.layer.setCollidable(this.portionId, entityFlags);\n    }\n\n    _setPickable(flags) {\n        this.layer.setPickable(this.portionId, flags, this._transparent);\n    }\n\n    _setCulled(flags) {\n        this.layer.setCulled(this.portionId, flags, this._transparent);\n    }\n\n    /**\n     * @private\n     */\n    canPickTriangle() {\n        return false;\n    }\n\n    /**\n     * @private\n     */\n    drawPickTriangles(renderFlags, frameCtx) {\n        // NOP\n    }\n\n    /**\n     * @private\n     */\n    pickTriangleSurface(pickResult) {\n        // NOP\n    }\n\n    /**\n     * @private\n     */\n    precisionRayPickSurface(worldRayOrigin, worldRayDir, worldSurfacePos, worldSurfaceNormal) {\n        return this.layer.precisionRayPickSurface(this.portionId, worldRayOrigin, worldRayDir, worldSurfacePos, worldSurfaceNormal);\n    }\n\n    /**\n     * @private\n     */\n    canPickWorldPos() {\n        return true;\n    }\n\n    /**\n     * @private\n     */\n    drawPickDepths(frameCtx) {\n        this.model.drawPickDepths(frameCtx);\n    }\n\n    /**\n     * @private\n     */\n    drawPickNormals(frameCtx) {\n        this.model.drawPickNormals(frameCtx);\n    }\n\n    /**\n     * @private\n     */\n    delegatePickedEntity() {\n        return this.parent;\n    }\n\n    /**\n     * @private\n     */\n    getEachVertex(callback) {\n        if (this.layer.getEachVertex) {\n            this.layer.getEachVertex(this.portionId, callback);\n        }\n    }\n\n    /**\n     * @private\n     */\n    getEachIndex(callback) {\n        if (this.layer.getEachIndex ) {\n            this.layer.getEachIndex(this.portionId, callback);\n        }\n    }\n\n    isSolid() {\n        return this.layer.solid;\n    }\n\n    /**\n     * Returns the volume of this SceneModelMesh.\n     * @returns {number}\n     */\n    get volume() {\n        if (this._volume !== null) {\n            return this._volume;\n        }\n        switch (this.layer.primitive) {\n            case \"solid\":\n            case \"surface\":\n            case \"triangles\":\n                meshVolume.reset();\n                meshVolume.setPrimitive(this.layer.primitive);\n                this.getEachVertex((vertex) =>{\n                    meshVolume.addVertex(vertex);\n                });\n                this.getEachIndex((index)=>{\n                   meshVolume.addIndex(index);\n                });\n                this._volume = meshVolume.volume;\n                break;\n            default:\n                this._volume = 0;\n                break;\n        }\n        return this._volume;\n    }\n\n    /**\n     * Returns the surface area of this SceneModelMesh.\n     * @returns {number}\n     */\n    get surfaceArea() {\n        if (this._surfaceArea !== null) {\n            return this._surfaceArea;\n        }\n        switch (this.layer.primitive) {\n            case \"solid\":\n            case \"surface\":\n            case \"triangles\":\n                meshSurfaceArea.reset();\n                this.getEachVertex((vertex) =>{\n                    meshSurfaceArea.addVertex(vertex);\n                });\n                this.getEachIndex((index)=>{\n                    meshSurfaceArea.addIndex(index);\n                });\n                this._surfaceArea = meshSurfaceArea.surfaceArea;\n                break;\n            default:\n                this._surfaceArea = 0;\n                break;\n        }\n        return this._surfaceArea;\n    }\n\n    /**\n     * @private\n     */\n    set aabb(aabb) { // Called by SceneModel\n        this._aabbLocal = aabb;\n        if (this.origin) {\n            this._aabbLocal = aabb.slice(0);\n            const origin = this.origin;\n            this._aabbLocal[0] += origin[0];\n            this._aabbLocal[1] += origin[1];\n            this._aabbLocal[2] += origin[2];\n            this._aabbLocal[3] += origin[0];\n            this._aabbLocal[4] += origin[1];\n            this._aabbLocal[5] += origin[2];\n        }\n    }\n\n    /**\n     * @private\n     */\n    get aabb() { // called by SceneModelEntity\n        if (this._aabbWorldDirty) {\n            math.AABB3ToOBB3(this._aabbLocal, tempOBB3$1);\n            if (this.transform) {\n                math.transformOBB3(this.transform.worldMatrix, tempOBB3$1, tempOBB3b);\n                math.transformOBB3(this.model.worldMatrix, tempOBB3b, tempOBB3c);\n                math.OBB3ToAABB3(tempOBB3c, this._aabbWorld);\n            } else {\n                math.transformOBB3(this.model.worldMatrix, tempOBB3$1, tempOBB3b);\n                math.OBB3ToAABB3(tempOBB3b, this._aabbWorld);\n            }\n            this._aabbWorldDirty = false;\n        }\n        return this._aabbWorld;\n    }\n\n    /**\n     * @private\n     */\n    _destroy() {\n        this.model.scene._renderer.putPickID(this.pickId);\n\n        this.layer = null;\n    }\n}\n\n/**\n * @private\n * @type {{PICKABLE: number, CLIPPABLE: number, BACKFACES: number, VISIBLE: number, SELECTED: number, OUTLINED: number, CULLED: number, RECEIVE_SHADOW: number, COLLIDABLE: number, XRAYED: number, CAST_SHADOW: number, EDGES: number, HIGHLIGHTED: number}}\n */\nconst ENTITY_FLAGS = {\n    VISIBLE: 1,\n    CULLED: 1 << 2,\n    PICKABLE: 1 << 3,\n    CLIPPABLE: 1 << 4,\n    COLLIDABLE: 1 << 5,\n    CAST_SHADOW: 1 << 6,\n    RECEIVE_SHADOW: 1 << 7,\n    XRAYED: 1 << 8,\n    HIGHLIGHTED: 1 << 9,\n    SELECTED: 1 << 10,\n    EDGES: 1 << 11,\n    BACKFACES: 1 << 12,\n    TRANSPARENT: 1 << 13\n};\n\nconst ColorProgram = function(programVariables, geometry, logarithmicDepthBufferEnabled, lightSetup, sao, primitive) {\n    const vColor = programVariables.createVarying(\"vec4\", \"vColor\", () => {\n        const attributes = geometry.attributes;\n        const color = (primitive === \"points\") ? `vec4(${attributes.color}.rgb, 1.0)` : `${attributes.color}`;\n        if (lightSetup) {\n            const lightComponents = [\n                lightSetup.getAmbientColor()\n            ].concat(\n                lightSetup.directionalLights.map(\n                    light => `max(dot(${attributes.normal.view}, ${light.getDirection(geometry.viewMatrix, attributes.position.view)}), 0.0) * ${light.getColor()}`));\n            return `vec4(${lightComponents.join(\" + \")}, 1) * ${color}`;\n        } else {\n            return color;\n        }\n    });\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        programName: \"Color\",\n        getHash: () => [lightSetup ? lightSetup.getHash() : \"-\", sao ? \"sao\" : \"nosao\"],\n        cleanerEdges: true,\n        getLogDepth: logarithmicDepthBufferEnabled && (vFragDepth => ((primitive !== \"points\") && (primitive !== \"lines\")) ? `${vFragDepth} + length(vec2(dFdx(${vFragDepth}), dFdy(${vFragDepth})))` : vFragDepth),\n        renderPassFlag: 0,  // COLOR_OPAQUE | COLOR_TRANSPARENT\n        appendFragmentOutputs: (src, getGammaOutputExpression, gl_FragCoord, sliceColorOr) => {\n            if ((primitive === \"points\") || (primitive === \"lines\")) {\n                src.push(`${outColor} = ${vColor};`);\n            } else {\n                src.push(`vec4 fragColor = ${sliceColorOr(vColor)};`);\n                src.push(`${outColor} = ${(sao ? (`vec4(fragColor.rgb * ${sao.getAmbient(gl_FragCoord)}, fragColor.a)`) : \"fragColor\")};`);\n            }\n        },\n\n        filterIntensityRange: true,\n        incrementDrawState: true\n    };\n};\n\nconst ColorTextureProgram = function(programVariables, geometry, scene, lightSetup, sao, useAlphaCutoff, gammaOutput) {\n    const colorTexture = setupTexture(programVariables, \"sampler2D\", \"uColorMap\", sRGBEncoding, (set, state) => {\n        const texture = state.layerTextureSet.colorTexture;\n        texture && set(texture.texture);\n    });\n    const materialAlphaCutoff = useAlphaCutoff && programVariables.createUniform(\"float\", \"materialAlphaCutoff\", (set, state) => set(state.layerTextureSet.alphaCutoff));\n\n    const attributes = geometry.attributes;\n    const vViewPosition = programVariables.createVarying(\"vec3\", \"vViewPosition\", () => `${attributes.position.view}.xyz`);\n    const vUV           = programVariables.createVarying(\"vec2\", \"vUV\",           () => attributes.uv);\n    const vColor        = programVariables.createVarying(\"vec4\", \"vColor\",        () => attributes.color);\n\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n\n    return {\n        programName: \"ColorTexture\",\n        getHash: () => [lightSetup.getHash(), sao ? \"sao\" : \"nosao\", !!gammaOutput, useAlphaCutoff ? \"alphaCutoffYes\" : \"alphaCutoffNo\"],\n        getLogDepth: scene.logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n        renderPassFlag: 0,      // COLOR_OPAQUE | COLOR_TRANSPARENT\n        appendFragmentOutputs: (src, getGammaOutputExpression, gl_FragCoord, sliceColorOr) => {\n            src.push(`vec3 viewNormal = normalize(cross(dFdx(${vViewPosition}), dFdy(${vViewPosition})));`);\n            src.push(\"vec3 reflectedColor = vec3(0.0, 0.0, 0.0);\");\n            lightSetup.directionalLights.forEach(light => {\n                src.push(`reflectedColor += max(dot(viewNormal, ${light.getDirection(geometry.viewMatrix, vViewPosition)}), 0.0) * ${light.getColor()};`);\n            });\n\n            src.push(`vec4 color = vec4(${lightSetup.getAmbientColor()} + reflectedColor, 1) * ${sliceColorOr(vColor)};`);\n\n            src.push(`vec4 sampleColor = ${colorTexture(vUV)};`);\n\n            if (materialAlphaCutoff) {\n                src.push(`if (sampleColor.a < ${materialAlphaCutoff}) { discard; }`);\n            }\n\n            src.push(\"vec4 colorTexel = color * sampleColor;\");\n            src.push(`${outColor} = vec4(colorTexel.rgb${(sao ? (\" * \" + sao.getAmbient(gl_FragCoord)) : \"\")}, color.a);`);\n\n            getGammaOutputExpression && src.push(`${outColor} = ${getGammaOutputExpression(outColor)};`);\n        },\n\n        incrementDrawState: true\n    };\n};\n\nconst DepthProgram = function(programVariables, geometry, logarithmicDepthBufferEnabled) {\n    const vHighPrecisionZW = programVariables.createVarying(\"highp vec2\", \"vHighPrecisionZW\", () => `${geometry.attributes.position.clip}.zw`);\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        programName: \"Depth\",\n        getLogDepth: logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n        renderPassFlag: 0,  // COLOR_OPAQUE | COLOR_TRANSPARENT\n        // isn't it the same as vec4(vec3(1.0 - gl_FragCoord.z), 1.0) ?\n        appendFragmentOutputs: (src) => src.push(`${outColor} = vec4(vec3((1.0 - ${vHighPrecisionZW}[0] / ${vHighPrecisionZW}[1]) / 2.0), 1.0);`)\n    };\n};\n\nconst EdgesProgram = function(programVariables, geometry, logarithmicDepthBufferEnabled, colorUniform) {\n    const edgeColorUniform = colorUniform && programVariables.createUniform(\"vec4\", \"edgeColor\", (set, state) => set(state.legacyFrameCtx.programColor));\n    const color = geometry.attributes.color;\n    const vColor = (!colorUniform) && programVariables.createVarying(\"vec4\", \"vColor\", () => `vec4(${color}.rgb * 0.5, ${color}.a)`);\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        programName: colorUniform ? \"Edges\" : \"EdgesColor\",\n        getLogDepth: logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n        renderPassFlag: 2,  // EDGES_COLOR_OPAQUE | EDGES_COLOR_TRANSPARENT | EDGES_HIGHLIGHTED | EDGES_XRAYED | EDGES_SELECTED\n        appendFragmentOutputs: (src) => src.push(`${outColor} = ${edgeColorUniform || vColor};`)\n    };\n};\n\nconst FlatColorProgram = function(programVariables, geometry, logarithmicDepthBufferEnabled, lightSetup, sao) {\n    const attributes = geometry.attributes;\n    const vViewPosition = programVariables.createVarying(\"vec3\", \"vViewPosition\", () => `${attributes.position.view}.xyz`);\n    const vColor = programVariables.createVarying(\"vec4\", \"vColor\", () => attributes.color);\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        programName: \"FlatColor\",\n        getHash: () => [lightSetup.getHash(), sao ? \"sao\" : \"nosao\"],\n        cleanerEdges: true,\n        getLogDepth: logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n        renderPassFlag: 0,      // COLOR_OPAQUE | COLOR_TRANSPARENT\n        appendFragmentOutputs: (src, getGammaOutputExpression, gl_FragCoord, sliceColorOr) => {\n            src.push(`vec3 viewNormal = normalize(cross(dFdx(${vViewPosition}), dFdy(${vViewPosition})));`);\n            const lightComponents = [\n                lightSetup.getAmbientColor()\n            ].concat(\n                lightSetup.directionalLights.map(\n                    light => `max(dot(viewNormal, ${light.getDirection(geometry.viewMatrix, vViewPosition)}), 0.0) * ${light.getColor()}`));\n\n            src.push(`vec4 fragColor = vec4(${lightComponents.join(\" + \")}, 1) * ${sliceColorOr(vColor)};`);\n            src.push(`${outColor} = ${sao ? `vec4(fragColor.rgb * ${sao.getAmbient(gl_FragCoord)}, fragColor.a)` : \"fragColor\"};`);\n        }\n    };\n};\n\nconst OcclusionProgram = function(programVariables, logarithmicDepthBufferEnabled) {\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        programName: \"Occlusion\",\n        // Logarithmic depth buffer involves an accuracy tradeoff, sacrificing\n        // accuracy at close range to improve accuracy at long range. This can\n        // mess up accuracy for occlusion tests, so we'll disable for now.\n        getLogDepth: false  ,\n        renderPassFlag: 0,  // COLOR_OPAQUE // Only opaque objects can be occluders\n        appendFragmentOutputs: (src) => src.push(`${outColor} = vec4(0.0, 0.0, 1.0, 1.0);`) // Occluders are blue\n    };\n};\n\nconst PBRProgram = function(programVariables, geometry, scene, lightSetup, sao) {\n    const setup2dTexture = (name, isSrgb, getTexture) => {\n        return setupTexture(programVariables, \"sampler2D\", name, isSrgb ? sRGBEncoding : LinearEncoding, (set, state) => {\n            const texture = getTexture(state.layerTextureSet);\n            texture && set(texture.texture);\n        });\n    };\n\n    const attributes = geometry.attributes;\n    const getIrradiance = lightSetup.getIrradiance;\n\n    const colorMap         = setup2dTexture(\"uColorMap\",         true,  textureSet => textureSet.colorTexture);\n    const metallicRoughMap = setup2dTexture(\"uMetallicRoughMap\", false, textureSet => textureSet.metallicRoughnessTexture);\n    const emissiveMap      = setup2dTexture(\"uEmissiveMap\",      true,  textureSet => textureSet.emissiveTexture);\n    const normalMap        = setup2dTexture(\"uNormalMap\",        false, textureSet => textureSet.normalsTexture);\n    const aOMap            = setup2dTexture(\"uAOMap\",            false, textureSet => textureSet.occlusionTexture);\n\n    const vViewPosition      = programVariables.createVarying(\"vec3\", \"vViewPosition\",      () => `${attributes.position.view}.xyz`);\n    const vViewNormal        = programVariables.createVarying(\"vec3\", \"vViewNormal\",        () => attributes.normal.view);\n    const vColor             = programVariables.createVarying(\"vec4\", \"vColor\",             () => attributes.color);\n    const vUV                = programVariables.createVarying(\"vec2\", \"vUV\",                () => attributes.uv);\n    const vMetallicRoughness = programVariables.createVarying(\"vec2\", \"vMetallicRoughness\", () => attributes.metallicRoughness);\n    const vWorldNormal       = programVariables.createVarying(\"vec3\", \"vWorldNormal\",       () => `${attributes.normal.world}.xyz`);\n\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n\n    const saturate = programVariables.createFragmentDefinition(\n        \"saturate\",\n        (name, src) => src.push(`float ${name}(const in float a) { return clamp(a, 0.0, 1.0); }`));\n\n    const BRDF_Specular_GGX = programVariables.createFragmentDefinition(\n        \"BRDF_Specular_GGX\",\n        (name, src) => {\n            src.push(\"vec3 F_Schlick(const in vec3 specularColor, const in float dotLH) {\");\n            src.push(\"   float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\");\n            src.push(\"   return ( 1.0 - specularColor ) * fresnel + specularColor;\");\n            src.push(\"}\");\n\n            src.push(\"float G_GGX_Smith(const in float alpha, const in float dotNL, const in float dotNV) {\");\n            src.push(\"   float a2 = ( alpha * alpha );\");\n            src.push(\"   float gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * ( dotNL * dotNL ) );\");\n            src.push(\"   float gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * ( dotNV * dotNV ) );\");\n            src.push(\"   return 1.0 / ( gl * gv );\");\n            src.push(\"}\");\n\n            src.push(\"float G_GGX_SmithCorrelated(const in float alpha, const in float dotNL, const in float dotNV) {\");\n            src.push(\"   float a2 = ( alpha * alpha );\");\n            src.push(\"   float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * ( dotNV * dotNV ) );\");\n            src.push(\"   float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * ( dotNL * dotNL ) );\");\n            src.push(\"   return 0.5 / max( gv + gl, 1e-6 );\");\n            src.push(\"}\");\n\n            src.push(\"float D_GGX(const in float alpha, const in float dotNH) {\");\n            src.push(\"   float a2 = ( alpha * alpha );\");\n            src.push(\"   float denom = ( dotNH * dotNH) * ( a2 - 1.0 ) + 1.0;\");\n            src.push(\"   return 0.31830988618 * a2 / ( denom * denom);\"); // 1/PI\n            src.push(\"}\");\n\n            src.push(`vec3 ${name}(const in vec3 incidentLightDirection, const in vec3 viewNormal, const in vec3 viewEyeDir, const in vec3 specularColor, const in float roughness) {`);\n            src.push(\"   float alpha = ( roughness * roughness );\");\n            src.push(\"   vec3 halfDir = normalize( incidentLightDirection + viewEyeDir );\");\n            src.push(`   float dotNL = ${saturate}( dot( viewNormal, incidentLightDirection ) );`);\n            src.push(`   float dotNV = ${saturate}( dot( viewNormal, viewEyeDir ) );`);\n            src.push(`   float dotNH = ${saturate}( dot( viewNormal, halfDir ) );`);\n            src.push(`   float dotLH = ${saturate}( dot( incidentLightDirection, halfDir ) );`);\n            src.push(\"   vec3  F = F_Schlick( specularColor, dotLH );\");\n            src.push(\"   float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\");\n            src.push(\"   float D = D_GGX( alpha, dotNH );\");\n            src.push(\"   return F * (G * D);\");\n            src.push(\"}\");\n        });\n\n    const BRDF_Specular_GGX_Environment = programVariables.createFragmentDefinition(\n        \"BRDF_Specular_GGX_Environment\",\n        (name, src) => {\n            src.push(`vec3 ${name}(const in vec3 viewNormal, const in vec3 viewEyeDir, const in vec3 specularColor, const in float roughness) {`);\n            src.push(`   float dotNV = ${saturate}(dot(viewNormal, viewEyeDir));`);\n            src.push(\"   const vec4 c0 = vec4( -1, -0.0275, -0.572,  0.022);\");\n            src.push(\"   const vec4 c1 = vec4(  1,  0.0425,   1.04, -0.04);\");\n            src.push(\"   vec4 r = roughness * c0 + c1;\");\n            src.push(\"   float a004 = min(r.x * r.x, exp2(-9.28 * dotNV)) * r.x + r.y;\");\n            src.push(\"   vec2 AB    = vec2(-1.04, 1.04) * a004 + r.zw;\");\n            src.push(\"   return specularColor * AB.x + AB.y;\");\n            src.push(\"}\");\n        });\n\n    const perturbNormal2Arb = programVariables.createFragmentDefinition(\n        \"perturbNormal2Arb\",\n        (name, src) => {\n            src.push(`vec3 ${name}( vec3 eye_pos, vec3 surf_norm, vec2 uv, vec4 texel ) {`);\n            src.push(\"      if (texel.r == 0.0 && texel.g == 0.0 && texel.b == 0.0) {\");\n            src.push(\"             return surf_norm;\");\n            src.push(\"      }\");\n            src.push(\"      vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\");\n            src.push(\"      vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\");\n            src.push(\"      vec2 st0 = dFdx( uv.st );\");\n            src.push(\"      vec2 st1 = dFdy( uv.st );\");\n            src.push(\"      vec3 S = normalize( q0 * st1.t - q1 * st0.t );\");\n            src.push(\"      vec3 T = normalize( -q0 * st1.s + q1 * st0.s );\");\n            src.push(\"      vec3 N = normalize( surf_norm );\");\n            src.push(\"      vec3 mapN = texel.xyz * 2.0 - 1.0;\");\n            src.push(\"      mat3 tsn = mat3( S, T, N );\");\n            //     src.push(\"      mapN *= 3.0;\");\n            src.push(\"      return normalize( tsn * mapN );\");\n            src.push(\"}\");\n        });\n\n    return {\n        programName: \"PBR\",\n        getHash: () => [lightSetup.getHash(), sao ? \"sao\" : \"nosao\", !!scene.gammaOutput],\n        getLogDepth: scene.logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n        renderPassFlag: 0,      // COLOR_OPAQUE | COLOR_TRANSPARENT\n        clippingCaps: scene._sectionPlanesState.clippingCaps && outColor,\n        incrementDrawState: true,\n        appendFragmentOutputs: (src, getGammaOutputExpression, gl_FragCoord) => {\n            src.push(\"const float PI = 3.14159265359;\");\n            src.push(\"vec3 reflDiff = vec3(0.0);\");\n            src.push(\"vec3 reflSpec = vec3(0.0);\");\n\n            src.push(`vec3 rgb = ${vColor}.rgb;`);\n            src.push(`float opacity = ${vColor}.a;`);\n\n            src.push(\"vec3  baseColor  = rgb;\");\n            src.push(\"float specularF0 = 1.0;\");\n            src.push(`float metallic   = float(${vMetallicRoughness}.r) / 255.0;`);\n            src.push(`float roughness  = float(${vMetallicRoughness}.g) / 255.0;`);\n            src.push(\"float dielectricSpecular = 0.16 * specularF0 * specularF0;\");\n\n            src.push(`vec4 colorTexel = ${colorMap(vUV)};`);\n            src.push(\"baseColor *= colorTexel.rgb;\");\n            // src.push(\"opacity *=/= colorTexel.a;\"); // batching had \"*=\", instancing had \"=\"\n\n            src.push(`vec3 metalRoughTexel = ${metallicRoughMap(vUV)}.rgb;`);\n            src.push(\"metallic *= metalRoughTexel.b;\");\n            src.push(\"roughness *= metalRoughTexel.g;\");\n\n            src.push(\"vec3 diffuseColor       = baseColor * (1.0 - dielectricSpecular) * (1.0 - metallic);\");\n            src.push(\"float specularRoughness = clamp(roughness, 0.04, 1.0);\");\n            src.push(\"vec3 specularColor      = mix(vec3(dielectricSpecular), baseColor, metallic);\");\n\n            src.push(`vec3 viewNormal = -${perturbNormal2Arb}(${vViewPosition}, normalize(${vViewNormal}), ${vUV}, ${normalMap(vUV)});`);\n            src.push(`vec3 viewEyeDir = normalize(${vViewPosition});`);\n\n            getIrradiance && src.push(`reflDiff += ${getIrradiance(`normalize(${vWorldNormal})`)};`);\n\n            if (lightSetup.getReflection) {\n                const reflectVec = `reflect(viewEyeDir, viewNormal)`;\n                const viewReflectVec = `normalize((vec4(${reflectVec}, 0.0) * ${geometry.viewMatrix}).xyz)`;\n                const maxMIPLevel = \"8.0\";\n                const blinnExpFromRoughness = `(2.0 / pow(specularRoughness + 0.0001, 2.0) - 2.0)`;\n                const desiredMIPLevel = `${maxMIPLevel} - 0.79248 - 0.5 * log2(pow(${blinnExpFromRoughness}, 2.0) + 1.0)`;\n                const specularMIPLevel = `0.5 * clamp(${desiredMIPLevel}, 0.0, ${maxMIPLevel})`; // TODO: a random factor - fix this\n                const radiance = lightSetup.getReflection(viewReflectVec, specularMIPLevel);\n                const specularBRDFContrib = `${BRDF_Specular_GGX_Environment}(viewNormal, viewEyeDir, specularColor, specularRoughness)`;\n                src.push(`reflSpec += ${radiance} * ${specularBRDFContrib};`);\n            }\n\n            lightSetup.directionalLights.forEach((light, i) => {\n                src.push(`vec3 lightDirection${i} = -${light.getDirection(geometry.viewMatrix, vViewPosition)};`); // This \"-\" might be wrong, but it used to be like that\n                const dotNL = `${saturate}(dot(viewNormal, lightDirection${i}))`;\n                src.push(`vec3 irradiance${i} = ${dotNL} * ${light.getColor()};`);\n                src.push(`reflDiff += irradiance${i};`);\n                src.push(`reflSpec += irradiance${i} * PI * ${BRDF_Specular_GGX}(lightDirection${i}, viewNormal, viewEyeDir, specularColor, specularRoughness);`);\n            });\n\n            src.push(`vec3 emissiveColor = ${emissiveMap(vUV)}.rgb;`); // TODO: correct gamma function\n            src.push(`float aoFactor = ${aOMap(vUV)}.r;`);\n\n            const ambient = `${lightSetup.getAmbientColor()} * baseColor * opacity * rgb`;\n            src.push(`vec3 outgoingLight = emissiveColor + reflDiff * diffuseColor + reflSpec + ${ambient};`);\n\n            src.push(`${outColor} = vec4(outgoingLight * aoFactor${sao ? ` * ${sao.getAmbient(gl_FragCoord)}` : \"\"}, opacity);`);\n\n            getGammaOutputExpression && src.push(`${outColor} = ${getGammaOutputExpression(outColor)};`);\n        }\n    };\n};\n\nconst PickDepthProgram = function(programVariables, geometry, logarithmicDepthBufferEnabled) {\n    const far  = programVariables.createUniform(\"float\", \"far\",  (set, state) => set(state.legacyFrameCtx.viewParams.far));\n    const near = programVariables.createUniform(\"float\", \"near\", (set, state) => set(state.legacyFrameCtx.viewParams.near));\n    const vViewPosition = programVariables.createVarying(\"vec3\", \"vViewPosition\", () => `${geometry.attributes.position.view}.xyz`);\n    const outPackedDepth = programVariables.createOutput(\"vec4\", \"outPackedDepth\");\n    const packDepth = programVariables.createFragmentDefinition(\n        \"packDepth\",\n        (name, src) => {\n            src.push(`vec4 ${name}(const in float depth) {`);\n            src.push(\"  const vec4 bitShift = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);\");\n            src.push(\"  const vec4 bitMask  = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);\");\n            src.push(\"  vec4 res = fract(depth * bitShift);\");\n            src.push(\"  res -= res.xxyz * bitMask;\");\n            src.push(\"  return res;\");\n            src.push(\"}\");\n        });\n\n    return {\n        programName: \"PickDepth\",\n        getLogDepth: logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n        renderPassFlag: 3,  // PICK\n        incPointSizeBy10: true,\n        appendFragmentOutputs: (src) => {\n            src.push(`float zNormalizedDepth = abs((${near} + ${vViewPosition}.z) / (${far} - ${near}));`);\n            // isn't zNormalizedDepth the same as gl_FragDepth or gl_FragCoord.z?\n            src.push(`${outPackedDepth} = ${packDepth}(zNormalizedDepth);`); // Must be linear depth\n            // try: src.push(\"    outPackedDepth = vec4(zNormalizedDepth, fract(zNormalizedDepth * vec3(256.0, 256.0*256.0, 256.0*256.0*256.0)));\");\n        }\n    };\n};\n\nconst PickMeshProgram = function(programVariables, geometry, logarithmicDepthBufferEnabled) {\n    const vPickColor = programVariables.createVarying(\"vec4\", \"vPickColor\", () => `${geometry.attributes.pickColor} / 255.0`);\n    const outPickColor = programVariables.createOutput(\"vec4\", \"outPickColor\");\n    return {\n        programName: \"PickMesh\",\n        getLogDepth: logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n        renderPassFlag: 3,  // PICK\n        incPointSizeBy10: true,\n        dontCullOnAlphaZero: true, // should be false?\n        appendFragmentOutputs: (src) => src.push(`${outPickColor} = ${vPickColor};`)\n    };\n};\n\nconst PickNormalsProgram = function(programVariables, geometry, logarithmicDepthBufferEnabled, isFlat) {\n    const vWorldPosition = programVariables.createVarying(\"vec3\", \"vWorldPosition\", () => `${geometry.attributes.position.world}.xyz`);\n    const vWorldNormal = programVariables.createVarying(\"vec3\", \"vWorldNormal\", () => geometry.attributes.normal.world);\n    const outNormal = programVariables.createOutput(\"highp ivec4\", \"outNormal\");\n    return {\n        programName: isFlat ? \"PickNormalsFlat\" : \"PickNormals\",\n        getLogDepth: logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n        renderPassFlag: 3,  // PICK\n        appendFragmentOutputs: (src) => {\n            const worldNormal = (isFlat\n                                 ? `normalize(cross(dFdx(${vWorldPosition}), dFdy(${vWorldPosition})))`\n                                 : vWorldNormal);\n            src.push(`${outNormal} = ivec4(${worldNormal} * float(${math.MAX_INT}), 1.0);`);\n        }\n    };\n};\n\nconst ShadowProgram = function(programVariables, logarithmicDepthBufferEnabled) {\n    // VBOBatchingPointsShadowRenderer has been implemented by 14e973df6268369b00baef60e468939e062ac320,\n    // but never used (and probably not maintained), as opposed to VBOInstancingPointsShadowRenderer in the same commit\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    const encodeFloat = programVariables.createFragmentDefinition(\n        \"encodeFloat\",\n        (name, src) => {\n            src.push(`vec4 ${name}(const in float v) {`);\n            src.push(\"  const vec4 bitShift = vec4(256 * 256 * 256, 256 * 256, 256, 1.0);\");\n            src.push(\"  const vec4 bitMask = vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);\");\n            src.push(\"  vec4 comp = fract(v * bitShift);\");\n            src.push(\"  comp -= comp.xxyz * bitMask;\");\n            src.push(\"  return comp;\");\n            src.push(\"}\");\n        });\n    return {\n        programName: \"Shadow\",\n        getLogDepth: logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n        renderPassFlag: 0,\n        isShadowProgram: true,\n        appendFragmentOutputs: (src, getGammaOutputExpression, gl_FragCoord) => src.push(`${outColor} = ${encodeFloat}(${gl_FragCoord}.z);`)\n    };\n};\n\nconst SilhouetteProgram = function(programVariables, geometry, logarithmicDepthBufferEnabled, isPointsOrLines) {\n    const silhouetteColor = programVariables.createUniform(\"vec4\", \"silhouetteColor\", (set, state) => set(state.legacyFrameCtx.programColor));\n    const vAlpha = programVariables.createVarying(\"float\", \"vAlpha\", () => `${geometry.attributes.color}.a`);\n    const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n    return {\n        programName: \"Silhouette\",\n        getLogDepth: logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n        renderPassFlag: 1,  // SILHOUETTE_HIGHLIGHTED | SILHOUETTE_SELECTED | SILHOUETTE_XRAYED\n        appendFragmentOutputs: (src, getGammaOutputExpression, gl_FragCoord, sliceColorOr) => {\n            src.push(`${outColor} = ${isPointsOrLines\n                                      ? silhouetteColor\n                                      : sliceColorOr(`vec4(${silhouetteColor}.rgb, min(${silhouetteColor}.a, ${vAlpha}))`)};`);\n        }\n    };\n};\n\nconst SnapProgram = function(programVariables, geometry, isSnapInit, isPoints) {\n    const layerNumber      = programVariables.createUniform(\"int\",  \"layerNumber\",      (set, state) => set(state.legacyFrameCtx.snapPickLayerParams.length));\n    const coordinateScaler = programVariables.createUniform(\"vec3\", \"coordinateScaler\", (set, state) => set(state.legacyFrameCtx.snapPickCoordinateScale));\n\n    const vWorldPosition = programVariables.createVarying(\"vec3\", \"vWorldPosition\", () => `${geometry.attributes.position.world}.xyz`);\n    const vPickColor = programVariables.createVarying(\"vec4\", \"vPickColor\", () => geometry.attributes.pickColor); // Using `flat` causes an instability - see XEOK-385 and XEOK-401\n\n    const outCoords    = programVariables.createOutput(\"highp ivec4\", \"outCoords\", 0);\n    const outNormal    = programVariables.createOutput(\"highp ivec4\", \"outNormal\", 1);\n    const outPickColor = programVariables.createOutput(\"lowp uvec4\", \"outPickColor\", 2);\n\n    return {\n        programName: isSnapInit ? \"SnapInit\" : \"Snap\",\n        // Improves occlusion accuracy at distance\n        getLogDepth: (vFragDepth => (isSnapInit ? `${vFragDepth} + length(vec2(dFdx(${vFragDepth}), dFdy(${vFragDepth})))` : vFragDepth)),\n        renderPassFlag: 3,  // PICK\n        vertexCullX: (!isSnapInit) && \"2.0\",\n        dontCullOnAlphaZero: !isSnapInit,\n        appendFragmentOutputs: (src) => {\n            src.push(`${outCoords} = ivec4(${vWorldPosition} * ${coordinateScaler}.xyz, ${isSnapInit ? \"-\" : \"\"}${layerNumber});`);\n            if (isSnapInit) {\n                src.push(`${outNormal} = ${isPoints ? \"ivec4(1.0)\" : `ivec4(normalize(cross(dFdx(${vWorldPosition}), dFdy(${vWorldPosition}))) * float(${math.MAX_INT}), 1.0)`};`);\n                src.push(`${outPickColor} = uvec4(${vPickColor});`);\n            }\n        }\n    };\n};\n\nconst tempVec2 = math.vec2();\nconst tempVec3$6 = math.vec3();\nconst tempVec4$1 = math.vec4();\nconst tempMat4$2 = math.mat4();\nconst vec3zero = math.vec3([0,0,0]);\n\nconst RENDER_PASSES = {\n    // Skipped - suppress rendering\n    NOT_RENDERED: 0,\n\n    // Normal rendering - mutually exclusive modes\n    COLOR_OPAQUE: 1,\n    COLOR_TRANSPARENT: 2,\n\n    // Emphasis silhouette rendering - mutually exclusive modes\n    SILHOUETTE_HIGHLIGHTED: 3,\n    SILHOUETTE_SELECTED: 4,\n    SILHOUETTE_XRAYED: 5,\n\n    // Edges rendering - mutually exclusive modes\n    EDGES_COLOR_OPAQUE: 6,\n    EDGES_COLOR_TRANSPARENT: 7,\n    EDGES_HIGHLIGHTED: 8,\n    EDGES_SELECTED: 9,\n    EDGES_XRAYED: 10,\n\n    // Picking\n    PICK: 11\n};\n\nconst safeInvVec3 = v => [ math.safeInv(v[0]), math.safeInv(v[1]), math.safeInv(v[2]) ];\n\nconst isPerspectiveMatrix = (m) => `(${m}[2][3] == - 1.0)`;\n\nconst getColSilhEdgePickFlags = (flags, transparent, hasEdges, scene, dst) => {\n    const visible     = !!(flags & ENTITY_FLAGS.VISIBLE);\n    const xrayed      = !!(flags & ENTITY_FLAGS.XRAYED);\n    const highlighted = !!(flags & ENTITY_FLAGS.HIGHLIGHTED);\n    const selected    = !!(flags & ENTITY_FLAGS.SELECTED);\n    const edges       = !!(flags & ENTITY_FLAGS.EDGES);\n    const pickable    = !!(flags & ENTITY_FLAGS.PICKABLE);\n    const culled      = !!(flags & ENTITY_FLAGS.CULLED);\n\n    let colorFlag;\n    if (!visible || culled || xrayed\n        || (highlighted && !scene.highlightMaterial.glowThrough)\n        || (selected && !scene.selectedMaterial.glowThrough)) {\n        colorFlag = RENDER_PASSES.NOT_RENDERED;\n    } else {\n        if (transparent) {\n            colorFlag = RENDER_PASSES.COLOR_TRANSPARENT;\n        } else {\n            colorFlag = RENDER_PASSES.COLOR_OPAQUE;\n        }\n    }\n\n    let silhouetteFlag;\n    if (!visible || culled) {\n        silhouetteFlag = RENDER_PASSES.NOT_RENDERED;\n    } else if (selected) {\n        silhouetteFlag = RENDER_PASSES.SILHOUETTE_SELECTED;\n    } else if (highlighted) {\n        silhouetteFlag = RENDER_PASSES.SILHOUETTE_HIGHLIGHTED;\n    } else if (xrayed) {\n        silhouetteFlag = RENDER_PASSES.SILHOUETTE_XRAYED;\n    } else {\n        silhouetteFlag = RENDER_PASSES.NOT_RENDERED;\n    }\n\n    let edgeFlag = 0;\n    if ((!hasEdges) || (!visible) || culled) {\n        edgeFlag = RENDER_PASSES.NOT_RENDERED;\n    } else if (selected) {\n        edgeFlag = RENDER_PASSES.EDGES_SELECTED;\n    } else if (highlighted) {\n        edgeFlag = RENDER_PASSES.EDGES_HIGHLIGHTED;\n    } else if (xrayed) {\n        edgeFlag = RENDER_PASSES.EDGES_XRAYED;\n    } else if (edges) {\n        if (transparent) {\n            edgeFlag = RENDER_PASSES.EDGES_COLOR_TRANSPARENT;\n        } else {\n            edgeFlag = RENDER_PASSES.EDGES_COLOR_OPAQUE;\n        }\n    } else {\n        edgeFlag = RENDER_PASSES.NOT_RENDERED;\n    }\n\n    const pickFlag = (visible && !culled && pickable) ? RENDER_PASSES.PICK : RENDER_PASSES.NOT_RENDERED;\n\n    dst[0] = colorFlag;\n    dst[1] = silhouetteFlag;\n    dst[2] = edgeFlag;\n    dst[3] = pickFlag;\n};\n\nconst getRenderers = (function() {\n    const cachedRenderers = { };\n\n    return function(scene, layerType, primitive, saoEnabled, pbrSupported, colorTextureSupported, surfaceHasNormals, makeRenderingAttributes) {\n        const primKey = ((primitive === \"points\") || (primitive === \"lines\")) ? primitive : \"triangles\";\n        const cacheKey = [ layerType, primKey, !!saoEnabled, !!pbrSupported, !!colorTextureSupported, !!surfaceHasNormals ].join(\":\");\n        if (! (cacheKey in cachedRenderers)) {\n            cachedRenderers[cacheKey] = { };\n        }\n        const cache = cachedRenderers[cacheKey];\n        const sceneId = scene.id;\n        if (! (sceneId in cache)) {\n            const gl = scene.canvas.gl;\n            const wrapRenderer = function(createProgramSetup, subGeometry, isEager) {\n                const instantiate = function() {\n                    const programVariablesState = createProgramVariablesState();\n                    const programVariables = programVariablesState.programVariables;\n                    const renderingAttributes = makeRenderingAttributes(programVariables, subGeometry);\n                    return createProgramSetup(\n                        programVariables,\n                        renderingAttributes.geometryParameters,\n                        function(programSetup, usePickClipPos) {\n                            const pointsMaterial     = scene.pointsMaterial;\n                            const setupPoints        = (primitive === \"points\") && (! subGeometry);\n\n                            const getHash = () => [ scene._sectionPlanesState.getHash() ].concat(setupPoints ? [ pointsMaterial.hash ] : [ ]).concat(programSetup.getHash ? programSetup.getHash() : [ ]).join(\";\");\n                            const hash = getHash();\n                            const getValid = () => hash === getHash();\n\n                            const geometryParameters     = renderingAttributes.geometryParameters;\n                            const incrementDrawState     = programSetup.incrementDrawState;\n                            const isShadowProgram        = programSetup.isShadowProgram;\n                            const attributes             = geometryParameters.attributes;\n                            const worldPositionAttribute = attributes.position.world;\n                            const clipPos                = \"clipPos\";\n\n                            const [ program, errors ] = programVariablesState.buildProgram(\n                                gl,\n                                layerType + \" \" + primitive + \" \" + programSetup.programName,\n                                {\n                                    appendFragmentOutputs:          programSetup.appendFragmentOutputs,\n                                    cleanerEdges:                   programSetup.cleanerEdges,\n                                    clipPos:                        clipPos,\n                                    clippableTest:                  renderingAttributes.clippableTest,\n                                    clippingCaps:                   programSetup.clippingCaps,\n                                    crossSections:                  scene.crossSections,\n                                    discardPoints:                  setupPoints && pointsMaterial.roundPoints,\n                                    getGammaFactor:                 scene.gammaOutput && (() => scene.gammaFactor),\n                                    getLogDepth:                    programSetup.getLogDepth,\n                                    getPointSize:                   (function() {\n                                        const addends = [ ];\n                                        if (setupPoints) {\n                                            const pointSize = programVariables.createUniform(\"float\", \"pointSize\", (set) => set(pointsMaterial.pointSize));\n                                            if (pointsMaterial.perspectivePoints) {\n                                                const nearPlaneHeight = programVariables.createUniform(\"float\", \"nearPlaneHeight\", (set, state) => set(state.legacyFrameCtx.nearPlaneHeight));\n                                                const minVal = `${Math.floor(pointsMaterial.minPerspectivePointSize)}.0`;\n                                                const maxVal = `${Math.floor(pointsMaterial.maxPerspectivePointSize)}.0`;\n                                                addends.push(`clamp((${nearPlaneHeight} * ${pointSize}) / gl_Position.w, ${minVal}, ${maxVal})`);\n                                            } else {\n                                                addends.push(pointSize);\n                                            }\n                                        } else if (subGeometry && subGeometry.vertices) {\n                                            addends.push(\"1.0\");\n                                        }\n                                        programSetup.incPointSizeBy10 && (primitive === \"points\") && addends.push(\"10.0\");\n                                        return (addends.length > 0) && (() => addends.join(\" + \"));\n                                    })(),\n                                    getVertexData:                  () => {\n                                        const colorA = attributes.color;\n                                        const flag = attributes.flags[programSetup.renderPassFlag];\n                                        const renderPass = programVariables.createUniform(\"int\", \"renderPass\", (set, state) => set(state.renderPass));\n                                        const flagTest = (isShadowProgram\n                                                          ? `(${flag} <= 0) || (${colorA}.a < 1.0)`\n                                                          : `${flag} != ${renderPass}`);\n\n                                        const afterFlagsColorLines = [\n                                            `if (${flagTest}) {`,\n                                            `   gl_Position = vec4(${programSetup.vertexCullX || 0.0}, 0.0, 0.0, 0.0);`, // Cull vertex\n                                            \"   return;\",\n                                            \"}\"\n                                        ].concat(\n                                            ((! renderingAttributes.dontCullOnAlphaZero) && (! programSetup.dontCullOnAlphaZero))\n                                                ? [\n                                                    `if (${colorA}.a == 0.0) {`,\n                                                    \"   gl_Position = vec4(3.0, 3.0, 3.0, 1.0);\", // Cull vertex\n                                                    \"   return;\",\n                                                    \"}\"\n                                                ]\n                                                : [ ]\n                                        ).concat(\n                                            (programSetup.filterIntensityRange && (primitive === \"points\") && pointsMaterial.filterIntensity)\n                                                ? (function () {\n                                                    const intensityRange  = programVariables.createUniform(\"vec2\", \"intensityRange\", (set) => {\n                                                        tempVec2[0] = pointsMaterial.minIntensity;\n                                                        tempVec2[1] = pointsMaterial.maxIntensity;\n                                                        set(tempVec2);\n                                                    });\n                                                    return [\n                                                        `if ((${colorA}.a < ${intensityRange}[0]) || (${colorA}.a > ${intensityRange}[1])) {`,\n                                                        \"   gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\", // Cull vertex\n                                                        \"   return;\",\n                                                        \"}\"\n                                                    ];\n                                                })()\n                                            : [ ]);\n\n                                        const vertexData = [ ];\n                                        renderingAttributes.ensureColorAndFlagAvailable && renderingAttributes.ensureColorAndFlagAvailable(vertexData);\n                                        afterFlagsColorLines.forEach(line => vertexData.push(line));\n                                        renderingAttributes.appendVertexData(vertexData);\n                                        const viewPosition = geometryParameters.attributes.position.view;\n                                        vertexData.push(`vec4 ${viewPosition} = ${geometryParameters.viewMatrix} * ${worldPositionAttribute};`);\n                                        vertexData.push(`vec4 ${clipPos} = ${geometryParameters.projMatrix} * ${viewPosition};`);\n                                        return vertexData;\n                                    },\n                                    projMatrix:                     geometryParameters.projMatrix,\n                                    sectionPlanesState:             scene._sectionPlanesState,\n                                    testPerspectiveForGl_FragDepth: ((primitive !== \"points\") && (primitive !== \"lines\")) || subGeometry,\n                                    usePickClipPos:                 usePickClipPos,\n                                    worldPositionAttribute:         worldPositionAttribute\n                                });\n\n                            if (errors) {\n                                console.error(errors);\n                                return {\n                                    getValid:  getValid,\n                                    destroy:   () => { },\n                                    drawLayer: (frameCtx, layer, renderPass) => { }\n                                };\n                            } else {\n                                return {\n                                    getValid:  getValid,\n                                    destroy:   () => program.destroy(),\n                                    drawLayer: (frameCtx, layer, renderPass) => {\n                                        if (frameCtx.lastProgramId !== program.id) {\n                                            frameCtx.lastProgramId = program.id;\n                                            program.bind();\n                                        }\n\n                                        const origin = layer.origin;\n                                        const model = layer.model;\n                                        const viewParams = frameCtx.viewParams;\n                                        const rtcOrigin = tempVec3$6;\n                                        math.transformPoint3(model.matrix, origin, rtcOrigin);\n\n                                        const viewMatrix = viewParams.viewMatrix;\n                                        const projMatrix = viewParams.projMatrix;\n\n                                        if (frameCtx.snapPickOrigin) {\n                                            frameCtx.snapPickOrigin[0] = rtcOrigin[0];\n                                            frameCtx.snapPickOrigin[1] = rtcOrigin[1];\n                                            frameCtx.snapPickOrigin[2] = rtcOrigin[2];\n                                        }\n\n                                        const state = {\n                                            legacyFrameCtx: frameCtx,\n                                            layerTextureSet: layer.layerTextureSet,\n                                            mesh: {\n                                                layerIndex:  layer.layerIndex,\n                                                origin:      rtcOrigin,\n                                                renderFlags: { sectionPlanesActivePerLayer: model.renderFlags.sectionPlanesActivePerLayer },\n                                            },\n                                            renderPass:     renderPass,\n                                            view: {\n                                                eye:              viewParams.eye,\n                                                far:              viewParams.far,\n                                                projMatrix:       projMatrix,\n                                                viewMatrix:       math.compareVec3(rtcOrigin, vec3zero) ? viewMatrix : createRTCViewMat(viewMatrix, rtcOrigin, tempMat4$2),\n                                                viewNormalMatrix: viewParams.viewNormalMatrix\n                                            }\n                                        };\n\n                                        program.inputSetters.setUniforms(frameCtx, state);\n\n                                        layer.drawCalls[subGeometry ? (subGeometry.vertices ? \"drawVertices\" : \"drawEdges\") : \"drawSurface\"](\n                                            program.inputSetters.attributesHash,\n                                            renderingAttributes.layerTypeInputs,\n                                            {\n                                                projMatrix:       projMatrix,\n                                                viewMatrix:       math.compareVec3(rtcOrigin, vec3zero) ? viewMatrix : createRTCViewMat(viewMatrix, rtcOrigin, tempMat4$2),\n                                                viewNormalMatrix: viewParams.viewNormalMatrix,\n                                                eye:              viewParams.eye\n                                            });\n\n                                        if (incrementDrawState) {\n                                            frameCtx.drawElements++;\n                                        }\n                                    }\n                                };\n                            }\n                        });\n                };\n                let renderer = isEager && instantiate();\n                return {\n                    drawLayer: (frameCtx, layer, renderPass) => {\n                        if (! renderer) {\n                            renderer = instantiate();\n                        }\n                        renderer.drawLayer(frameCtx, layer, renderPass);\n                    },\n                    revalidate: force => {\n                        if (renderer && (force || (! renderer.getValid()))) {\n                            renderer.destroy();\n                            renderer = isEager && instantiate();\n                        }\n                    }\n                };\n            };\n\n            // Pre-initialize certain renderers that would otherwise be lazy-initialised on user interaction,\n            // such as picking or emphasis, so that there is no delay when user first begins interacting with the viewer.\n            const eager = (createProgramSetup, subGeometry) => wrapRenderer(createProgramSetup, subGeometry, true);\n            const lazy  = (createProgramSetup, subGeometry) => wrapRenderer(createProgramSetup, subGeometry, false);\n\n            const makeColorProgram = (vars, geo, lights, sao) => ColorProgram(vars, geo, scene.logarithmicDepthBufferEnabled, lights, sao, primitive);\n\n            const makePickDepthProgram   = (vars, geo, c) => c(PickDepthProgram(vars, geo, scene.logarithmicDepthBufferEnabled), true);\n            const makePickMeshProgram    = (vars, geo, c) => c(PickMeshProgram(vars, geo, scene.logarithmicDepthBufferEnabled), true);\n            const makePickNormalsProgram = (vars, geo, c, isFlat) => c(PickNormalsProgram(vars, geo, scene.logarithmicDepthBufferEnabled, isFlat), true);\n\n            const makeSnapProgram = (vars, geo, c, isSnapInit, isPoints) => c(SnapProgram(vars, geo, isSnapInit, isPoints), true);\n\n            if (primitive === \"points\") {\n                cache[sceneId] = {\n                    colorRenderers:     { \"sao-\": { \"vertex\": lazy((vars, geo, c) => c(makeColorProgram(vars, geo, null, null))) } },\n                    occlusionRenderer:  lazy((vars, geo, c) => c(OcclusionProgram(vars, scene.logarithmicDepthBufferEnabled))),\n                    pickDepthRenderer:  lazy(makePickDepthProgram),\n                    pickMeshRenderer:   lazy(makePickMeshProgram),\n                    // VBOBatchingPointsShadowRenderer has been implemented by 14e973df6268369b00baef60e468939e062ac320,\n                    // but never used (and probably not maintained), as opposed to VBOInstancingPointsShadowRenderer in the same commit\n                    // drawShadow has been nop in VBO point layers\n                    // shadowRenderer:     instancing && lazy((vars, geo, c) => c(ShadowProgram(scene.logarithmicDepthBufferEnabled))),\n                    silhouetteRenderer: lazy((vars, geo, c) => c(SilhouetteProgram(vars, geo, scene.logarithmicDepthBufferEnabled, true))),\n                    snapInitRenderer:   lazy((vars, geo, c) => makeSnapProgram(vars, geo, c, true,  true)),\n                    snapVertexRenderer: lazy((vars, geo, c) => makeSnapProgram(vars, geo, c, false, true), { vertices: true })\n                };\n            } else if (primitive === \"lines\") {\n                cache[sceneId] = {\n                    colorRenderers:     { \"sao-\": { \"vertex\": lazy((vars, geo, c) => c(makeColorProgram(vars, geo, null, null))) } },\n                    silhouetteRenderer: lazy((vars, geo, c) => c(SilhouetteProgram(vars, geo, scene.logarithmicDepthBufferEnabled, true))),\n                    snapInitRenderer:   lazy((vars, geo, c) => makeSnapProgram(vars, geo, c, true,  false)),\n                    snapEdgeRenderer:   lazy((vars, geo, c) => makeSnapProgram(vars, geo, c, false, false), { vertices: false }),\n                    snapVertexRenderer: lazy((vars, geo, c) => makeSnapProgram(vars, geo, c, false, false), { vertices: true })\n                };\n            } else {\n                cache[sceneId] = {\n                    colorRenderers: (function() {\n                        // WARNING: Changing `useMaps' to `true' for DTX might have unexpected consequences while binding textures, as the DTX texture binding mechanism doesn't rely on `frameCtx.textureUnit` the way VBO does (see setSAORenderState);\n                        const createLights = vars => createLightSetup(vars, scene._lightsState);\n                        const createSAO = vars => {\n                            const uSAOParams = vars.createUniform(\"vec4\", \"uSAOParams\", (set, state) => set(state.legacyFrameCtx.saoParams));\n                            const uOcclusionTexture = setupTexture(vars, \"sampler2D\", \"uOcclusionTexture\", LinearEncoding, (set, state) => set(state.legacyFrameCtx.occlusionTexture));\n                            return {\n                                getAmbient: (gl_FragCoord) => {\n                                    // Doing SAO blend in the main solid fill draw shader just so that edge lines can be drawn over the top\n                                    // Would be more efficient to defer this, then render lines later, using same depth buffer for Z-reject\n                                    const uv          = `${gl_FragCoord}.xy / ${uSAOParams}.xy`; // / viewportWH\n                                    const blendCutoff = `${uSAOParams}.z`;\n                                    const blendFactor = `${uSAOParams}.w`;\n                                    const unPackFactors = \"(255. / 256.) / vec4(256. * 256. * 256., 256. * 256., 256., 1.)\";\n                                    return `(smoothstep(${blendCutoff}, 1.0, dot(${uOcclusionTexture(uv)}, ${unPackFactors})) * ${blendFactor})`;\n                                }\n                            };\n                        };\n                        const saoRenderers = function(useSao) {\n                            const makeColorTextureProgram = (vars, geo, useAlphaCutoff) => ColorTextureProgram(vars, geo, scene, createLights(vars), useSao && createSAO(vars), useAlphaCutoff, scene.gammaOutput); // If gammaOutput set, then it expects that all textures and colors need to be outputted in premultiplied gamma. Default is false.\n                            return {\n                                \"PBR\": pbrSupported && lazy((vars, geo, c) => c(PBRProgram(vars, geo, scene, createLights(vars), useSao && createSAO(vars)))),\n                                \"texture\": colorTextureSupported && {\n                                    \"alphaCutoff-\": lazy((vars, geo, c) => c(makeColorTextureProgram(vars, geo, false))),\n                                    \"alphaCutoff+\": lazy((vars, geo, c) => c(makeColorTextureProgram(vars, geo, true)))\n                                },\n                                \"vertex\": (surfaceHasNormals\n                                           ? lazy((vars, geo, c) => c(makeColorProgram(vars, geo, createLights(vars), useSao && createSAO(vars))))\n                                           : lazy((vars, geo, c) => c(FlatColorProgram(vars, geo, scene.logarithmicDepthBufferEnabled, createLights(vars), useSao && createSAO(vars)))))\n                            };\n                        };\n                        return {\n                            \"sao-\": saoRenderers(false),\n                            \"sao+\": saoEnabled && saoRenderers(true)\n                        };\n                    })(),\n                    depthRenderer:           lazy((vars, geo, c) => c(DepthProgram(vars, geo, scene.logarithmicDepthBufferEnabled))),\n                    edgesRenderers: {\n                        uniform: lazy((vars, geo, c) => c(EdgesProgram(vars, geo, scene.logarithmicDepthBufferEnabled, true)),  { vertices: false }),\n                        vertex:  lazy((vars, geo, c) => c(EdgesProgram(vars, geo, scene.logarithmicDepthBufferEnabled, false)), { vertices: false })\n                    },\n                    occlusionRenderer:       lazy((vars, geo, c) => c(OcclusionProgram(vars, scene.logarithmicDepthBufferEnabled))),\n                    pickDepthRenderer:       eager(makePickDepthProgram),\n                    pickMeshRenderer:        eager(makePickMeshProgram),\n                    pickNormalsFlatRenderer: eager((vars, geo, c) => makePickNormalsProgram(vars, geo, c, true)),\n                    pickNormalsRenderer:     eager((vars, geo, c) => makePickNormalsProgram(vars, geo, c, false)),\n                    shadowRenderer:          lazy((vars, geo, c) => c(ShadowProgram(vars, scene))),\n                    silhouetteRenderer:      eager((vars, geo, c) => c(SilhouetteProgram(vars, geo, scene.logarithmicDepthBufferEnabled, false))),\n                    snapInitRenderer:        eager((vars, geo, c) => makeSnapProgram(vars, geo, c, true,  false)),\n                    snapEdgeRenderer:        eager((vars, geo, c) => makeSnapProgram(vars, geo, c, false, false), { vertices: false }),\n                    snapVertexRenderer:      eager((vars, geo, c) => makeSnapProgram(vars, geo, c, false, false), { vertices: true })\n                };\n            }\n\n            const revalidateAll = force => {\n                (function rec(obj) {\n                    if (obj.revalidate) {\n                        obj.revalidate(force);\n                    } else {\n                        Object.values(obj).forEach(v => v && rec(v));\n                    }\n                })(cache[sceneId]);\n            };\n            const compile = () => revalidateAll(false);\n            compile();\n            scene.on(\"compile\", compile);\n            scene.on(\"destroyed\", () => {\n                delete cache[sceneId];\n            });\n        }\n        return cache[sceneId];\n    };\n})();\n\nclass Layer {\n\n    constructor(model, primitive, origin) {\n\n        this.model     = model;\n        this.primitive = primitive;\n        this.origin    = origin;\n\n        this._meshes = [];\n        // The axis-aligned World-space boundary of this Layer's positions.\n        this._aabb = math.collapseAABB3();\n        this._aabbDirty = true;\n    }\n\n    finalize() {\n        if (! this._compiledPortions) {\n            this._compiledPortions = this.compilePortions();\n            this.solid = this._compiledPortions.solid;\n            this.sortId = this._compiledPortions.sortId;\n            this.layerTextureSet = this._compiledPortions.layerTextureSet;\n            this.drawCalls = this._compiledPortions.drawCalls;\n            this._renderers = this._compiledPortions.renderers;\n            this._setFlags = this._compiledPortions.setFlags;\n\n            this.setColor  = this._compiledPortions.setColor;\n            this.setMatrix = this._compiledPortions.setMatrix;\n            this.setOffset = this._compiledPortions.setOffset;\n\n            this.getEachIndex = this._compiledPortions.getEachIndex;\n            this.getEachVertex = this._compiledPortions.getEachVertex;\n            this.readGeometryData = this._compiledPortions.readGeometryData;\n            this.precisionRayPickSurface = this._compiledPortions.precisionRayPickSurface;\n\n            // These counts are used to avoid unnecessary render passes\n            this._countsByFlag = { };\n            const setupFlagCount = (entityFlag, modelCountProperty) => {\n                const cnt = {\n                    count: 0,\n                    fromFlags: (flags, onlyIncrement) => {\n                        if (flags & entityFlag) {\n                            cnt.count++;\n                            this.model[modelCountProperty]++;\n                        } else if (! onlyIncrement) {\n                            cnt.count--;\n                            this.model[modelCountProperty]--;\n                        }\n                    }\n                };\n                this._countsByFlag[entityFlag] = cnt;\n            };\n            setupFlagCount(ENTITY_FLAGS.VISIBLE,     \"numVisibleLayerPortions\");\n            setupFlagCount(ENTITY_FLAGS.CULLED,      \"numCulledLayerPortions\");\n            setupFlagCount(ENTITY_FLAGS.PICKABLE,    \"numPickableLayerPortions\");\n            setupFlagCount(ENTITY_FLAGS.CLIPPABLE,   \"numClippableLayerPortions\");\n            setupFlagCount(ENTITY_FLAGS.XRAYED,      \"numXRayedLayerPortions\");\n            setupFlagCount(ENTITY_FLAGS.HIGHLIGHTED, \"numHighlightedLayerPortions\");\n            setupFlagCount(ENTITY_FLAGS.SELECTED,    \"numSelectedLayerPortions\");\n            if (this._renderers.edgesRenderers) {\n                setupFlagCount(ENTITY_FLAGS.EDGES, \"numEdgesLayerPortions\");\n            }\n\n            // Optimize initFlags to not require Object.values call each time (adds up a lot)\n            this._countsByFlagArr = Object.values(this._countsByFlag);\n            this._numTransparentLayerPortions = 0;\n        }\n    }\n\n    aabbChanged() { this._aabbDirty = true; }\n\n    getAABB() {\n        if (this._aabbDirty) { // Per-layer AABB for best RTC accuracy\n            math.collapseAABB3(this._aabb);\n            this._meshes.forEach(m => math.expandAABB3(this._aabb, m.aabb));\n            this._aabbDirty = false;\n        }\n        return this._aabb;\n    }\n\n    __drawLayer(renderFlags, frameCtx, renderer, pass) {\n        if ((this._countsByFlag[ENTITY_FLAGS.CULLED].count < this._portions.length) && (this._countsByFlag[ENTITY_FLAGS.VISIBLE].count > 0)) {\n            const backfacePasses = (this.primitive !== \"points\") && (this.primitive !== \"lines\") && [\n                RENDER_PASSES.COLOR_OPAQUE,\n                RENDER_PASSES.COLOR_TRANSPARENT,\n                RENDER_PASSES.PICK,\n                RENDER_PASSES.SILHOUETTE_HIGHLIGHTED,\n                RENDER_PASSES.SILHOUETTE_SELECTED,\n                RENDER_PASSES.SILHOUETTE_XRAYED,\n            ];\n            if (backfacePasses && backfacePasses.includes(pass)) {\n                // _updateBackfaceCull\n                const backfaces = true; // See XCD-230\n                if (frameCtx.backfaces !== backfaces) {\n                    const gl = this.model.scene.canvas.gl;\n                    {\n                        gl.disable(gl.CULL_FACE);\n                    }\n                    frameCtx.backfaces = backfaces;\n                }\n            }\n            frameCtx.textureUnit = 0; // WIP Maybe only for (! snap)?\n            renderer.drawLayer(frameCtx, this, pass);\n        }\n    }\n\n    __setVec4FromMaterialColorAlpha(color, alpha, dst) {\n        dst[0] = color[0];\n        dst[1] = color[1];\n        dst[2] = color[2];\n        dst[3] = alpha;\n        return dst;\n    }\n\n    // ---------------------- COLOR RENDERING -----------------------------------\n\n    __drawColor(renderFlags, frameCtx, renderOpaque) {\n        if ((renderOpaque ? (this._numTransparentLayerPortions < this._portions.length) : (this._numTransparentLayerPortions > 0))\n            &&\n            (this._countsByFlag[ENTITY_FLAGS.XRAYED].count < this._portions.length)) {\n            const saoRenderer = (renderOpaque && frameCtx.withSAO && this._renderers.colorRenderers[\"sao+\"]) || this._renderers.colorRenderers[\"sao-\"];\n            const renderer = ((frameCtx.pbrEnabled && saoRenderer[\"PBR\"])\n                              ? saoRenderer[\"PBR\"]\n                              : ((frameCtx.colorTextureEnabled && saoRenderer[\"texture\"])\n                                 ? saoRenderer[\"texture\"][(this.layerTextureSet && (typeof(this.layerTextureSet.alphaCutoff) === \"number\")) ? \"alphaCutoff+\" : \"alphaCutoff-\"]\n                                 : saoRenderer[\"vertex\"]));\n            const pass = renderOpaque ? RENDER_PASSES.COLOR_OPAQUE : RENDER_PASSES.COLOR_TRANSPARENT;\n            this.__drawLayer(renderFlags, frameCtx, renderer, pass);\n        }\n    }\n\n    drawColorOpaque(renderFlags, frameCtx) {\n        this.__drawColor(renderFlags, frameCtx, true);\n    }\n\n    drawColorTransparent(renderFlags, frameCtx) {\n        this.__drawColor(renderFlags, frameCtx, false);\n    }\n\n    // ---------------------- RENDERING SAO POST EFFECT TARGETS --------------\n\n    drawDepth(renderFlags, frameCtx) {\n        // Assume whatever post-effect uses depth (eg SAO) does not apply to transparent objects\n        const renderer = this._renderers.depthRenderer;\n        if (renderer && (this._numTransparentLayerPortions < this._portions.length) && (this._countsByFlag[ENTITY_FLAGS.XRAYED].count < this._portions.length)) {\n            this.__drawLayer(renderFlags, frameCtx, renderer, RENDER_PASSES.COLOR_OPAQUE);\n        }\n    }\n\n    // ---------------------- SILHOUETTE RENDERING -----------------------------------\n\n    __drawSilhouette(renderFlags, frameCtx, material, renderPass) {\n        frameCtx.programColor = this.__setVec4FromMaterialColorAlpha(material.fillColor, material.fillAlpha, tempVec4$1);\n        this.__drawLayer(renderFlags, frameCtx, this._renderers.silhouetteRenderer, renderPass);\n    }\n\n    drawSilhouetteXRayed(renderFlags, frameCtx) {\n        if (this._countsByFlag[ENTITY_FLAGS.XRAYED].count > 0) {\n            this.__drawSilhouette(renderFlags, frameCtx, this.model.scene.xrayMaterial, RENDER_PASSES.SILHOUETTE_XRAYED);\n        }\n    }\n\n    drawSilhouetteHighlighted(renderFlags, frameCtx) {\n        if (this._countsByFlag[ENTITY_FLAGS.HIGHLIGHTED].count > 0) {\n            this.__drawSilhouette(renderFlags, frameCtx, this.model.scene.highlightMaterial, RENDER_PASSES.SILHOUETTE_HIGHLIGHTED);\n        }\n    }\n\n    drawSilhouetteSelected(renderFlags, frameCtx) {\n        if (this._countsByFlag[ENTITY_FLAGS.SELECTED].count > 0) {\n            this.__drawSilhouette(renderFlags, frameCtx, this.model.scene.selectedMaterial, RENDER_PASSES.SILHOUETTE_SELECTED);\n        }\n    }\n\n    // ---------------------- EDGES RENDERING -----------------------------------\n\n    __drawVertexEdges(renderFlags, frameCtx, renderPass) {\n        const renderer = this._renderers.edgesRenderers && this._renderers.edgesRenderers.vertex;\n        if (renderer && (this._countsByFlag[ENTITY_FLAGS.EDGES].count > 0)) {\n            this.__drawLayer(renderFlags, frameCtx, renderer, renderPass);\n        }\n    }\n\n    drawEdgesColorOpaque(renderFlags, frameCtx) {\n        if (this._compiledPortions.edgesColorOpaqueAllowed()) {\n            this.__drawVertexEdges(renderFlags, frameCtx, RENDER_PASSES.EDGES_COLOR_OPAQUE);\n        }\n    }\n\n    drawEdgesColorTransparent(renderFlags, frameCtx) {\n        if (this._numTransparentLayerPortions > 0) {\n            this.__drawVertexEdges(renderFlags, frameCtx, RENDER_PASSES.EDGES_COLOR_TRANSPARENT);\n        }\n    }\n\n    __drawUniformEdges(renderFlags, frameCtx, material, renderPass) {\n        const renderer = this._renderers.edgesRenderers && this._renderers.edgesRenderers.uniform;\n        if (renderer) {\n            frameCtx.programColor = this.__setVec4FromMaterialColorAlpha(material.edgeColor, material.edgeAlpha, tempVec4$1);\n            this.__drawLayer(renderFlags, frameCtx, renderer, renderPass);\n        }\n    }\n\n    drawEdgesHighlighted(renderFlags, frameCtx) {\n        if (this._countsByFlag[ENTITY_FLAGS.HIGHLIGHTED].count > 0) {\n            this.__drawUniformEdges(renderFlags, frameCtx, this.model.scene.highlightMaterial, RENDER_PASSES.EDGES_HIGHLIGHTED);\n        }\n    }\n\n    drawEdgesSelected(renderFlags, frameCtx) {\n        if (this._countsByFlag[ENTITY_FLAGS.SELECTED].count > 0) {\n            this.__drawUniformEdges(renderFlags, frameCtx, this.model.scene.selectedMaterial, RENDER_PASSES.EDGES_SELECTED);\n        }\n    }\n\n    drawEdgesXRayed(renderFlags, frameCtx) {\n        if (this._countsByFlag[ENTITY_FLAGS.XRAYED].count > 0) {\n            this.__drawUniformEdges(renderFlags, frameCtx, this.model.scene.xrayMaterial, RENDER_PASSES.EDGES_XRAYED);\n        }\n    }\n\n    //---- PICKING ----------------------------------------------------------------------------------------------------\n\n    __drawPick(renderFlags, frameCtx, renderer) {\n        if (renderer) {\n            this.__drawLayer(renderFlags, frameCtx, renderer, RENDER_PASSES.PICK);\n        }\n    }\n\n    drawPickMesh(renderFlags, frameCtx) {\n        this.__drawPick(renderFlags, frameCtx, this._renderers.pickMeshRenderer);\n    }\n\n    drawPickDepths(renderFlags, frameCtx) {\n        this.__drawPick(renderFlags, frameCtx, this._renderers.pickDepthRenderer);\n    }\n\n    drawPickNormals(renderFlags, frameCtx) {\n        const renderer = (this._renderers.pickNormalsFlatRenderer);\n        this.__drawPick(renderFlags, frameCtx, renderer);\n    }\n\n    drawSnap(renderFlags, frameCtx, isSnapInit) {\n        frameCtx.snapPickOrigin = [0, 0, 0];\n\n        const aabb = this.getAABB();\n        frameCtx.snapPickCoordinateScale = math.mulVec3Scalar(\n            safeInvVec3([ aabb[3] - aabb[0], aabb[4] - aabb[1], aabb[5] - aabb[2] ]),\n            math.MAX_INT);\n\n        const renderer = isSnapInit ? this._renderers.snapInitRenderer : ((frameCtx.snapMode === \"edge\") ? this._renderers.snapEdgeRenderer : this._renderers.snapVertexRenderer);\n        this.__drawPick(renderFlags, frameCtx, renderer);\n\n        frameCtx.snapPickLayerParams.push({\n            origin: frameCtx.snapPickOrigin.slice(),\n            coordinateScale: safeInvVec3(frameCtx.snapPickCoordinateScale)\n        });\n    }\n\n\n    drawOcclusion(renderFlags, frameCtx) {\n        const renderer = this._renderers.occlusionRenderer;\n        if (renderer) {\n            this.__drawLayer(renderFlags, frameCtx, renderer, RENDER_PASSES.COLOR_OPAQUE);\n        }\n    }\n\n    drawShadow(renderFlags, frameCtx) {\n        const renderer = this._renderers.shadowRenderer;\n        if (renderer) {\n            this.__drawLayer(renderFlags, frameCtx, renderer, RENDER_PASSES.COLOR_OPAQUE);\n        }\n    }\n\n\n    initFlags(portionId, flags, transparent) {\n        this._countsByFlagArr.forEach(cnt => cnt.fromFlags(flags, true));\n\n        if (transparent) {\n            this._numTransparentLayerPortions++;\n            this.model.numTransparentLayerPortions++;\n        }\n        const deferred = (this.primitive !== \"points\");\n        this._setFlags(portionId, flags, transparent, deferred);\n        this._compiledPortions.setFlags2(portionId, flags, deferred);\n    }\n\n    flushInitFlags() {\n        this._compiledPortions.setDeferredFlags();\n    }\n\n    setVisible(portionId, flags, transparent) {\n        this._countsByFlag[ENTITY_FLAGS.VISIBLE].fromFlags(flags);\n        this._setFlags(portionId, flags, transparent);\n    }\n\n    setCulled(portionId, flags, transparent) {\n        this._countsByFlag[ENTITY_FLAGS.CULLED].fromFlags(flags);\n        this._setFlags(portionId, flags, transparent);\n    }\n\n    setPickable(portionId, flags, transparent) {\n        this._countsByFlag[ENTITY_FLAGS.PICKABLE].fromFlags(flags);\n        this._setFlags(portionId, flags, transparent);\n    }\n\n    setClippable(portionId, flags) {\n        this._countsByFlag[ENTITY_FLAGS.CLIPPABLE].fromFlags(flags);\n        this._compiledPortions.setClippableFlags(portionId, flags);\n    }\n\n    setCollidable(portionId, flags) {\n    }\n\n    setXRayed(portionId, flags, transparent) {\n        this._countsByFlag[ENTITY_FLAGS.XRAYED].fromFlags(flags);\n        this._setFlags(portionId, flags, transparent);\n    }\n\n    setHighlighted(portionId, flags, transparent) {\n        this._countsByFlag[ENTITY_FLAGS.HIGHLIGHTED].fromFlags(flags);\n        this._setFlags(portionId, flags, transparent);\n    }\n\n    setSelected(portionId, flags, transparent) {\n        this._countsByFlag[ENTITY_FLAGS.SELECTED].fromFlags(flags);\n        this._setFlags(portionId, flags, transparent);\n    }\n\n    setEdges(portionId, flags, transparent) {\n        if (this._countsByFlag[ENTITY_FLAGS.EDGES]) {\n            this._countsByFlag[ENTITY_FLAGS.EDGES].fromFlags(flags);\n            this._setFlags(portionId, flags, transparent);\n        }\n    }\n\n    setTransparent(portionId, flags, transparent) {\n        if (transparent) {\n            this._numTransparentLayerPortions++;\n            this.model.numTransparentLayerPortions++;\n        } else {\n            this._numTransparentLayerPortions--;\n            this.model.numTransparentLayerPortions--;\n        }\n        this._setFlags(portionId, flags, transparent);\n    }\n\n    destroy() {\n        this._compiledPortions && this._compiledPortions.destroy();\n    }\n}\n\nlet maxDataTextureHeight = 1 << 16;\nlet maxGeometryBatchSize = 5000000;\n\n/**\n * Manages global configurations for all {@link Viewer}s.\n *\n * ## Example\n *\n * In the example below, we'll disable xeokit's double-precision support, which gives a performance and memory boost\n * on low-power devices, but also means that we can no longer render double-precision models without jittering.\n *\n * That's OK if we know that we're not going to view models that are geographically vast, or offset far from the World coordinate origin.\n *\n * [[Run this example](/examples/index.html#Configs_disableDoublePrecisionAndRAF)]\n *\n * ````javascript\n * import {Configs, Viewer, XKTLoaderPlugin} from \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/xeokit-sdk.es.min.js\";\n *\n * // Access xeoit-sdk global configs.\n * // We typically set configs only before we create any Viewers.\n * const configs = new Configs();\n *\n * // Disable 64-bit precision for extra speed.\n * // Only set this config once, before you create any Viewers.\n * configs.doublePrecisionEnabled = false;\n *\n * // Create a Viewer, to which our configs apply\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n *  });\n *\n * viewer.camera.eye = [-3.933, 2.855, 27.018];\n * viewer.camera.look = [4.400, 3.724, 8.899];\n * viewer.camera.up = [-0.018, 0.999, 0.039];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *     src: \"../assets/models/xkt/v8/ifc/Duplex.ifc.xkt\"\n * });\n * ````\n */\nclass Configs {\n\n    /**\n     * Creates a Configs.\n     */\n    constructor() {\n\n    }\n\n    /**\n     * Sets whether double precision mode is enabled for Viewers.\n     *\n     * When double precision mode is enabled (default), Viewers will accurately render models that contain\n     * double-precision coordinates, without jittering.\n     *\n     * Internally, double precision incurs extra performance and memory overhead, so if we're certain that\n     * we're not going to render models that rely on double-precision coordinates, then it's a good idea to disable\n     * it, especially on low-power devices.\n     *\n     * This should only be set once, before creating any Viewers.\n     *\n     * @returns {Boolean}\n     */\n    set doublePrecisionEnabled(doublePrecision) {\n        math.setDoublePrecisionEnabled(doublePrecision);\n    }\n\n    /**\n     * Gets whether double precision mode is enabled for all Viewers.\n     *\n     * @returns {Boolean}\n     */\n    get doublePrecisionEnabled() {\n        return math.getDoublePrecisionEnabled();\n    }\n\n    /**\n     * Sets the maximum data texture height.\n     *\n     * Should be a multiple of 1024. Default is 4096, which is the maximum allowed value.\n     */\n    set maxDataTextureHeight(value) {\n        value = Math.ceil(value / 1024) * 1024;\n        if (value > 4096) {\n            value = 4096;\n        } else if (value < 1024) {\n            value = 1024;\n        }\n        maxDataTextureHeight = value;\n    }\n\n    /**\n     * Sets maximum data texture height.\n     * @returns {*|number}\n     */\n    get maxDataTextureHeight() {\n        return maxDataTextureHeight;\n    }\n\n    /**\n     * Sets the maximum batched geometry VBO size.\n     *\n     * Default value is 5000000, which is the maximum size.\n     *\n     * Minimum size is 100000.\n     */\n    set maxGeometryBatchSize(value) {\n        if (value < 100000) {\n            value = 100000;\n        } else if (value > 5000000) {\n            value = 5000000;\n        }\n        maxGeometryBatchSize = value;\n    }\n\n    /**\n     * Gets the maximum batched geometry VBO size.\n     */\n    get maxGeometryBatchSize() {\n        return maxGeometryBatchSize;\n    }\n}\n\nconst iota$2 = (n) => { const ret = [ ]; for (let i = 0; i < n; ++i) ret.push(i); return ret; };\n\nconst dataTextureRamStats = {\n    sizeDataColorsAndFlags: 0,\n    sizeDataInstancesMatrices: 0,\n    sizeDataPositionDecodeMatrices: 0,\n    sizeDataTextureOffsets: 0,\n    sizeDataTexturePositions: 0,\n    sizeDataTextureIndices: 0,\n    sizeDataTextureEdgeIndices: 0,\n    sizeDataTexturePortionIds: 0,\n    numberOfGeometries: 0,\n    numberOfPortions: 0,\n    numberOfLayers: 0,\n    numberOfTextures: 0,\n    totalPolygons: 0,\n    totalPolygons8Bits: 0,\n    totalPolygons16Bits: 0,\n    totalPolygons32Bits: 0,\n    totalEdges: 0,\n    totalEdges8Bits: 0,\n    totalEdges16Bits: 0,\n    totalEdges32Bits: 0,\n    cannotCreatePortion: {\n        because10BitsObjectId: 0,\n        becauseTextureSize: 0,\n    },\n    overheadSizeAlignementIndices: 0,\n    overheadSizeAlignementEdgeIndices: 0,\n};\n\nwindow.printDataTextureRamStats = function () {\n\n    console.log(JSON.stringify(dataTextureRamStats, null, 4));\n\n    let totalRamSize = 0;\n\n    Object.keys(dataTextureRamStats).forEach(key => {\n        if (key.startsWith(\"size\")) {\n            totalRamSize += dataTextureRamStats[key];\n        }\n    });\n\n    console.log(`Total size ${totalRamSize} bytes (${(totalRamSize / 1000 / 1000).toFixed(2)} MB)`);\n    console.log(`Avg bytes / triangle: ${(totalRamSize / dataTextureRamStats.totalPolygons).toFixed(2)}`);\n\n    let percentualRamStats = {};\n\n    Object.keys(dataTextureRamStats).forEach(key => {\n        if (key.startsWith(\"size\")) {\n            percentualRamStats[key] =\n                `${(dataTextureRamStats[key] / totalRamSize * 100).toFixed(2)} % of total`;\n        }\n    });\n\n    console.log(JSON.stringify({percentualRamUsage: percentualRamStats}, null, 4));\n};\n\nconst configs = new Configs();\n\n/**\n * 12-bits allowed for object ids.\n * Limits the per-object texture height in the layer.\n */\nconst MAX_NUMBER_OF_OBJECTS_IN_LAYER = (1 << 16);\n\n/**\n * 4096 is max data texture height.\n * Limits the aggregated geometry texture height in the layer.\n */\nconst MAX_DATA_TEXTURE_HEIGHT = configs.maxDataTextureHeight;\n\n/**\n * Align `indices` and `edgeIndices` memory layout to 8 elements.\n *\n * Used as an optimization for the `...portionIds...` texture, so it\n * can just be stored 1 out of 8 `portionIds` corresponding to a given\n * `triangle-index` or `edge-index`.\n */\nconst INDICES_EDGE_INDICES_ALIGNEMENT_SIZE = 8;\n\n/**\n * Number of maximum allowed per-object flags update per render frame\n * before switching to batch update mode.\n */\nconst MAX_OBJECT_UPDATES_IN_FRAME_WITHOUT_BATCHED_UPDATE = 10;\n\nconst tempVec3$5 = math.vec3();\nconst tempVec3a$e = math.vec3();\nconst tempVec4a$b = math.vec4();\nmath.vec4();\nconst tempMat4a = new Float32Array(16);\nconst tempUint8Array4$1 = new Uint8Array(4);\n\nconst DEFAULT_MATRIX$1 = math.identityMat4();\n\n/**\n * @private\n */\nclass DTXLayer extends Layer {\n\n    constructor(model, primitive, origin) {\n\n        super(model, primitive, origin);\n\n        dataTextureRamStats.numberOfLayers++;\n\n        this._sortId = `TriDTX-${dataTextureRamStats.numberOfLayers}`;\n\n        const gl = model.scene.canvas.gl;\n\n        const geometryData = (indicesStatsProp, edgesStatsProp) => {\n            const indicesBuffer = [ ];\n            let lenIndices = 0;\n            const perTriangleNumberPortionId = [ ];\n            let numIndices = 0;\n\n            const edgeIndicesBuffer = [ ];\n            let lenEdgeIndices = 0;\n            const perEdgeNumberPortionId = [ ];\n            let numEdgeIndices = 0;\n\n            return {\n                len: () => numIndices,\n\n                accumulateIndices: (indices, edgeIndices) => {\n                    const accIndicesSubPortion = (indices && (indices.length > 0)) && (function() {\n                        const indicesBase = lenIndices / 3;\n                        lenIndices += indices.length;\n                        indicesBuffer.push(indices);\n                        const numTriangles = indices.length / 3;\n                        return (subPortionId) => {\n                            const currentNumIndices = numIndices;\n                            numIndices += numTriangles * 3;\n                            buffer.perObjectIndexBaseOffsets.push(currentNumIndices / 3 - indicesBase);\n                            for (let i = 0; i < numTriangles; i += INDICES_EDGE_INDICES_ALIGNEMENT_SIZE) {\n                                perTriangleNumberPortionId.push(subPortionId);\n                            }\n                            dataTextureRamStats[indicesStatsProp] += numTriangles;\n                            dataTextureRamStats.totalPolygons += numTriangles;\n                        };\n                    })();\n\n                    const accEdgesSubPortion = edgeIndices && (function() {\n                        const edgeIndicesBase = lenEdgeIndices / 2;\n                        lenEdgeIndices += edgeIndices.length;\n                        edgeIndicesBuffer.push(edgeIndices);\n                        const numEdges = edgeIndices.length / 2;\n                        return subPortionId => {\n                            const currentNumEdgeIndices = numEdgeIndices;\n                            numEdgeIndices += numEdges * 2;\n                            buffer.perObjectEdgeIndexBaseOffsets.push(currentNumEdgeIndices / 2 - edgeIndicesBase);\n                            for (let i = 0; i < numEdges; i += INDICES_EDGE_INDICES_ALIGNEMENT_SIZE) {\n                                perEdgeNumberPortionId.push(subPortionId);\n                            }\n                            dataTextureRamStats[edgesStatsProp] += numEdges;\n                            dataTextureRamStats.totalEdges += numEdges;\n                        };\n                    })();\n\n                    dataTextureRamStats.numberOfGeometries++;\n\n                    return {\n                        numTriangles: indices ? (indices.length / 3) : 0,\n                        accumulateSubPortionId: subPortionId => {\n                            accIndicesSubPortion && accIndicesSubPortion(subPortionId);\n                            accEdgesSubPortion   && accEdgesSubPortion(subPortionId);\n                        }\n                    };\n                },\n\n                createDrawers: (createTextureForSingleItems, indicesType) => {\n                    const createTextureForPackedPortionIds = function(portionIdsArray, defaultIfEmpty) {\n                        return (portionIdsArray.length > 0) ? createTextureForSingleItems([ portionIdsArray ], portionIdsArray.length, 1, gl.UNSIGNED_SHORT, \"sizeDataTexturePortionIds\") : defaultIfEmpty;\n                    };\n\n                    // Texture that holds the PortionId that corresponds to a given polygon-id.\n                    const portionIdsTexture = createTextureForPackedPortionIds(perTriangleNumberPortionId, { texture: null });\n\n                    // Texture that holds the unique-vertex-indices.\n                    const indicesTexture = (lenIndices > 0) && createTextureForSingleItems(indicesBuffer, lenIndices, 3, indicesType, \"sizeDataTextureIndices\");\n\n                    // Texture that holds the PortionId that corresponds to a given edge-id.\n                    const portionEdgeIdsTexture = createTextureForPackedPortionIds(perEdgeNumberPortionId);\n\n                    // Texture that holds the unique-vertex-indices for 8-bit based edge indices.\n                    const edgeIndicesTexture = (lenEdgeIndices > 0) && createTextureForSingleItems(edgeIndicesBuffer, lenEdgeIndices, 2, indicesType, \"sizeDataTextureEdgeIndices\");\n\n                    return {\n                        indices: function(layerTypeInputs, glMode) {\n                            if (numIndices > 0) {\n                                layerTypeInputs.perPrimIndices.setInputValue(indicesTexture);\n                                layerTypeInputs.perPrimIdPorIds.setInputValue(portionIdsTexture);\n                                gl.drawArrays(glMode, 0, numIndices);\n                            }\n                        },\n                        edges: function(layerTypeInputs, glMode) {\n                            if (numEdgeIndices > 0) {\n                                layerTypeInputs.perPrimIndices.setInputValue(edgeIndicesTexture);\n                                layerTypeInputs.perPrimIdPorIds.setInputValue(portionEdgeIdsTexture);\n                                gl.drawArrays(glMode, 0, numEdgeIndices);\n                            }\n                        }\n                    };\n                }\n            };\n        };\n\n        const buffer = this._buffer = {\n            positionsCompressed: [],\n            lenPositionsCompressed: 0,\n\n            geometry8Bits:  geometryData(\"totalPolygons8Bits\",  \"totalEdges8Bits\"),\n            geometry16Bits: geometryData(\"totalPolygons16Bits\", \"totalEdges16Bits\"),\n            geometry32Bits: geometryData(\"totalPolygons32Bits\", \"totalEdges32Bits\"),\n\n            perObjectColors: [],\n            perObjectPickColors: [],\n            perObjectSolid: [],\n            perObjectPositionsDecodeMatrices: [],\n            perObjectInstancePositioningMatrices: [],\n            perObjectVertexBases: [],\n            perObjectIndexBaseOffsets: [],\n            perObjectEdgeIndexBaseOffsets: []\n        };\n\n        this._numVertices = 0;\n\n        this._portions = []; // These counts are used to avoid unnecessary render passes\n\n        this._subPortionReadableGeometries = this.model.scene.readableGeometryEnabled && {};\n\n        /**\n         * Due to `index rebucketting` process in ```prepareMeshGeometry``` function, it's possible that a single\n         * portion is expanded to more than 1 real sub-portion.\n         *\n         * This Array tracks the mapping between:\n         *\n         * - external `portionIds` as seen by consumers of this class.\n         * - internal `sub-portionIds` actually managed by this class.\n         *\n         * The outer index of this array is the externally seen `portionId`.\n         * The inner value of the array, are `sub-portionIds` corresponding to the `portionId`.\n         */\n        this._portionToSubPortionsMap = [];\n\n        this._bucketGeometries = {};\n\n        this._primitive = primitive;\n    }\n\n    /**\n     * Returns whether the ```TrianglesDataTextureLayer``` has room for more portions.\n     *\n     * @param {object} portionCfg An object containing the geometrical data (`positions`, `indices`, `edgeIndices`) for the portion.\n     * @returns {Boolean} Wheter the requested portion can be created\n     */\n    canCreatePortion(portionCfg) {\n        const numNewPortions = portionCfg.buckets.length;\n        if ((this._portions.length + numNewPortions) > MAX_NUMBER_OF_OBJECTS_IN_LAYER) {\n            dataTextureRamStats.cannotCreatePortion.because10BitsObjectId++;\n        }\n        let retVal = (this._portions.length + numNewPortions) <= MAX_NUMBER_OF_OBJECTS_IN_LAYER;\n        const bucketIndex = 0; // TODO: Is this a bug?\n        const bucketGeometryId = portionCfg.geometryId !== undefined && portionCfg.geometryId !== null\n            ? `${portionCfg.geometryId}#${bucketIndex}`\n            : `${portionCfg.id}#${bucketIndex}`;\n        const alreadyHasPortionGeometry = this._bucketGeometries[bucketGeometryId];\n        if (!alreadyHasPortionGeometry) {\n            const buffer = this._buffer;\n            const maxIndicesOfAnyBits = Math.max(buffer.geometry8Bits.len(), buffer.geometry16Bits.len(), buffer.geometry32Bits.len());\n            let numVertices = 0;\n            let numIndices = 0;\n            portionCfg.buckets.forEach(bucket => {\n                numVertices += bucket.positionsCompressed.length / 3;\n                numIndices += bucket.indices.length / 3;\n            });\n            if ((this._numVertices + numVertices) > MAX_DATA_TEXTURE_HEIGHT * 4096 ||\n                (maxIndicesOfAnyBits + numIndices) > MAX_DATA_TEXTURE_HEIGHT * 4096) {\n                dataTextureRamStats.cannotCreatePortion.becauseTextureSize++;\n            }\n            retVal &&=\n                (this._numVertices + numVertices) <= MAX_DATA_TEXTURE_HEIGHT * 4096 &&\n                (maxIndicesOfAnyBits + numIndices) <= MAX_DATA_TEXTURE_HEIGHT * 4096;\n        }\n        return retVal;\n    }\n\n    /**\n     * Creates a new portion within this TrianglesDataTextureLayer, returns the new portion ID.\n     *\n     * Gives the portion the specified geometry, color and matrix.\n     *\n     * @param mesh The SceneModelMesh that owns the portion\n     * @param portionCfg.positionsCompressed Flat float Local-space positionsCompressed array.\n     * @param [portionCfg.normals] Flat float normals array.\n     * @param [portionCfg.colors] Flat float colors array.\n     * @param portionCfg.indices  Flat int indices array.\n     * @param [portionCfg.edgeIndices] Flat int edges indices array.\n     * @param portionCfg.color Quantized RGB color [0..255,0..255,0..255,0..255]\n     * @param portionCfg.opacity Opacity [0..255]\n     * @param [portionCfg.meshMatrix] Flat float 4x4 matrix - transforms the portion within the coordinate system that's local to the SceneModel\n     * @param portionCfg.worldAABB Flat float AABB World-space AABB\n     * @param portionCfg.pickColor Quantized pick color\n     * @returns {number} Portion ID\n     */\n    createPortion(mesh, portionCfg) {\n        const buffer = this._buffer;\n        //   const portionAABB = portionCfg.worldAABB;\n        const subPortionIds = portionCfg.buckets.map((bucket, bucketIndex) => {\n            const bucketGeometryId = (portionCfg.geometryId ?? portionCfg.id) + \"#\" + bucketIndex;\n            //  const subPortionAABB = math.collapseAABB3(tempAABB3b);\n            if (! (bucketGeometryId in this._bucketGeometries)) {\n                const aligned = (indices, elementSize, statsProp) => {\n                    // Indices and EdgeIndices alignement\n                    // This will make every mesh consume a multiple of INDICES_EDGE_INDICES_ALIGNEMENT_SIZE\n                    // array items for storing the triangles and edges of the mesh, and it supports:\n                    // - a memory optimization of factor INDICES_EDGE_INDICES_ALIGNEMENT_SIZE\n                    // - in exchange for a small RAM overhead\n                    //   (by adding some padding until a size that is multiple of INDICES_EDGE_INDICES_ALIGNEMENT_SIZE)\n                    if (indices) {\n                        const alignedLen = Math.ceil((indices.length / elementSize) / INDICES_EDGE_INDICES_ALIGNEMENT_SIZE) * INDICES_EDGE_INDICES_ALIGNEMENT_SIZE * elementSize;\n                        const alignedArray = new Uint32Array(alignedLen);\n                        alignedArray.set(indices);\n                        dataTextureRamStats[statsProp] += 2 * (alignedArray.length - indices.length);\n                        return alignedArray;\n                    } else {\n                        return indices;\n                    }\n                };\n\n                bucket.indices     = aligned(bucket.indices,     3, \"overheadSizeAlignementIndices\");\n                bucket.edgeIndices = aligned(bucket.edgeIndices, 2, \"overheadSizeAlignementEdgeIndices\");\n\n                const positionsCompressed = bucket.positionsCompressed;\n                buffer.positionsCompressed.push(positionsCompressed);\n                const numVertices = positionsCompressed.length / 3;\n                this._numVertices += numVertices;\n                const vertexBase = buffer.lenPositionsCompressed / 3;\n                buffer.lenPositionsCompressed += positionsCompressed.length;\n\n                this._bucketGeometries[bucketGeometryId] = {\n                    vertexBase: vertexBase,\n                    geometryData: (function() {\n                        const indices = bucket.indices;\n                        const edgeIndices = bucket.edgeIndices;\n                        if (numVertices <= (1 << 8)) {\n                            return buffer.geometry8Bits.accumulateIndices( indices, edgeIndices);\n                        } else if (numVertices <= (1 << 16)) {\n                            return buffer.geometry16Bits.accumulateIndices(indices, edgeIndices);\n                        } else {\n                            return buffer.geometry32Bits.accumulateIndices(indices, edgeIndices);\n                        }\n                    })()\n                };\n            }\n\n            //math.expandAABB3(portionAABB, subPortionAABB);\n            const bucketGeometry = this._bucketGeometries[bucketGeometryId];\n            buffer.perObjectPositionsDecodeMatrices.push(portionCfg.positionsDecodeMatrix);\n            buffer.perObjectInstancePositioningMatrices.push(portionCfg.meshMatrix || DEFAULT_MATRIX$1);\n            buffer.perObjectSolid.push(!!portionCfg.solid);\n            buffer.perObjectPickColors.push(portionCfg.pickColor);\n            buffer.perObjectVertexBases.push(bucketGeometry.vertexBase);\n\n            const colors = portionCfg.colors;\n            const color = portionCfg.color; // Color is pre-quantized by SceneModel\n            buffer.perObjectColors.push(colors\n                                        ? [ colors[0] * 255, colors[1] * 255, colors[2] * 255, 255 ]\n                                        : [ color[0],        color[1],        color[2],        portionCfg.opacity ]);\n\n            const subPortionId = this._portions.length;\n            this._portions.push({ });\n            bucketGeometry.geometryData.accumulateSubPortionId(subPortionId);\n\n            if (this._subPortionReadableGeometries) {\n                this._subPortionReadableGeometries[subPortionId] = {\n                    indices: bucket.indices,\n                    positionsCompressed: bucket.positionsCompressed,\n                    positionsDecodeMatrix: portionCfg.positionsDecodeMatrix\n                };\n            }\n\n            dataTextureRamStats.numberOfPortions++;\n\n            return subPortionId;\n        });\n        const portionId = this._portionToSubPortionsMap.length;\n        this._portionToSubPortionsMap.push(subPortionIds);\n        this.model.numPortions++;\n        this._meshes.push(mesh);\n        return portionId;\n    }\n\n    /**\n     * Builds data textures from the appended geometries and loads them into the GPU.\n     *\n     * No more portions can then be created.\n     */\n    compilePortions() {\n        const buffer                       = this._buffer;\n        const model                        = this.model;\n        const numPortions                  = this._portions.length;\n        const origin                       = this.origin;\n        const portionToSubPortionsMap      = this._portionToSubPortionsMap;\n        const primitive                    = this._primitive;\n        const sortId                       = this._sortId;\n        const subPortionReadableGeometries = this._subPortionReadableGeometries;\n\n        const scene = model.scene;\n        const gl = scene.canvas.gl;\n\n        /*\n         * Texture that holds colors/pickColors/flags/flags2 per-object:\n         * - columns: one concept per column => color / pick-color / ...\n         * - row: the object Id\n         * The texture will have:\n         * - 4 RGBA columns per row: for each object (pick) color and flags(2)\n         * - N rows where N is the number of objects\n         */\n        const populateTexArray = texArray => {\n            const pack32as4x8 = ui32 => [\n                (ui32 >> 24) & 255,\n                (ui32 >> 16) & 255,\n                (ui32 >>  8) & 255,\n                (ui32)       & 255\n            ];\n            for (let i = 0; i < numPortions; i++) {\n                // 8 columns per texture row:\n                texArray.set(buffer.perObjectColors[i],                            i * 32 +  0); // (RGBA)\n                texArray.set(buffer.perObjectPickColors[i],                        i * 32 +  4); // (packed Uint32 as RGBA)\n                texArray.set([0, 0, 0, 0], /* flags */                             i * 32 +  8); // (packed 4 bytes as RGBA)\n                texArray.set([0, 0, 0, 0], /* flags2 */                            i * 32 + 12); // (packed 4 bytes as RGBA)\n                texArray.set(pack32as4x8(buffer.perObjectVertexBases[i]),          i * 32 + 16); // (packed Uint32 bytes as RGBA)\n                texArray.set(pack32as4x8(buffer.perObjectIndexBaseOffsets[i]),     i * 32 + 20); // (packed Uint32 bytes as RGBA)\n                texArray.set(pack32as4x8(buffer.perObjectEdgeIndexBaseOffsets[i]), i * 32 + 24); // (packed Uint32 bytes as RGBA)\n                texArray.set([buffer.perObjectSolid[i] ? 1 : 0, 0, 0, 0],          i * 32 + 28); // (packed 4 bytes as RGBA)\n            }\n        };\n\n        // The number of rows in the texture is the number of objects in the layer.\n        const texturePerObjectColorsAndFlags = createBindableDataTexture(gl, numPortions, 32, gl.UNSIGNED_BYTE, 512, populateTexArray, \"sizeDataColorsAndFlags\", true);\n        const texturePerObjectColorsAndFlagsData = texturePerObjectColorsAndFlags.textureData;\n\n        const createDataTexture = function(dataArrays, entitiesCnt, entitySize, type, entitiesPerRow, statsProp, exposeData) {\n            const populateTexArray = texArray => {\n                for (let i = 0, j = 0, len = dataArrays.length; i < len; i++) {\n                    const pc = dataArrays[i];\n                    texArray.set(pc, j);\n                    j += pc.length;\n                }\n            };\n            return createBindableDataTexture(gl, entitiesCnt, entitySize, type, entitiesPerRow, populateTexArray, statsProp, exposeData);\n        };\n\n        const createTextureForMatrices = function(matrices, statsProp, exposeData) {\n            const numMatrices = matrices.length;\n            if (numMatrices === 0) {\n                throw \"num \" + statsProp + \" matrices===0\";\n            }\n            // in one row we can fit 512 matrices\n            return createDataTexture(matrices, numMatrices, 16, gl.FLOAT, 512, statsProp, exposeData);\n        };\n\n        /**\n         * This will generate a texture for all positions decode matrices in the layer.\n         * The texture will have:\n         * - 4 RGBA columns per row (each column will contain 4 packed half-float (16 bits) components).\n         *   Thus, each row will contain 16 packed half-floats corresponding to a complete positions decode matrix)\n         * - N rows where N is the number of objects\n         */\n        const texturePerObjectInstanceMatrices = createTextureForMatrices(buffer.perObjectInstancePositioningMatrices, \"sizeDataInstancesMatrices\", true);\n        const texturePerObjectInstanceMatricesData = texturePerObjectInstanceMatrices.textureData;\n\n        /*\n         * Texture that holds the objectDecodeAndInstanceMatrix per-object:\n         * - columns: each column is one column of the matrix\n         * - row: the object Id\n         * The texture will have:\n         * - 4 RGBA columns per row (each column will contain 4 packed half-float (16 bits) components).\n         *   Thus, each row will contain 16 packed half-floats corresponding to a complete positions decode matrix)\n         * - N rows where N is the number of objects\n         */\n        const texturePerObjectPositionsDecodeMatrix = createTextureForMatrices(buffer.perObjectPositionsDecodeMatrices, \"sizeDataPositionDecodeMatrices\", false);\n\n\n        const createTextureForSingleItems = function(dataArrays, dataCnt, entitySize, type, statsProp) {\n            return createDataTexture(dataArrays, dataCnt / entitySize, entitySize, type, 4096, statsProp, false);\n        };\n\n        /*\n         * Texture that holds all the `different-vertices` used by the layer.\n         * This will generate a texture for positions in the layer.\n         *\n         * The texture will have:\n         * - 1024 columns, where each pixel will be a 16-bit-per-component RGB texture, corresponding to the XYZ of the position\n         * - a number of rows R where R*1024 is just >= than the number of vertices (positions / 3)\n         */\n        const texturePerVertexIdCoordinates = createTextureForSingleItems(\n            buffer.positionsCompressed, buffer.lenPositionsCompressed, 3, gl.UNSIGNED_SHORT, \"sizeDataTexturePositions\");\n\n        const draw8  = buffer.geometry8Bits.createDrawers( createTextureForSingleItems, gl.UNSIGNED_BYTE);\n        const draw16 = buffer.geometry16Bits.createDrawers(createTextureForSingleItems, gl.UNSIGNED_SHORT);\n        const draw32 = buffer.geometry32Bits.createDrawers(createTextureForSingleItems, gl.UNSIGNED_INT);\n\n        // Free up memory\n        this._buffer = null;\n\n        let deferredSetFlagsActive = false;\n        let deferredSetFlagsDirty = false;\n        let destroyed = false;\n        let numUpdatesInFrame = 0;\n\n\n        /**\n         * This will _start_ a \"set-flags transaction\".\n         *\n         * After invoking this method, calling setFlags/setFlags2 will not update\n         * the colors+flags texture but only store the new flags/flag2 in the\n         * colors+flags texture data array.\n         *\n         * After invoking this method, and when all desired setFlags/setFlags2 have\n         * been called on needed portions of the layer, invoke `uploadDeferredFlags`\n         * to actually upload the data array into the texture.\n         *\n         * In massive \"set-flags\" scenarios like VFC or LOD mechanisms, the combination of\n         * `beginDeferredFlags` + `uploadDeferredFlags`brings a speed-up of\n         * up to 80x when e.g. objects are massively (un)culled 🚀.\n         */\n        const beginDeferredFlags = () => { deferredSetFlagsActive = true; };\n\n        const onSceneRendering = scene.on(\"rendering\", () => {\n            if (deferredSetFlagsDirty) {\n                // uploadDeferredFlags\n                /**\n                 * This will _commit_ a \"set-flags transaction\".\n                 * Invoking this method will update the colors+flags texture data with new\n                 * flags/flags2 set since the previous invocation of `beginDeferredFlags`.\n                 */\n                deferredSetFlagsActive = false;\n                deferredSetFlagsDirty = false;\n                texturePerObjectColorsAndFlagsData.reloadData();\n            }\n            numUpdatesInFrame = 0;\n        });\n\n        const forEachSubPortionId = (portionId, cb) => {\n            const subPortionIds = portionToSubPortionsMap[portionId];\n            if (!subPortionIds) {\n                model.error(\"portion not found: \" + portionId);\n            } else {\n                for (let i = 0, len = subPortionIds.length; i < len; i++) {\n                    cb(subPortionIds[i]);\n                }\n            }\n        };\n\n        const setPortionColorsAndFlags = (subPortionId, offset, data, deferred) => {\n            const defer = deferredSetFlagsActive || deferred;\n            if (defer) {\n                deferredSetFlagsDirty = true;\n            } else if (++numUpdatesInFrame >= MAX_OBJECT_UPDATES_IN_FRAME_WITHOUT_BATCHED_UPDATE) {\n                beginDeferredFlags(); // Subsequent flags updates now deferred\n            }\n            texturePerObjectColorsAndFlagsData.setData(data, subPortionId, offset, !defer);\n        };\n\n        const setFlags2 = (portionId, flags, deferred = false) => {\n            tempUint8Array4$1.set([ (flags & ENTITY_FLAGS.CLIPPABLE) ? 255 : 0, 0, 1, 2 ]);\n            forEachSubPortionId(portionId, subPortionId => setPortionColorsAndFlags(subPortionId, 3, tempUint8Array4$1, deferred));\n        };\n\n        return {\n            edgesColorOpaqueAllowed: () => {\n                if (scene.logarithmicDepthBufferEnabled) {\n                    if (!scene._loggedWarning) {\n                        console.log(\"Edge enhancement for SceneModel data texture layers currently disabled with logarithmic depth buffer\");\n                        scene._loggedWarning = true;\n                    }\n                    return false;\n                } else {\n                    return true;\n                }\n            },\n            sortId: sortId,\n            setClippableFlags: setFlags2,\n            setFlags: (portionId, flags, transparent, deferred = false) => {\n                getColSilhEdgePickFlags(flags, transparent, true, scene, tempUint8Array4$1);\n                forEachSubPortionId(portionId, subPortionId => setPortionColorsAndFlags(subPortionId, 2, tempUint8Array4$1, deferred));\n            },\n            setFlags2: setFlags2,\n            setDeferredFlags: () => { },\n\n            setColor: (portionId, color) => {\n                tempUint8Array4$1.set(color);\n                forEachSubPortionId(portionId, subPortionId => setPortionColorsAndFlags(subPortionId, 0, tempUint8Array4$1, false));\n            },\n            setMatrix: (portionId, matrix) => {\n                forEachSubPortionId(portionId, subPortionId => {\n                    const defer = deferredSetFlagsActive;\n                    if (defer) {\n                        deferredSetFlagsDirty = true;\n                    } else if (++numUpdatesInFrame >= MAX_OBJECT_UPDATES_IN_FRAME_WITHOUT_BATCHED_UPDATE) {\n                        beginDeferredFlags(); // Subsequent flags updates now deferred\n                    }\n                    tempMat4a.set(matrix);\n                    texturePerObjectInstanceMatricesData.setData(tempMat4a, subPortionId, 0, !defer);\n                });\n            },\n            setOffset: (portionId, offset) =>  { /* NOT COMPLETE */ },\n\n            getEachIndex: (portionId, callback) => {\n                if (subPortionReadableGeometries) {\n                    forEachSubPortionId(\n                        portionId,\n                        subPortionId => subPortionReadableGeometries[subPortionId].indices.forEach(i => callback(i)));\n                }\n            },\n            getEachVertex: (portionId, callback) => {\n                if (subPortionReadableGeometries) {\n                    forEachSubPortionId(portionId, subPortionId => {\n                        const subPortionReadableGeometry = subPortionReadableGeometries[subPortionId];\n                        const positions = subPortionReadableGeometry.positionsCompressed;\n                        const positionsDecodeMatrix = subPortionReadableGeometry.positionsDecodeMatrix;\n                        const worldPos = tempVec4a$b;\n                        for (let i = 0, len = positions.length; i < len; i += 3) {\n                            worldPos[0] = positions[i];\n                            worldPos[1] = positions[i + 1];\n                            worldPos[2] = positions[i + 2];\n                            worldPos[3] = 1.0;\n                            math.decompressPosition(worldPos, positionsDecodeMatrix);\n                            math.mulMat4v4(model.worldMatrix, worldPos, worldPos);\n                            math.addVec3(origin, worldPos, worldPos);\n                            callback(worldPos);\n                        }\n                    });\n                }\n            },\n            precisionRayPickSurface: (portionId, worldRayOrigin, worldRayDir, worldSurfacePos, worldNormal) => false,\n\n            renderers: getRenderers(scene, \"dtx\", primitive, model.saoEnabled, false, false, true,\n                                    (programVariables, subGeometry) => makeDTXRenderingAttributes(programVariables, !subGeometry)),\n            drawCalls: (function() {\n                const drawer = function(drawCall) {\n                    const setInputValue = (input, value) => (input.setInputValue && input.setInputValue(value));\n                    return (attributesHash, layerTypeInputs, viewState) => {\n                        setInputValue(layerTypeInputs.worldMatrix, model.rotationMatrix);\n                        setInputValue(layerTypeInputs.viewMatrix, viewState.viewMatrix);\n                        setInputValue(layerTypeInputs.projMatrix, viewState.projMatrix);\n                        const rtcOrigin = math.transformPoint3(model.matrix, origin, tempVec3$5);\n                        setInputValue(layerTypeInputs.uCameraEyeRtc, math.subVec3(viewState.eye, rtcOrigin, tempVec3a$e));\n                        setInputValue(layerTypeInputs.perObjPosDecode, texturePerObjectPositionsDecodeMatrix);\n                        setInputValue(layerTypeInputs.perVertIdCoords, texturePerVertexIdCoordinates);\n                        setInputValue(layerTypeInputs.perObjColsFlags, texturePerObjectColorsAndFlags);\n                        setInputValue(layerTypeInputs.perObjectMatrix, texturePerObjectInstanceMatrices);\n                        drawCall(layerTypeInputs);\n                    };\n                };\n\n                const vertEdgesDrawer = function(glMode) {\n                    return drawer((layerTypeInputs) => {\n                        draw8.edges( layerTypeInputs, glMode);\n                        draw16.edges(layerTypeInputs, glMode);\n                        draw32.edges(layerTypeInputs, glMode);\n                    });\n                };\n\n                return {\n                    drawVertices: vertEdgesDrawer(gl.POINTS),\n                    drawEdges:    vertEdgesDrawer(gl.LINES),\n                    drawSurface:  drawer((layerTypeInputs) => {\n                        const glMode = gl.TRIANGLES;\n                        draw8.indices( layerTypeInputs, glMode);\n                        draw16.indices(layerTypeInputs, glMode);\n                        draw32.indices(layerTypeInputs, glMode);\n                    })\n                };\n            })(),\n\n            destroy: () => {\n                if (! destroyed) {\n                    scene.off(onSceneRendering);\n                    destroyed = true;\n                }\n            }\n        };\n    }\n}\n\nconst createBindableDataTexture = function(gl, entitiesCnt, entitySize, type, entitiesPerRow, populateTexArray, statsProp, exposeData) {\n    if ((entitySize > 4) && ((entitySize % 4) > 0)) {\n        throw \"Unhandled data size \" + entitySize;\n    }\n    const pixelsPerEntity = Math.ceil(entitySize / 4);\n    const pixelWidth = entitySize / pixelsPerEntity;\n\n    const [ arrayType, internalFormat, format ] = (function() {\n        switch(type) {\n        case gl.UNSIGNED_BYTE:\n            return [ Uint8Array,   ...((pixelWidth === 1) ? [ gl.R8UI,  gl.RED_INTEGER ] : ((pixelWidth === 2) ? [ gl.RG8UI,  gl.RG_INTEGER ] : ((pixelWidth === 3) ? [ gl.RGB8UI,  gl.RGB_INTEGER ] : [ gl.RGBA8UI,  gl.RGBA_INTEGER ]))) ];\n        case gl.UNSIGNED_SHORT:\n            return [ Uint16Array,  ...((pixelWidth === 1) ? [ gl.R16UI, gl.RED_INTEGER ] : ((pixelWidth === 2) ? [ gl.RG16UI, gl.RG_INTEGER ] : ((pixelWidth === 3) ? [ gl.RGB16UI, gl.RGB_INTEGER ] : [ gl.RGBA16UI, gl.RGBA_INTEGER ]))) ];\n        case gl.UNSIGNED_INT:\n            return [ Uint32Array,  ...((pixelWidth === 1) ? [ gl.R32UI, gl.RED_INTEGER ] : ((pixelWidth === 2) ? [ gl.RG32UI, gl.RG_INTEGER ] : ((pixelWidth === 3) ? [ gl.RGB32UI, gl.RGB_INTEGER ] : [ gl.RGBA32UI, gl.RGBA_INTEGER ]))) ];\n        case gl.FLOAT:\n            return [ Float32Array, ...((pixelWidth === 1) ? [ gl.R32F,  gl.RED ]         : ((pixelWidth === 2) ? [ gl.RG32F,  gl.RG ]         : ((pixelWidth === 3) ? [ gl.RGB32F,  gl.RGB ]         : [ gl.RGBA32F,  gl.RGBA ]))) ];\n        default:\n            throw \"Unhandled data type \" + type;\n        }\n    })();\n\n    const textureWidth = entitiesPerRow * pixelsPerEntity;\n    const textureHeight = Math.ceil(entitiesCnt / entitiesPerRow);\n    if (textureHeight === 0) {\n        throw \"texture height===0\";\n    }\n    const texArray = new arrayType(textureWidth * textureHeight * pixelWidth);\n    dataTextureRamStats[statsProp] += texArray.byteLength;\n    dataTextureRamStats.numberOfTextures++;\n\n    populateTexArray(texArray);\n\n    const texture = gl.createTexture();\n    gl.bindTexture(gl.TEXTURE_2D, texture);\n    gl.texStorage2D(gl.TEXTURE_2D, 1, internalFormat, textureWidth, textureHeight);\n    gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, textureWidth, textureHeight, format, type, texArray);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n    gl.bindTexture(gl.TEXTURE_2D, null);\n\n    return {\n        // called by createSampler::bindTexture\n        bind(unit) {\n            gl.activeTexture(gl[\"TEXTURE\" + unit]);\n            gl.bindTexture(gl.TEXTURE_2D, texture);\n            return true;\n        },\n\n        unbind(unit) {\n            // This `unbind` method is ignored at the moment to allow avoiding\n            // to rebind same texture already bound to a texture unit.\n\n            // this._gl.activeTexture(gl[\"TEXTURE\" + unit]);\n            // this._gl.bindTexture(gl.TEXTURE_2D, null);\n        },\n\n        textureData: exposeData && {\n            setData(data, subPortionId, offset = 0, load = false) {\n                texArray.set(data, subPortionId * entitySize + offset * pixelWidth);\n                if (load) {\n                    gl.bindTexture(gl.TEXTURE_2D, texture);\n                    const xoffset = (subPortionId % entitiesPerRow) * pixelsPerEntity + offset;\n                    const yoffset = Math.floor(subPortionId / entitiesPerRow);\n                    const width = data.length / pixelWidth;\n                    gl.texSubImage2D(gl.TEXTURE_2D, 0, xoffset, yoffset, width, 1, format, type, data);\n                    // gl.bindTexture (gl.TEXTURE_2D, null);\n                }\n            },\n\n            reloadData() {\n                gl.bindTexture(gl.TEXTURE_2D, texture);\n                gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, textureWidth, textureHeight, format, type, texArray);\n            }\n        }\n    };\n};\n\nconst makeDTXRenderingAttributes = function(programVariables, isTriangle) {\n    const setupTex = (type, name) => {\n        const map = programVariables.createUniform(type, name);\n        const texelFetch = (P) => `texelFetch(${map}, ${P}, 0)`;\n        texelFetch.map = map;\n        return texelFetch;\n    };\n\n    const perPrimIndices  = setupTex(\"highp   usampler2D\", \"perPrimIndices\");\n    const perPrimIdPorIds = setupTex(\"mediump usampler2D\", \"perPrimIdPorIds\");\n\n    const perObjPosDecode = setupTex(\"highp    sampler2D\", \"perObjPosDecode\");\n    const perVertIdCoords = setupTex(\"mediump usampler2D\", \"perVertIdCoords\");\n    const perObjColsFlags = setupTex(\"lowp    usampler2D\", \"perObjColsFlags\");\n    const perObjectMatrix = setupTex(\"highp    sampler2D\", \"perObjectMatrix\");\n\n    const worldMatrix   = programVariables.createUniform(\"mat4\", \"worldMatrix\");\n    const viewMatrix    = programVariables.createUniform(\"mat4\", \"viewMatrix\");\n    const projMatrix    = programVariables.createUniform(\"mat4\", \"projMatrix\");\n    const uCameraEyeRtc = programVariables.createUniform(\"vec3\", \"uCameraEyeRtc\");\n\n    const lazyShaderVariable = function(name) {\n        const variable = {\n            toString: () => {\n                variable.needed = true;\n                return name;\n            }\n        };\n        return variable;\n    };\n\n    const colorA     = lazyShaderVariable(\"colorA\");\n    const pickColorA = lazyShaderVariable(\"pickColor\");\n    const worldNormal = lazyShaderVariable(\"worldNormal\");\n    const viewNormal = lazyShaderVariable(\"viewNormal\");\n\n    const colorsAndFlags = (offset) => perObjColsFlags(`ivec2(objectIndexCoords.x*8+${offset}, objectIndexCoords.y)`);\n\n    return {\n        clippableTest: (function() {\n            const vClippable = programVariables.createVarying(\"uint\", \"vClippable\", () => \"flags2.r\", \"flat\");\n            return () => `${vClippable} > 0u`;\n        })(),\n\n        geometryParameters: {\n            attributes: {\n                color:             colorA,\n                flags:             iota$2(4).map(i => `int(flags[${i}])`),\n                metallicRoughness: null,\n                normal:            {\n                    view:  viewNormal,\n                    world: worldNormal\n                },\n                pickColor:         pickColorA,\n                position:          {\n                    clip:  \"gl_Position\",\n                    view:  \"viewPosition\",\n                    world: \"worldPosition\"\n                },\n                uv:                null\n            },\n            projMatrix: projMatrix,\n            viewMatrix: viewMatrix\n        },\n\n        ensureColorAndFlagAvailable: (src) => {\n            // constants\n            src.push(\"int primitiveIndex = gl_VertexID / \" + (isTriangle ? 3 : 2) + \";\");\n\n            // get packed object-id\n            src.push(\"int h_packed_object_id_index = (primitiveIndex >> 3) & 4095;\");\n            src.push(\"int v_packed_object_id_index = (primitiveIndex >> 3) >> 12;\");\n\n            src.push(`int objectIndex = int(${perPrimIdPorIds(\"ivec2(h_packed_object_id_index, v_packed_object_id_index)\")}.r);`);\n            src.push(\"ivec2 objectIndexCoords = ivec2(objectIndex % 512, objectIndex / 512);\");\n\n            // get flags & flags2\n            src.push(`uvec4 flags  = ${colorsAndFlags(2)};`);\n            src.push(`uvec4 flags2 = ${colorsAndFlags(3)};`);\n\n            colorA.needed && src.push(`vec4 ${colorA} = vec4(${colorsAndFlags(0)}) / 255.0;`);\n        },\n\n        appendVertexData: (src) => {\n            const objMatrix = (offset) => perObjectMatrix(`ivec2(objectIndexCoords.x*4+${offset}, objectIndexCoords.y)`);\n            src.push(`mat4 objectInstanceMatrix = mat4(${objMatrix(0)}, ${objMatrix(1)}, ${objMatrix(2)}, ${objMatrix(3)});`);\n\n            const posMatrix = (offset) => perObjPosDecode(`ivec2(objectIndexCoords.x*4+${offset}, objectIndexCoords.y)`);\n            src.push(`mat4 objectDecodeAndInstanceMatrix = objectInstanceMatrix * mat4(${posMatrix(0)}, ${posMatrix(1)}, ${posMatrix(2)}, ${posMatrix(3)});`);\n\n            src.push(`ivec4 packedVertexBase = ivec4(${colorsAndFlags(4)});`);\n            src.push(`ivec4 packedIndexBaseOffset = ivec4(${colorsAndFlags(isTriangle ? 5 : 6)});`);\n            src.push(\"int indexBaseOffset = (packedIndexBaseOffset.r << 24) + (packedIndexBaseOffset.g << 16) + (packedIndexBaseOffset.b << 8) + packedIndexBaseOffset.a;\");\n\n            src.push(\"int h_index = (primitiveIndex - indexBaseOffset) & 4095;\");\n            src.push(\"int v_index = (primitiveIndex - indexBaseOffset) >> 12;\");\n\n            src.push(`ivec3 vertexIndices = ivec3(${perPrimIndices(\"ivec2(h_index, v_index)\")});`);\n            src.push(\"ivec3 uniqueVertexIndexes = vertexIndices + (packedVertexBase.r << 24) + (packedVertexBase.g << 16) + (packedVertexBase.b << 8) + packedVertexBase.a;\");\n\n            if (isTriangle) {\n                src.push(\"ivec3 indexPositionH = uniqueVertexIndexes & 4095;\");\n                src.push(\"ivec3 indexPositionV = uniqueVertexIndexes >> 12;\");\n                src.push(`uint solid = ${colorsAndFlags(7)}.r;`);\n                const vertIdCoords = (idx) => `vec3(${perVertIdCoords(`ivec2(indexPositionH[${idx}], indexPositionV[${idx}])`)})`;\n                src.push(`vec3 positions[] = vec3[](${vertIdCoords(0)}, ${vertIdCoords(1)}, ${vertIdCoords(2)});`);\n                src.push(\"vec3 normal = normalize(cross(positions[2] - positions[0], positions[1] - positions[0]));\");\n                src.push(\"vec3 position = positions[gl_VertexID % 3];\");\n                if (worldNormal.needed) { // WARNING: Not thoroughly tested, as not being used at the moment\n                    src.push(`vec3 worldNormal = -normalize((transpose(inverse(${worldMatrix} * objectDecodeAndInstanceMatrix)) * vec4(normal,1)).xyz);`);\n                }\n                if (viewNormal.needed) {\n                    src.push(`vec3 viewNormal = -normalize((transpose(inverse(${viewMatrix} * objectDecodeAndInstanceMatrix)) * vec4(normal,1)).xyz);`);\n                }\n                // when the geometry is not solid, if needed, flip the triangle winding\n                src.push(\"if (solid != 1u) {\");\n                src.push(`  if (${isPerspectiveMatrix(projMatrix)}) {`);\n                src.push(`      vec3 uCameraEyeRtcInQuantizedSpace = (inverse(${worldMatrix} * objectDecodeAndInstanceMatrix) * vec4(${uCameraEyeRtc}, 1)).xyz;`);\n                src.push(\"      if (dot(position.xyz - uCameraEyeRtcInQuantizedSpace, normal) < 0.0) {\");\n                src.push(\"          position = positions[2 - (gl_VertexID % 3)];\");\n                if (worldNormal.needed) {\n                    src.push(\"          worldNormal = -worldNormal;\");\n                }\n                if (viewNormal.needed) {\n                    src.push(\"          viewNormal = -viewNormal;\");\n                }\n                src.push(\"      }\");\n                src.push(\"  } else {\");\n                if (!viewNormal.needed) {\n                    src.push(`      vec3 viewNormal = -normalize((transpose(inverse(${viewMatrix} * objectDecodeAndInstanceMatrix)) * vec4(normal,1)).xyz);`);\n                }\n                src.push(\"      if (viewNormal.z < 0.0) {\");\n                src.push(\"          position = positions[2 - (gl_VertexID % 3)];\");\n                if (worldNormal.needed) {\n                    src.push(\"          worldNormal = -worldNormal;\");\n                }\n                if (viewNormal.needed) {\n                    src.push(\"          viewNormal = -viewNormal;\");\n                }\n                src.push(\"      }\");\n                src.push(\"  }\");\n                src.push(\"}\");\n            } else {\n                src.push(\"int indexPositionH = uniqueVertexIndexes[gl_VertexID % 2] & 4095;\");\n                src.push(\"int indexPositionV = uniqueVertexIndexes[gl_VertexID % 2] >> 12;\");\n                src.push(`vec3 position = vec3(${perVertIdCoords(\"ivec2(indexPositionH, indexPositionV)\")});`);\n            }\n\n            pickColorA.needed && src.push(`vec4 pickColor = vec4(${colorsAndFlags(1)});`); // TODO: Normalize color \"/ 255.0\"?\n\n            src.push(`vec4 worldPosition = ${worldMatrix} * (objectDecodeAndInstanceMatrix * vec4(position, 1.0));`);\n        },\n\n        layerTypeInputs: {\n            perPrimIndices:  perPrimIndices.map,\n            perPrimIdPorIds: perPrimIdPorIds.map,\n\n            perObjPosDecode: perObjPosDecode.map,\n            perVertIdCoords: perVertIdCoords.map,\n            perObjColsFlags: perObjColsFlags.map,\n            perObjectMatrix: perObjectMatrix.map,\n\n            worldMatrix:   worldMatrix,\n            viewMatrix:    viewMatrix,\n            projMatrix:    projMatrix,\n            uCameraEyeRtc: uCameraEyeRtc\n        }\n    };\n};\n\nconst translate$1 = math.mat4();\nconst scale$1 = math.mat4();\n\n/**\n * @private\n */\nfunction quantizePositions(positions, aabb, positionsDecodeMatrix) { // http://cg.postech.ac.kr/research/mesh_comp_mobile/mesh_comp_mobile_conference.pdf\n    const lenPositions = positions.length;\n    const quantizedPositions = new Uint16Array(lenPositions);\n    const xmin = aabb[0];\n    const ymin = aabb[1];\n    const zmin = aabb[2];\n    const xwid = (aabb[3] - xmin) || 1;\n    const ywid = (aabb[4] - ymin) || 1;\n    const zwid = (aabb[5] - zmin) || 1;\n    const maxInt = 65525;\n    const xMultiplier = maxInt / xwid;\n    const yMultiplier = maxInt / ywid;\n    const zMultiplier = maxInt / zwid;\n    const verify = (num) => num >= 0 ? num : 0;\n    for (let i = 0; i < lenPositions; i += 3) {\n        quantizedPositions[i + 0] = Math.floor(verify(positions[i + 0] - xmin) * xMultiplier);\n        quantizedPositions[i + 1] = Math.floor(verify(positions[i + 1] - ymin) * yMultiplier);\n        quantizedPositions[i + 2] = Math.floor(verify(positions[i + 2] - zmin) * zMultiplier);\n    }\n    math.identityMat4(translate$1);\n    math.translationMat4v(aabb, translate$1);\n    math.identityMat4(scale$1);\n    math.scalingMat4v([xwid / maxInt, ywid / maxInt, zwid / maxInt], scale$1);\n    math.mulMat4(translate$1, scale$1, positionsDecodeMatrix);\n    return quantizedPositions;\n}\n\n/**\n * @private\n * @param aabb\n * @param positionsDecodeMatrix\n * @returns {*}\n */\nfunction createPositionsDecodeMatrix(aabb, positionsDecodeMatrix) { // http://cg.postech.ac.kr/research/mesh_comp_mobile/mesh_comp_mobile_conference.pdf\n    const xmin = aabb[0];\n    const ymin = aabb[1];\n    const zmin = aabb[2];\n    const xwid = (aabb[3] - xmin) || 1;\n    const ywid = (aabb[4] - ymin) || 1;\n    const zwid = (aabb[5] - zmin) || 1;\n    const maxInt = 65525;\n    math.identityMat4(translate$1);\n    math.translationMat4v(aabb, translate$1);\n    math.identityMat4(scale$1);\n    math.scalingMat4v([xwid / maxInt, ywid / maxInt, zwid / maxInt], scale$1);\n    math.mulMat4(translate$1, scale$1, positionsDecodeMatrix);\n    return positionsDecodeMatrix;\n}\n\n/**\n * @private\n */\nfunction transformAndOctEncodeNormals(worldNormalMatrix, normals, lenNormals, compressedNormals, lenCompressedNormals) {\n    // http://jcgt.org/published/0003/02/01/\n\n    function dot(array, vec3) {\n        return array[0] * vec3[0] + array[1] * vec3[1] + array[2] * vec3[2];\n    }\n\n    let oct, dec, best, currentCos, bestCos;\n    let i;\n    let localNormal = new Float32Array([0, 0, 0, 0]);\n    let worldNormal = new Float32Array([0, 0, 0, 0]);\n    for (i = 0; i < lenNormals; i += 3) {\n        localNormal[0] = normals[i];\n        localNormal[1] = normals[i + 1];\n        localNormal[2] = normals[i + 2];\n\n        math.transformVec3(worldNormalMatrix, localNormal, worldNormal);\n        math.normalizeVec3(worldNormal, worldNormal);\n\n        // Test various combinations of ceil and floor to minimize rounding errors\n        best = oct = octEncodeVec3(worldNormal, \"floor\", \"floor\");\n        dec = octDecodeVec2(oct);\n        currentCos = bestCos = dot(worldNormal, dec);\n        oct = octEncodeVec3(worldNormal, \"ceil\", \"floor\");\n        dec = octDecodeVec2(oct);\n        currentCos = dot(worldNormal, dec);\n        if (currentCos > bestCos) {\n            best = oct;\n            bestCos = currentCos;\n        }\n        oct = octEncodeVec3(worldNormal, \"floor\", \"ceil\");\n        dec = octDecodeVec2(oct);\n        currentCos = dot(worldNormal, dec);\n        if (currentCos > bestCos) {\n            best = oct;\n            bestCos = currentCos;\n        }\n        oct = octEncodeVec3(worldNormal, \"ceil\", \"ceil\");\n        dec = octDecodeVec2(oct);\n        currentCos = dot(worldNormal, dec);\n        if (currentCos > bestCos) {\n            best = oct;\n            bestCos = currentCos;\n        }\n        compressedNormals[lenCompressedNormals + i + 0] = best[0];\n        compressedNormals[lenCompressedNormals + i + 1] = best[1];\n        compressedNormals[lenCompressedNormals + i + 2] = 0.0; // Unused\n    }\n    lenCompressedNormals += lenNormals;\n    return lenCompressedNormals;\n}\n\n/**\n * @private\n */\nfunction octEncodeVec3(p, xfunc, yfunc) { // Oct-encode single normal vector in 2 bytes\n    let x = p[0] / (Math.abs(p[0]) + Math.abs(p[1]) + Math.abs(p[2]));\n    let y = p[1] / (Math.abs(p[0]) + Math.abs(p[1]) + Math.abs(p[2]));\n    if (p[2] < 0) {\n        let tempx = x;\n        let tempy = y;\n        tempx = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n        tempy = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n        x = tempx;\n        y = tempy;\n    }\n    return new Int8Array([\n        Math[xfunc](x * 127.5 + (x < 0 ? -1 : 0)),\n        Math[yfunc](y * 127.5 + (y < 0 ? -1 : 0))\n    ]);\n}\n\n/**\n * @private\n */\nfunction octDecodeVec2(oct) { // Decode an oct-encoded normal\n    let x = oct[0];\n    let y = oct[1];\n    x /= x < 0 ? 127 : 128;\n    y /= y < 0 ? 127 : 128;\n    const z = 1 - Math.abs(x) - Math.abs(y);\n    if (z < 0) {\n        x = (1 - Math.abs(y)) * (x >= 0 ? 1 : -1);\n        y = (1 - Math.abs(x)) * (y >= 0 ? 1 : -1);\n    }\n    const length = Math.sqrt(x * x + y * y + z * z);\n    return [\n        x / length,\n        y / length,\n        z / length\n    ];\n}\n\nconst tempFloat32 = new Float32Array(1);\nconst tempFloat32Vec4 = new Float32Array(4);\nconst tempVec3fa = new Float32Array(3);\nconst tempMat4$1 = math.mat4();\nconst tempVec4a$a = math.vec4([0, 0, 0, 1]);\nconst tempVec4b$9 = math.vec4();\n\nconst tempVec3a$d = math.vec3();\nconst tempVec3b$9 = math.vec3();\nconst tempVec3c$7 = math.vec3();\nconst tempVec3d$2 = math.vec3();\nconst tempVec3e$1 = math.vec3();\nconst tempVec3f$1 = math.vec3();\nconst tempVec3g = math.vec3();\n\nconst tempUint8Array4 = new Uint8Array(4);\nconst matricesUniformBlockBufferData = new Float32Array(4 * 4 * 6); // there is 6 mat4\n\nconst iota$1 = function(n) {\n    const ret = [ ];\n    for (let i = 0; i < n; ++i) ret.push(i);\n    return ret;\n};\n\n// fills the whole dst array with src copies\nconst fillArray = function(dst, src) {\n    dst.set(src);\n    let soFar = src.length;\n    const allDataLen = dst.length;\n    while (soFar < allDataLen) {\n        const toCopy = Math.min(soFar, allDataLen - soFar);\n        dst.set(dst.subarray(0, toCopy), soFar);\n        soFar += toCopy;\n    }\n};\n\nconst scratchMemory = (function() {\n    /**\n     * Provides scratch memory for methods like TrianglesBatchingLayer setFlags() and setColors(),\n     * so they don't need to allocate temporary arrays that need garbage collection.\n     */\n    let cnt = 0;\n    const arrays = new Map();\n    return {\n        acquire: () => cnt++,\n        release: () => {\n            cnt--;\n            if (cnt === 0) {\n                arrays.clear();\n            }\n        },\n        getTypeArray: function(type, len) {\n            if (! arrays.has(type)) {\n                arrays.set(type, { });\n            }\n            const typeArrays = arrays.get(type);\n            if (! (len in typeArrays)) {\n                typeArrays[len] = new type(len);\n            }\n            return typeArrays[len];\n        }\n    };\n})();\n\n/**\n * @private\n */\nclass VBOLayer extends Layer {\n\n    /**\n     * @param model\n     * @param primitive\n     * @param origin\n     *\n     * @param cfg\n     * @param cfg.textureSet\n     *\n     * batching:\n     * @param cfg.positionsDecodeMatrix\n     * @param cfg.uvDecodeMatrix\n     * @param cfg.maxGeometryBatchSize\n     *\n     * instancing:\n     * @param cfg.geometry\n     */\n    constructor(model, primitive, origin, cfg) {\n\n        super(model, primitive, origin);\n\n        const instancing = !! cfg.geometry;\n\n        this._maxVerts = cfg.maxGeometryBatchSize;\n\n        const positionsDecodeMatrix = instancing ? cfg.geometry.positionsDecodeMatrix : cfg.positionsDecodeMatrix;\n        this._positionsDecodeMatrix = positionsDecodeMatrix && math.mat4(positionsDecodeMatrix);\n\n        this._cfgUvDecodeMatrix = cfg.uvDecodeMatrix && math.mat3(cfg.uvDecodeMatrix);\n        this._instancedGeometry = cfg.geometry;\n        this._textureSet = cfg.textureSet;\n\n        this._modelAABB = (! instancing) && math.collapseAABB3(); // Model-space AABB\n        this._portions = [ ];\n\n        const attribute = function() {\n            let length = 0;\n            const portions = [ ];\n\n            return {\n                length: () => length,\n                append: function(data, times = 1, denormalizeScale = 1.0, increment = 0.0) {\n                    length += times * data.length;\n                    portions.push({ data: data, times: times, denormalizeScale: denormalizeScale, increment: increment });\n                },\n                compileBuffer: function(type) {\n                    let len = 0;\n                    portions.forEach(p => { len += p.times * p.data.length; });\n                    const buf = new type(len);\n\n                    let begin = 0;\n                    portions.forEach(p => {\n                        const data = p.data;\n                        const dScale = p.denormalizeScale;\n                        const increment = p.increment;\n                        const subBuf = buf.subarray(begin);\n\n                        if ((dScale === 1.0) && (increment === 0.0)) {\n                            subBuf.set(data);\n                        } else {\n                            for (let i = 0; i < data.length; ++i) {\n                                subBuf[i] = increment + data[i] * dScale;\n                            }\n                        }\n\n                        let soFar = data.length;\n                        const allDataLen = p.times * data.length;\n                        while (soFar < allDataLen) {\n                            const toCopy = Math.min(soFar, allDataLen - soFar);\n                            subBuf.set(subBuf.subarray(0, toCopy), soFar);\n                            soFar += toCopy;\n                        }\n\n                        begin += soFar;\n                    });\n\n                    return buf;\n                }\n            };\n        };\n\n        this._buffer = {\n            colors:            attribute(), // in instancing used only for non-points\n            metallicRoughness: attribute(), // used for triangulated\n            pickColors:        attribute(), // used for non-lines\n            ...(instancing\n                ? {\n                    // Modeling matrix per instance, array for each column\n                    modelMatrixCol:       [ attribute(), attribute(), attribute() ],\n                    modelNormalMatrixCol: [ attribute(), attribute(), attribute() ]\n                }\n                : {\n                    positions:             attribute(),\n                    indices:               attribute(), // used for non-points\n                    uv:                    attribute(), // used for triangulated\n                    normals:               attribute(), // used for triangulated\n                    edgeIndices:           attribute(), // used for triangulated\n                })\n        };\n    }\n\n    /**\n     * Tests if there is room for another portion in this Layer.\n     *\n     * @param lenPositions Number of positions we'd like to create in the portion.\n     * @param lenIndices Number of indices we'd like to create in this portion.\n     * @returns {Boolean} True if OK to create another portion.\n     */\n    canCreatePortion(lenPositions, lenIndices) {\n        return this._instancedGeometry || (((this._buffer.positions.length() + lenPositions) <= (this._maxVerts * 3)) && ((this._buffer.indices.length() + lenIndices) <= (this._maxVerts * 3)));\n    }\n\n    /**\n     * Creates a new portion within this Layer, returns the new portion ID.\n     *\n     * @param mesh The SceneModelMesh that owns the portion\n     * @param cfg Portion params\n     * @param cfg.metallic Metalness factor [0..255] (triangulated)\n     * @param cfg.roughness Roughness factor [0..255] (triangulated)\n     * @param cfg.pickColor Quantized pick color (non-lines)\n     * @param cfg.meshMatrix Flat float 4x4 matrix (optional in batching)\n     * batching:\n     * @param cfg.positionsCompressed Flat quantized positions array - decompressed with positionsDecodeMatrix\n     * @param cfg.positions Flat float Local-space positions array.\n     * @param cfg.indices  Flat int indices array.\n     * @param [cfg.normalsCompressed]\n     * @param [cfg.normals] Flat float normals array (triangulated)\n     * @param [cfg.colors] Flat float colors array (non-lines)\n     * @param [cfg.colorsCompressed] Quantized RGB colors [0..255,0..255,0..255,0..255] (non-lines)\n     * @param cfg.color Float RGB color [0..1,0..1,0..1] (points) or Quantized RGB color [0..255,0..255,0..255,0..255] (non-points)\n     * @param cfg.opacity Opacity [0..255] (non-points)\n     * @param [cfg.uv] Flat UVs array (triangulated)\n     * @param [cfg.uvCompressed] (triangulated)\n     * @param [cfg.edgeIndices] Flat int edges indices array (triangulated)\n     * @param cfg.aabb Flat float AABB World-space AABB\n     * instancing:\n     * @param cfg.color Color [0..255,0..255,0..255]\n     * @param cfg.opacity Opacity [0..255].\n     * @returns {number} Portion ID\n     */\n    createPortion(mesh, cfg) {\n        const buffer            = this._buffer;\n        const instancedGeometry = this._instancedGeometry;\n        const model             = this.model;\n        const portionId         = this._portions.length;\n        const primitive         = this.primitive;\n        const useCompressed     = !! this._positionsDecodeMatrix;\n        const scene = model.scene;\n        const meshMatrix = cfg.meshMatrix;\n\n        const appendPortion = (portionBase, portionSize, indices, quantizedPositions, meshMatrix) => {\n            const prevPortion = (this._portions.length > 0) && this._portions[this._portions.length - 1];\n            const portion = {\n                indicesBaseIndex: prevPortion ? (prevPortion.indicesBaseIndex + prevPortion.numIndices) : 0,\n                numIndices: indices ? indices.length : 0,\n                portionBase: portionBase,\n                portionSize: portionSize,\n                retainedGeometry: scene.readableGeometryEnabled && (primitive !== \"points\") && (primitive !== \"lines\") && {\n                    indices:            indices,\n                    quantizedPositions: quantizedPositions,\n                    offset:             scene.entityOffsetsEnabled && math.vec3(),\n                    matrix:             meshMatrix && meshMatrix.slice(),\n                    inverseMatrix:      null, // Lazy-computed for instancing in precisionRayPickSurface\n                    normalMatrix:       null, // Lazy-computed for instancing in precisionRayPickSurface\n                }\n            };\n\n            if ((primitive !== \"points\") && (primitive !== \"lines\")) {\n                buffer.metallicRoughness.append([ cfg.metallic ?? 0, cfg.roughness ?? 255 ], portionSize);\n            }\n\n            if (primitive !== \"lines\") {\n                buffer.pickColors.append(cfg.pickColor.slice(0, 4), portionSize);\n            }\n\n            this._portions.push(portion);\n            model.numPortions++;\n            this._meshes.push(mesh);\n            return portionId;\n        };\n\n        if (instancedGeometry) {\n            buffer.modelMatrixCol.forEach((b, i) => b.append([ meshMatrix[i+0], meshMatrix[i+4], meshMatrix[i+8], meshMatrix[i+12] ]));\n\n            if (primitive !== \"points\") {\n                const color = cfg.color; // Color is pre-quantized by SceneModel\n                buffer.colors.append([ color[0], color[1], color[2], cfg.opacity ?? 255 ]);\n            }\n\n            if ((primitive !== \"points\") && (primitive !== \"lines\")) {\n                if (instancedGeometry.normals) {\n                    // Note: order of inverse and transpose doesn't matter\n                    const normalMatrix = math.inverseMat4(math.transposeMat4(meshMatrix, math.mat4()));\n                    buffer.modelNormalMatrixCol.forEach((b, i) => b.append([ normalMatrix[i+0], normalMatrix[i+4], normalMatrix[i+8], normalMatrix[i+12] ]));\n                }\n            }\n\n            return appendPortion(portionId, 1, instancedGeometry.indices, instancedGeometry.positionsCompressed, meshMatrix);\n        } else {\n            const vertsBaseIndex = buffer.positions.length() / 3;\n\n            const positions = useCompressed ? cfg.positionsCompressed : cfg.positions;\n            if (! positions) {\n                throw ((useCompressed ? \"positionsCompressed\" : \"positions\") + \" expected\");\n            }\n\n            buffer.positions.append(positions);\n\n            const numVerts = positions.length / 3;\n\n            const indices = cfg.indices;\n            if (indices) {\n                buffer.indices.append(indices, 1, 1.0, vertsBaseIndex);\n            }\n\n            const normalsCompressed = cfg.normalsCompressed;\n            const normals = cfg.normals;\n            if (normalsCompressed && normalsCompressed.length > 0) {\n                buffer.normals.append(normalsCompressed);\n            } else if (normals && normals.length > 0) {\n                const worldNormalMatrix = tempMat4$1;\n                if (meshMatrix) {\n                    math.transposeMat4(meshMatrix, worldNormalMatrix);\n                    math.inverseMat4(worldNormalMatrix, worldNormalMatrix); // Note: order of inverse and transpose doesn't matter\n                } else {\n                    math.identityMat4(worldNormalMatrix);\n                }\n                const normalsData = [ ];\n                transformAndOctEncodeNormals(worldNormalMatrix, normals, normals.length, normalsData, 0);\n                buffer.normals.append(normalsData);\n            }\n\n            const colors = cfg.colors;\n            const colorsCompressed = cfg.colorsCompressed;\n            const color = cfg.color;\n            if (colors) {\n                if (primitive === \"points\") {\n                    buffer.colors.append(colors, 1, 255.0);\n                } else {            // triangulated\n                    const colorsData = [ ];\n                    for (let i = 0, len = colors.length; i < len; i += 3) {\n                        colorsData.push(colors[i] * 255);\n                        colorsData.push(colors[i + 1] * 255);\n                        colorsData.push(colors[i + 2] * 255);\n                        colorsData.push(255);\n                    }\n                    buffer.colors.append(colorsData);\n                }\n            } else if (colorsCompressed) {\n                if (primitive === \"points\") {\n                    buffer.colors.append(colorsCompressed);\n                } else {            // triangulated\n                    const colorsData = [ ];\n                    for (let i = 0, len = colorsCompressed.length; i < len; i += 3) {\n                        colorsData.push(colorsCompressed[i]);\n                        colorsData.push(colorsCompressed[i + 1]);\n                        colorsData.push(colorsCompressed[i + 2]);\n                        colorsData.push(255);\n                    }\n                    buffer.colors.append(colorsData);\n                }\n            } else if (color) {\n                // Color is pre-quantized by VBOSceneModel\n                buffer.colors.append([ color[0], color[1], color[2], (primitive === \"points\") ? 1.0 : cfg.opacity ], numVerts);\n            }\n\n            const nonEmpty = v => v && (v.length > 0) && v;\n            const uv = nonEmpty(cfg.uv) || nonEmpty(cfg.uvCompressed);\n            if (uv) {\n                buffer.uv.append(uv);\n            }\n\n            const edgeIndices = cfg.edgeIndices;\n            if (edgeIndices) {\n                buffer.edgeIndices.append(edgeIndices, 1, 1.0, vertsBaseIndex);\n            }\n\n            math.expandAABB3(this._modelAABB, cfg.aabb);\n\n            // quantizedPositions are initialized in finalize()\n            return appendPortion(vertsBaseIndex, numVerts, indices);\n        }\n    }\n\n    compilePortions() {\n        const buffer              = this._buffer;\n        const instancedGeometry   = this._instancedGeometry;\n        const model               = this.model;\n        const modelAABB           = this._modelAABB;\n        const origin              = this.origin;\n        const portions            = this._portions;\n        const primitive           = this.primitive;\n        const textureSet          = this._textureSet;\n        let positionsDecodeMatrix = this._positionsDecodeMatrix;\n        const cfgUvDecodeMatrix   = this._cfgUvDecodeMatrix;\n\n        const scene = model.scene;\n        const gl = scene.canvas.gl;\n        const instancing = !! instancedGeometry;\n\n        const cleanups = [ ];\n\n        const createGlBuffer = (target, srcData, size, usage) => {\n            if (srcData.length > 0) {\n                const srcDataConstructor = srcData.constructor;\n                const [byteSize, type] = ({\n                    [Uint8Array]:   [1, gl.UNSIGNED_BYTE],\n                    [Int8Array]:    [1, gl.BYTE],\n                    [Uint16Array]:  [2, gl.UNSIGNED_SHORT],\n                    [Int16Array]:   [2, gl.SHORT],\n                    [Uint32Array]:  [4, gl.UNSIGNED_INT],\n                    [Int32Array]:   [4, gl.INT],\n                    [Float32Array]: [4, gl.FLOAT]\n                })[srcDataConstructor];\n\n                const buffer = gl.createBuffer();\n                cleanups.push(() => gl.deleteBuffer(buffer));\n\n                const bindBuffer = () => gl.bindBuffer(target, buffer);\n                const setData = data => {\n                    bindBuffer();\n                    gl.bufferData(target, data, usage);\n                };\n                setData(srcData);\n\n                const bytesPerElement = srcData.BYTES_PER_ELEMENT;\n                const numItems = srcData.length / size;\n                return {\n                    bindBuffer: bindBuffer,\n                    getData: (baseIndex = 0, length = numItems - baseIndex) => {\n                        bindBuffer();\n                        const array = new srcDataConstructor(length * size);\n                        gl.getBufferSubData(target, baseIndex * byteSize * size, array, 0, length * size);\n                        return array;\n                    },\n                    numItems: numItems,\n                    setData: setData,\n                    setSubData: (data, offset) => {\n                        bindBuffer();\n                        gl.bufferSubData(target, offset * bytesPerElement, data);\n                    },\n                    type: type\n                };\n            } else {\n                return null;\n            }\n        };\n\n        const maybeCreateBuffer = (srcData, size, usage, setDivisor = false, normalized = false) => {\n            const buf = createGlBuffer(gl.ARRAY_BUFFER, srcData, size, usage);\n            return buf && {\n                getData: buf.getData,\n                numItems: buf.numItems,\n                setData: buf.setData,\n                setSubData: buf.setSubData,\n                attributeDivisor: setDivisor && 1,\n                bindAtLocation: location => {\n                    buf.bindBuffer();\n                    gl.vertexAttribPointer(location, size, buf.type, !!normalized, 0, 0);\n                }\n            };\n        };\n\n        const maybeCreateIndicesBuffer = srcData => {\n            const buf = createGlBuffer(gl.ELEMENT_ARRAY_BUFFER, srcData, 1, gl.STATIC_DRAW);\n            return buf && {\n                getData: buf.getData,\n                bindIndicesBuffer: buf.bindBuffer,\n                indicesCount: srcData.length,\n                indicesType: buf.type\n            };\n        };\n\n        const attributesCnt = portions.reduce((acc,p) => acc + p.portionSize, 0);\n\n        const flagsBuf = maybeCreateBuffer(new Float32Array(attributesCnt), 1, gl.DYNAMIC_DRAW, instancing);\n\n        const createColorsBuf = (srcData, usage) => maybeCreateBuffer(srcData, 4, usage, instancing && (primitive !== \"points\"), true);\n        const colorsBuf = ((instancing && instancedGeometry.colorsCompressed)\n                           ? createColorsBuf(new Uint8Array(instancedGeometry.colorsCompressed), gl.STATIC_DRAW)\n                           : createColorsBuf(buffer.colors.compileBuffer(Uint8Array), gl.DYNAMIC_DRAW));\n\n        const offsetsBuf = scene.entityOffsetsEnabled && maybeCreateBuffer(new Float32Array(attributesCnt * 3), 3, gl.DYNAMIC_DRAW, instancing);\n\n        const metallicRoughnessBuf = maybeCreateBuffer(buffer.metallicRoughness.compileBuffer(Uint8Array), 2, gl.STATIC_DRAW, instancing);\n\n        const pickColorsBuf = maybeCreateBuffer(buffer.pickColors.compileBuffer(Uint8Array), 4, gl.STATIC_DRAW, instancing);\n\n        const edgeIndicesBuf = maybeCreateIndicesBuffer(instancing\n                                                        ? new Uint32Array(instancedGeometry.edgeIndices)\n                                                        : buffer.edgeIndices.compileBuffer(Uint32Array));\n\n        const indices = (instancing\n                         ? ((primitive !== \"points\") && instancedGeometry.indices && new Uint32Array(instancedGeometry.indices))\n                         : buffer.indices.compileBuffer(Uint32Array));\n        const indicesBuf = indices && maybeCreateIndicesBuffer(indices);\n\n        const positions = (instancing\n                           ? instancedGeometry.positionsCompressed\n                           : (positionsDecodeMatrix\n                              ? buffer.positions.compileBuffer(Uint16Array)\n                              : (quantizePositions(buffer.positions.compileBuffer(Float64Array), modelAABB, positionsDecodeMatrix = math.mat4()))));\n        const positionsBuf = positions && maybeCreateBuffer(positions, 3, gl.STATIC_DRAW);\n        if (! instancing) {\n            portions.forEach(portion => {\n                if (portion.retainedGeometry) {\n                    const start = 3 * portion.portionBase;\n                    portion.retainedGeometry.quantizedPositions = positions.subarray(start, start + 3 * portion.portionSize);\n                }\n            });\n        }\n\n        const modelMatrixColBufs = instancing && buffer.modelMatrixCol.map(b => maybeCreateBuffer(b.compileBuffer(Float32Array), 4, gl.STATIC_DRAW, true));\n\n        const normals = (instancing\n                         ? false // (primitive !== \"points\") && (primitive !== \"lines\") && instancedGeometry.normalsCompressed\n                         : buffer.normals.compileBuffer(Int8Array));\n        // Normals are already oct-encoded, so `normalized = true` for oct encoded UInts\n        const normalsBuf = normals && maybeCreateBuffer(normals, 3, gl.STATIC_DRAW, false, true);\n\n        // WARNING: modelMatrixColBufs and normalsBuf are never simultaneously defined at the moment (when instancing=true)\n        const modelNormalMatrixColBufs = modelMatrixColBufs && normalsBuf && buffer.modelNormalMatrixCol.map(b => maybeCreateBuffer(b.compileBuffer(Float32Array), 4, gl.STATIC_DRAW, true));\n\n        const uvSetup = (instancing\n                         ? ((primitive !== \"points\") && (primitive !== \"lines\") && instancedGeometry.uvCompressed && {\n                             buf: maybeCreateBuffer(instancedGeometry.uvCompressed, 2, gl.STATIC_DRAW),\n                             mat: instancedGeometry.uvDecodeMatrix\n                         })\n                         : (function() {\n                             const uvs = buffer.uv.compileBuffer(Float32Array);\n                             if (uvs.length === 0) {\n                                 return null;\n                             } else if (cfgUvDecodeMatrix) {\n                                 return {\n                                     buf: maybeCreateBuffer(uvs, 2, gl.STATIC_DRAW),\n                                     mat: cfgUvDecodeMatrix\n                                 };\n                             } else {\n                                 const bounds = geometryCompressionUtils.getUVBounds(uvs);\n                                 const result = geometryCompressionUtils.compressUVs(uvs, bounds.min, bounds.max);\n                                 return {\n                                     buf: maybeCreateBuffer(result.quantized, 2, gl.STATIC_DRAW),\n                                     mat: math.mat3(result.decodeMatrix)\n                                 };\n                             }\n                         })());\n\n        // Free up memory\n        this._buffer = null;\n\n        scratchMemory.acquire();\n        cleanups.push(() => scratchMemory.release());\n\n        let deferredFlagValues = null;\n\n        /**\n         * flags are 4bits values encoded on a 32bit base. color flag on the first 4 bits, silhouette flag on the next 4 bits and so on for edge, pick and clippable.\n         */\n        const setFlags = (portionId, flags, transparent, deferred = false) => {\n            getColSilhEdgePickFlags(flags, transparent, (primitive !== \"points\") && (primitive !== \"lines\"), scene, tempUint8Array4);\n\n            const clippableFlag = !!(flags & ENTITY_FLAGS.CLIPPABLE) ? 1 : 0;\n\n            let vertFlag = 0;\n            vertFlag |= tempUint8Array4[0];\n            vertFlag |= tempUint8Array4[1] << 4;\n            vertFlag |= tempUint8Array4[2] << 8;\n            vertFlag |= tempUint8Array4[3] << 12;\n            vertFlag |= clippableFlag << 16;\n\n            tempFloat32[0] = vertFlag;\n\n            const portion   = portions[portionId];\n            const firstFlag = portion.portionBase;\n            const lenFlags  = portion.portionSize;\n\n            if (deferred && (! instancedGeometry)) {\n                // Avoid zillions of individual WebGL bufferSubData calls - buffer them to apply in one shot\n                if (!deferredFlagValues) {\n                    deferredFlagValues = new Float32Array(attributesCnt);\n                }\n                fillArray(deferredFlagValues.subarray(firstFlag, firstFlag + lenFlags), tempFloat32);\n            } else if (flagsBuf) {\n                const tempArray = scratchMemory.getTypeArray(Float32Array, lenFlags);\n                fillArray(tempArray, tempFloat32);\n                flagsBuf.setSubData(tempArray, firstFlag);\n            }\n        };\n\n        const solid = (primitive === \"solid\");\n        return {\n            edgesColorOpaqueAllowed: () => true,\n            solid: solid,\n            sortId: (((primitive === \"points\") ? \"Points\" : ((primitive === \"lines\") ? \"Lines\" : \"Triangles\"))\n                     + (instancing ? \"Instancing\" : \"Batching\") + \"Layer\" +\n                     (((primitive !== \"points\") && (primitive !== \"lines\"))\n                      ? ((solid ? \"-solid\" : \"-surface\")\n                         + \"-autoNormals\"\n                         + (instancing\n                            ? \"\"\n                            // TODO: These two parts need to be IDs (ie. unique):\n                            : ((textureSet && textureSet.colorTexture ? \"-colorTexture\" : \"\")\n                               +\n                               (textureSet && textureSet.metallicRoughnessTexture ? \"-metallicRoughnessTexture\" : \"\"))))\n                      : \"\")),\n            setClippableFlags: setFlags,\n            setFlags: setFlags,\n            setFlags2: (portionId, flags, deferred) => { },\n            setDeferredFlags: () => {\n                if (deferredFlagValues) {\n                    flagsBuf.setData(deferredFlagValues);\n                    deferredFlagValues = null;\n                }\n            },\n\n            setColor: (portionId, color) => { // RGBA color is normalized as ints\n                if (colorsBuf) {\n                    const portion = portions[portionId];\n                    const tempArray = scratchMemory.getTypeArray(Uint8Array, portion.portionSize * 4);\n                    // alpha used to be unset for points, so effectively random (from last use)\n                    fillArray(tempArray, color.slice(0, 4));\n                    colorsBuf.setSubData(tempArray, portion.portionBase * 4);\n                }\n            },\n            setMatrix: (portionId, matrix) => {\n                if (modelMatrixColBufs) {\n                    modelMatrixColBufs.forEach((b, i) => {\n                        tempFloat32Vec4[0] = matrix[i+0];\n                        tempFloat32Vec4[1] = matrix[i+4];\n                        tempFloat32Vec4[2] = matrix[i+8];\n                        tempFloat32Vec4[3] = matrix[i+12];\n                        b.setSubData(tempFloat32Vec4, portionId * 4);\n                    });\n                }\n            },\n            setOffset: (portionId, offset) => {\n                if (!scene.entityOffsetsEnabled) {\n                    model.error(\"Entity#offset not enabled for this Viewer\"); // See Viewer entityOffsetsEnabled\n                } else {\n                    const portion = portions[portionId];\n                    if (offsetsBuf) {\n                        tempVec3fa.set(offset);\n                        const tempArray = scratchMemory.getTypeArray(Float32Array, portion.portionSize * 3);\n                        fillArray(tempArray, tempVec3fa);\n                        offsetsBuf.setSubData(tempArray, portion.portionBase * 3);\n                    }\n                    if (portion.retainedGeometry) {\n                        portion.retainedGeometry.offset.set(offset);\n                    }\n                }\n            },\n\n            getEachIndex: (portionId, callback) => {\n                const retainedGeometry = portions[portionId].retainedGeometry;\n                if (retainedGeometry) {\n                    retainedGeometry.indices.forEach(i => callback(i));\n                }\n            },\n            getEachVertex: (portionId, callback) => {\n                const retainedGeometry = portions[portionId].retainedGeometry;\n                if (retainedGeometry) {\n                    const origVec = tempVec4b$9;\n                    if (origin) {\n                        origVec.set(origin, 0);\n                    } else {\n                        origVec[0] = origVec[1] = origVec[2] = 0;\n                    }\n                    origVec[3] = 1;\n                    const sceneModelMatrix = model.matrix;\n                    math.mulMat4v4(sceneModelMatrix, origVec, origVec);\n                    const positions = retainedGeometry.quantizedPositions;\n                    const worldPos = tempVec4a$a;\n                    for (let i = 0, len = positions.length; i < len; i += 3) {\n                        worldPos[0] = positions[i];\n                        worldPos[1] = positions[i + 1];\n                        worldPos[2] = positions[i + 2];\n                        math.decompressPosition(worldPos, positionsDecodeMatrix);\n                        if (retainedGeometry.matrix) {\n                            math.transformPoint3(retainedGeometry.matrix, worldPos, worldPos);\n                        }\n                        worldPos[3] = 1;\n                        math.mulMat4v4(sceneModelMatrix, worldPos, worldPos);\n                        math.addVec3(origVec, worldPos, worldPos);\n                        callback(worldPos);\n                    }\n                }\n            },\n            readGeometryData: (primitive !== \"points\") && (primitive !== \"lines\") && ((portionId) => {\n                const portion = (! instancing) && portions[portionId];\n                const indices = (portion\n                                 ? indicesBuf.getData(portion.indicesBaseIndex, portion.numIndices).map(i => i - portion.portionBase)\n                                 : indicesBuf.getData());\n\n                const sceneModelMatrix = model.matrix;\n\n                const origin4 = math.vec4();\n                origin4.set(origin, 0); origin4[3] = 1;\n                math.mulMat4v4(sceneModelMatrix, origin4, origin4);\n\n                const instanceMatrix = modelMatrixColBufs && math.mat4();\n                if (instanceMatrix) {\n                    const col0 = modelMatrixColBufs[0].getData(portionId, 1);\n                    const col1 = modelMatrixColBufs[1].getData(portionId, 1);\n                    const col2 = modelMatrixColBufs[2].getData(portionId, 1);\n                    instanceMatrix.set([\n                        col0[0], col1[0], col2[0], 0,\n                        col0[1], col1[1], col2[1], 0,\n                        col0[2], col1[2], col2[2], 0,\n                        col0[3], col1[3], col2[3], 1,\n                    ]);\n                }\n\n                const matrix = math.mat4();\n                math.mulMat4(sceneModelMatrix, instanceMatrix ? math.mulMat4(instanceMatrix, positionsDecodeMatrix, matrix) : positionsDecodeMatrix, matrix);\n\n                matrix[12] += origin4[0];\n                matrix[13] += origin4[1];\n                matrix[14] += origin4[2];\n\n                const positionsQuantized = portion ? positionsBuf.getData(portion.portionBase, portion.portionSize) : positionsBuf.getData();\n\n                const positions = math.transformPositions3(\n                    matrix,\n                    positionsQuantized,\n                    new Float64Array(positionsQuantized.length));\n\n                return { indices, positions };\n            }),\n            precisionRayPickSurface: (portionId, worldRayOrigin, worldRayDir, worldSurfacePos, worldNormal) => {\n                const retainedGeometry = portions[portionId].retainedGeometry;\n                if (! retainedGeometry) {\n                    return false;\n                } else {\n                    if (retainedGeometry.matrix && (! retainedGeometry.inverseMatrix)) {\n                        retainedGeometry.inverseMatrix = math.inverseMat4(retainedGeometry.matrix, math.mat4());\n                    }\n\n                    if (worldNormal && retainedGeometry.inverseMatrix && (! retainedGeometry.normalMatrix)) {\n                        retainedGeometry.normalMatrix = math.transposeMat4(retainedGeometry.inverseMatrix, math.mat4());\n                    }\n\n                    const positions = retainedGeometry.quantizedPositions;\n                    const indices   = retainedGeometry.indices;\n                    const offset    = retainedGeometry.offset;\n\n                    const rtcRayOrigin = tempVec3a$d;\n                    const rtcRayDir = tempVec3b$9;\n\n                    rtcRayOrigin.set(origin ? math.subVec3(worldRayOrigin, origin, tempVec3c$7) : worldRayOrigin);  // World -> RTC\n                    rtcRayDir.set(worldRayDir);\n\n                    if (offset) {\n                        math.subVec3(rtcRayOrigin, offset);\n                    }\n\n                    math.transformRay(model.worldNormalMatrix, rtcRayOrigin, rtcRayDir, rtcRayOrigin, rtcRayDir); // RTC -> local\n\n                    if (retainedGeometry.inverseMatrix) {\n                        math.transformRay(retainedGeometry.inverseMatrix, rtcRayOrigin, rtcRayDir, rtcRayOrigin, rtcRayDir);\n                    }\n\n                    const a = tempVec3d$2;\n                    const b = tempVec3e$1;\n                    const c = tempVec3f$1;\n\n                    let gotIntersect = false;\n                    let closestDist = 0;\n                    const closestIntersectPos = tempVec3g;\n\n                    for (let i = 0, len = indices.length; i < len; i += 3) {\n\n                        const ia = indices[i] * 3;\n                        const ib = indices[i + 1] * 3;\n                        const ic = indices[i + 2] * 3;\n\n                        a[0] = positions[ia];\n                        a[1] = positions[ia + 1];\n                        a[2] = positions[ia + 2];\n\n                        b[0] = positions[ib];\n                        b[1] = positions[ib + 1];\n                        b[2] = positions[ib + 2];\n\n                        c[0] = positions[ic];\n                        c[1] = positions[ic + 1];\n                        c[2] = positions[ic + 2];\n\n                        math.decompressPosition(a, positionsDecodeMatrix);\n                        math.decompressPosition(b, positionsDecodeMatrix);\n                        math.decompressPosition(c, positionsDecodeMatrix);\n\n                        if (math.rayTriangleIntersect(rtcRayOrigin, rtcRayDir, a, b, c, closestIntersectPos)) {\n\n                            if (retainedGeometry.matrix) {\n                                math.transformPoint3(retainedGeometry.matrix, closestIntersectPos, closestIntersectPos);\n                            }\n\n                            math.transformPoint3(model.worldMatrix, closestIntersectPos, closestIntersectPos);\n\n                            if (offset) {\n                                math.addVec3(closestIntersectPos, offset);\n                            }\n\n                            if (origin) {\n                                math.addVec3(closestIntersectPos, origin);\n                            }\n\n                            const dist = Math.abs(math.lenVec3(math.subVec3(closestIntersectPos, worldRayOrigin, [])));\n\n                            if (!gotIntersect || dist > closestDist) {\n                                closestDist = dist;\n                                worldSurfacePos.set(closestIntersectPos);\n                                if (worldNormal) { // Not that wasteful to eagerly compute - unlikely to hit >2 surfaces on most geometry\n                                    math.triangleNormal(a, b, c, worldNormal);\n                                }\n                                gotIntersect = true;\n                            }\n                        }\n                    }\n\n                    if (gotIntersect && worldNormal) {\n                        if (retainedGeometry.normalMatrix) {\n                            math.transformVec3(retainedGeometry.normalMatrix, worldNormal, worldNormal);\n                        }\n                        math.transformVec3(model.worldNormalMatrix, worldNormal, worldNormal);\n                        math.normalizeVec3(worldNormal);\n                    }\n\n                    return gotIntersect;\n                }\n            },\n\n            layerTextureSet: textureSet,\n\n            renderers: getRenderers(scene, instancing ? \"instancing\" : \"batching\", primitive,\n                                    model.saoEnabled,\n                                    model.pbrEnabled          && uvSetup && textureSet && textureSet.colorTexture && normalsBuf && metallicRoughnessBuf && textureSet.metallicRoughnessTexture,\n                                    model.colorTextureEnabled && uvSetup && textureSet && textureSet.colorTexture,\n                                    !!normalsBuf,\n                                    (programVariables) => makeVBORenderingAttributes(programVariables, instancing && { hasModelNormalMat: !!modelNormalMatrixColBufs }, scene.entityOffsetsEnabled)),\n            drawCalls: (function() {\n                const drawCallCache = { };\n                const makeDrawer = (subGeometry) => (attributesHash, layerTypeInputs, viewState) => {\n                    let offset = 0;\n                    const mat4Size = 4 * 4;\n                    matricesUniformBlockBufferData.set(model.rotationMatrix, 0);\n                    matricesUniformBlockBufferData.set(viewState.viewMatrix, offset += mat4Size);\n                    matricesUniformBlockBufferData.set(viewState.projMatrix, offset += mat4Size);\n                    matricesUniformBlockBufferData.set(positionsDecodeMatrix, offset += mat4Size);\n                    if (layerTypeInputs.needNormal()) {\n                        matricesUniformBlockBufferData.set(model.worldNormalMatrix, offset += mat4Size);\n                        matricesUniformBlockBufferData.set(viewState.viewNormalMatrix, offset += mat4Size);\n                    }\n                    layerTypeInputs.matrices.setInputValue(matricesUniformBlockBufferData);\n\n                    layerTypeInputs.uvDecodeMatrix.setInputValue && layerTypeInputs.uvDecodeMatrix.setInputValue(uvSetup.mat);\n\n                    if (! (attributesHash in drawCallCache)) {\n                        drawCallCache[attributesHash] = [ null, null, null ];\n                    }\n                    const inputsCache = drawCallCache[attributesHash];\n                    const cacheKey = subGeometry ? (subGeometry.vertices ? 0 : 1) : 2;\n                    if (! inputsCache[cacheKey]) {\n                        const vao = gl.createVertexArray();\n                        gl.bindVertexArray(vao);\n\n                        const setAttr = (a, b) => { if (a && a.setInputValue && b) { a.setInputValue(b); } };\n                        const attrs = layerTypeInputs.attributes;\n                        setAttr(attrs.position, positionsBuf);\n                        setAttr(attrs.normal, normalsBuf);\n                        setAttr(attrs.color, colorsBuf);\n                        setAttr(attrs.pickColor, pickColorsBuf);\n                        setAttr(attrs.uV, uvSetup && uvSetup.buf);\n                        setAttr(attrs.metallicRoughness, metallicRoughnessBuf);\n                        setAttr(attrs.flags, flagsBuf);\n                        setAttr(attrs.offset, offsetsBuf);\n                        attrs.modelMatrixCol && attrs.modelMatrixCol.forEach((a, i) => setAttr(a, modelMatrixColBufs[i]));\n                        attrs.modelNormalMatrixCol && attrs.modelNormalMatrixCol.forEach((a, i) => setAttr(a, modelNormalMatrixColBufs[i]));\n\n                        const drawer = (function() {\n                            // TODO: Use drawElements count and offset to draw only one entity\n\n                            const drawPoints = () => {\n                                if (instancing) {\n                                    gl.drawArraysInstanced(gl.POINTS, 0, positionsBuf.numItems, portions.length);\n                                } else {\n                                    gl.drawArrays(gl.POINTS, 0, positionsBuf.numItems);\n                                }\n                            };\n\n                            const elementsDrawer = (mode, indicesBuf) => {\n                                indicesBuf.bindIndicesBuffer();\n                                const count = indicesBuf.indicesCount;\n                                const type = indicesBuf.indicesType;\n                                return () => {\n                                    if (instancing) {\n                                        gl.drawElementsInstanced(mode, count, type, 0, portions.length);\n                                    } else {\n                                        gl.drawElements(mode, count, type, 0);\n                                    }\n                                };\n                            };\n\n                            if (primitive === \"points\") {\n                                return drawPoints;\n                            } else if (primitive === \"lines\") {\n                                if (subGeometry && subGeometry.vertices) {\n                                    return drawPoints;\n                                } else {\n                                    return elementsDrawer(gl.LINES, indicesBuf);\n                                }\n                            } else {    // triangles\n                                if (subGeometry && subGeometry.vertices) {\n                                    return drawPoints;\n                                } else if (subGeometry) {\n                                    return edgeIndicesBuf ? elementsDrawer(gl.LINES, edgeIndicesBuf) : (() => { });\n                                } else {\n                                    return elementsDrawer(gl.TRIANGLES, indicesBuf);\n                                }\n                            }\n                        })();\n\n                        gl.bindVertexArray(null);\n\n                        cleanups.push(() => gl.deleteVertexArray(vao));\n\n                        inputsCache[cacheKey] = () => {\n                            gl.bindVertexArray(vao);\n                            drawer();\n                            gl.bindVertexArray(null);\n                        };\n                    }\n\n                    inputsCache[cacheKey]();\n                };\n\n                return {\n                    drawVertices: makeDrawer({ vertices: true }),\n                    drawEdges:    makeDrawer({ }),\n                    drawSurface:  makeDrawer(null)\n                };\n            })(),\n\n            destroy: () => {\n                cleanups.forEach(c => c());\n                cleanups.length = 0;\n            }\n        };\n    }\n}\n\nconst lazyShaderVariable = function(name) {\n    const variable = {\n        toString: () => {\n            variable.needed = true;\n            return name;\n        }\n    };\n    return variable;\n};\n\nconst makeVBORenderingAttributes = function(programVariables, instancing, entityOffsetsEnabled) {\n    const createAttribute = programVariables.createAttribute;\n\n    const attributes = {\n        position:             createAttribute(\"vec3\",  \"positionA\"),\n        normal:               createAttribute(\"vec3\",  \"normalA\"),\n        color:                createAttribute(\"vec4\",  \"colorA\"),\n        pickColor:            createAttribute(\"vec4\",  \"pickColor\"),\n        uV:                   createAttribute(\"vec2\",  \"uvApremul\"),\n        metallicRoughness:    createAttribute(\"vec2\",  \"metallicRoughness\"),\n        flags:                createAttribute(\"float\", \"flagsA\"),\n        offset:               entityOffsetsEnabled && createAttribute(\"vec3\", \"offset\"),\n        modelMatrixCol:       instancing && iota$1(3).map(i => createAttribute(\"vec4\", \"modelMatrixCol\" + i)),\n        modelNormalMatrixCol: instancing && instancing.hasModelNormalMat && iota$1(3).map(i => createAttribute(\"vec4\", \"modelNormalMatrixCol\" + i))\n    };\n\n    const uvA            = lazyShaderVariable(\"aUv\");\n    const viewNormal     = lazyShaderVariable(\"viewNormal\");\n    const worldNormal    = lazyShaderVariable(\"worldNormal\");\n    const uvDecodeMatrix = programVariables.createUniform(\"mat3\", \"uvDecodeMatrix\");\n\n    const needNormal = () => (viewNormal.needed || worldNormal.needed);\n    const matrices = programVariables.createUniformBlock(\n        \"Matrices\",\n        {\n            worldMatrix:           \"mat4\",\n            viewMatrix:            \"mat4\",\n            projMatrix:            \"mat4\",\n            positionsDecodeMatrix: \"mat4\",\n            worldNormalMatrix:     \"mat4\",\n            viewNormalMatrix:      \"mat4\"\n        });\n\n    return {\n        dontCullOnAlphaZero: true,\n\n        clippableTest: (function() {\n            const vClippable = programVariables.createVarying(\"float\", \"vClippable\", () => `${`((int(${attributes.flags}) >> 16 & 0xF) == 1)`} ? 1.0 : 0.0`); // Using `flat uint` for vClippable causes an instability - see XEOK-385\n            return () => `${vClippable} != 0.0`;\n        })(),\n\n        geometryParameters: {\n            attributes: {\n                color:             attributes.color,\n                flags:             iota$1(4).map(i => ({ toString: () => `(int(${attributes.flags}) >> ${i * 4} & 0xF)` })),\n                metallicRoughness: attributes.metallicRoughness,\n                normal:            {\n                    view:  viewNormal,\n                    world: worldNormal\n                },\n                pickColor:         attributes.pickColor,\n                position:          {\n                    clip:  \"gl_Position\",\n                    view:  \"viewPosition\",\n                    world: \"worldPosition\"\n                },\n                uv:                uvA\n            },\n            projMatrix: matrices.projMatrix,\n            viewMatrix: matrices.viewMatrix\n        },\n\n        appendVertexData: (src) => {\n            uvA.needed && src.push(`vec2 ${uvA} = (${uvDecodeMatrix} * vec3(${attributes.uV}, 1.0)).xy;`);\n\n            const modelMatrixTransposed = attributes.modelMatrixCol && `mat4(${attributes.modelMatrixCol[0]}, ${attributes.modelMatrixCol[1]}, ${attributes.modelMatrixCol[2]}, vec4(0.0,0.0,0.0,1.0))`;\n            src.push(`vec4 worldPosition = ${matrices.worldMatrix} * (${matrices.positionsDecodeMatrix} * vec4(${attributes.position}, 1.0)${modelMatrixTransposed ? (\" * \" + modelMatrixTransposed) : \"\"});`);\n            attributes.offset && src.push(`worldPosition.xyz = worldPosition.xyz + ${attributes.offset};`);\n\n            if (needNormal()) {\n                const timesModelNormalMatrixT = attributes.modelNormalMatrixCol && `* mat4(${attributes.modelNormalMatrixCol[0]}, ${attributes.modelNormalMatrixCol[1]}, ${attributes.modelNormalMatrixCol[2]}, vec4(0.0,0.0,0.0,1.0))`;\n                src.push(`vec4 modelNormal = vec4(${programVariables.commonLibrary.octDecode}(${attributes.normal}.xy), 0.0)${timesModelNormalMatrixT || \"\"};`);\n                src.push(`vec3 ${worldNormal} = (${matrices.worldNormalMatrix} * modelNormal).xyz;`);\n                if (viewNormal.needed) {\n                    src.push(`vec3 ${viewNormal} = normalize((${matrices.viewNormalMatrix} * vec4(${worldNormal}, 0.0)).xyz);`);\n                }\n            }\n        },\n\n        layerTypeInputs: {\n            attributes:     attributes,\n            matrices:       matrices,\n            uvDecodeMatrix: uvDecodeMatrix,\n            needNormal:     needNormal\n        }\n    };\n};\n\n/**\n * A texture set within a {@link SceneModel}.\n *\n * * Created with {@link SceneModel#createTextureSet}\n * * Belongs to many {@link SceneModelMesh}es\n * * Stored by ID in {@link SceneModel#textureSets}\n * * Referenced by {@link SceneModelMesh#textureSet}\n */\nclass SceneModelTextureSet {\n\n    /**\n     * @private\n     */\n    constructor(cfg) {\n\n        /**\n         * Unique ID of this SceneModelTextureSet.\n         *\n         * The SceneModelTextureSet is registered against this ID in {@link SceneModel#textureSets}.\n         */\n        this.id = cfg.id;\n\n        /**\n         * The color texture.\n         * @type {SceneModelTexture|*}\n         */\n        this.colorTexture = cfg.colorTexture;\n\n        /**\n         * The alpha cutoff [float]\n         */\n        this.alphaCutoff = cfg.alphaCutoff;\n\n        /**\n         * The metallic-roughness texture.\n         * @type {SceneModelTexture|*}\n         */\n        this.metallicRoughnessTexture = cfg.metallicRoughnessTexture;\n\n        /**\n         * The normal map texture.\n         * @type {SceneModelTexture|*}\n         */\n        this.normalsTexture = cfg.normalsTexture;\n\n        /**\n         * The emissive color texture.\n         * @type {SceneModelTexture|*}\n         */\n        this.emissiveTexture = cfg.emissiveTexture;\n\n        /**\n         * The ambient occlusion texture.\n         * @type {SceneModelTexture|*}\n         */\n        this.occlusionTexture = cfg.occlusionTexture;\n    }\n\n    /**\n     * @private\n     */\n    destroy() {\n    }\n}\n\n/**\n * A texture within a {@link SceneModelTextureSet}.\n *\n * * Created with {@link SceneModel#createTexture}\n * * Belongs to many {@link SceneModelTextureSet}s\n * * Stored by ID in {@link SceneModel#textures}}\n */\nclass SceneModelTexture {\n\n    /**\n     * @private\n     * @param cfg\n     */\n    constructor(cfg) {\n\n        /**\n         * Unique ID of this SceneModelTexture.\n         *\n         * The SceneModelTexture is registered against this ID in {@link SceneModel#textures}.\n         */\n        this.id = cfg.id;\n\n        /**\n         * @private\n         */\n        this.texture = cfg.texture;\n    }\n\n    /**\n     * @private\n     */\n    destroy() {\n        if (this.texture) {\n            this.texture.destroy();\n            this.texture = null;\n        }\n    }\n}\n\nconst Cache$1 = {\n\n    enabled: false,\n    files: {},\n\n    add: function (key, file) {\n        if (this.enabled === false) {\n            return;\n        }\n        this.files[key] = file;\n    },\n\n    get: function (key) {\n        if (this.enabled === false) {\n            return;\n        }\n        return this.files[key];\n    },\n\n    remove: function (key) {\n        delete this.files[key];\n    },\n\n    clear: function () {\n        this.files = {};\n    }\n};\n\nclass LoadingManager {\n\n    constructor(onLoad, onProgress, onError) {\n\n        this.isLoading = false;\n        this.itemsLoaded = 0;\n        this.itemsTotal = 0;\n        this.urlModifier = undefined;\n        this.handlers = [];\n\n        this.onStart = undefined;\n        this.onLoad = onLoad;\n        this.onProgress = onProgress;\n        this.onError = onError;\n    }\n\n    itemStart(url) {\n        this.itemsTotal++;\n        if (this.isLoading === false) {\n            if (this.onStart !== undefined) {\n                this.onStart(url, this.itemsLoaded, this.itemsTotal);\n            }\n        }\n        this.isLoading = true;\n    }\n\n    itemEnd(url) {\n        this.itemsLoaded++;\n        if (this.onProgress !== undefined) {\n            this.onProgress(url, this.itemsLoaded, this.itemsTotal);\n        }\n        if (this.itemsLoaded === this.itemsTotal) {\n            this.isLoading = false;\n            if (this.onLoad !== undefined) {\n                this.onLoad();\n            }\n        }\n    }\n\n    itemError(url) {\n        if (this.onError !== undefined) {\n            this.onError(url);\n        }\n    }\n\n    resolveURL(url) {\n        if (this.urlModifier) {\n            return this.urlModifier(url);\n        }\n        return url;\n    }\n\n    setURLModifier(transform) {\n        this.urlModifier = transform;\n        return this;\n    }\n\n    addHandler(regex, loader) {\n        this.handlers.push(regex, loader);\n        return this;\n    }\n\n    removeHandler(regex) {\n        const index = this.handlers.indexOf(regex);\n        if (index !== -1) {\n            this.handlers.splice(index, 2);\n        }\n        return this;\n    }\n\n    getHandler(file) {\n        for (let i = 0, l = this.handlers.length; i < l; i += 2) {\n            const regex = this.handlers[i];\n            const loader = this.handlers[i + 1];\n            if (regex.global) regex.lastIndex = 0; // see #17920\n            if (regex.test(file)) {\n                return loader;\n            }\n        }\n        return null;\n    }\n}\n\nconst DefaultLoadingManager = new LoadingManager();\n\nclass Loader {\n\n    constructor(manager) {\n\n        this.manager = (manager !== undefined) ? manager : DefaultLoadingManager;\n\n        this.crossOrigin = 'anonymous';\n        this.withCredentials = false;\n        this.path = '';\n        this.resourcePath = '';\n        this.requestHeader = {};\n    }\n\n    load( /* url, onLoad, onProgress, onError */) {\n    }\n\n    loadAsync(url, onProgress) {\n        const scope = this;\n        return new Promise(function (resolve, reject) {\n            scope.load(url, resolve, onProgress, reject);\n        });\n    }\n\n    parse( /* data */) {\n    }\n\n    setCrossOrigin(crossOrigin) {\n        this.crossOrigin = crossOrigin;\n        return this;\n    }\n\n    setWithCredentials(value) {\n        this.withCredentials = value;\n        return this;\n    }\n\n    setPath(path) {\n        this.path = path;\n        return this;\n    }\n\n    setResourcePath(resourcePath) {\n        this.resourcePath = resourcePath;\n        return this;\n    }\n\n    setRequestHeader(requestHeader) {\n        this.requestHeader = requestHeader;\n        return this;\n    }\n}\n\nconst loading = {};\n\nclass FileLoader extends Loader {\n\n    constructor(manager) {\n        super(manager);\n    }\n\n    load(url, onLoad, onProgress, onError) {\n        if (url === undefined) {\n            url = '';\n        }\n        if (this.path !== undefined) {\n            url = this.path + url;\n        }\n        url = this.manager.resolveURL(url);\n        const cached = Cache$1.get(url);\n        if (cached !== undefined) {\n            this.manager.itemStart(url);\n            core.scheduleTask(() => {\n                if (onLoad) {\n                    onLoad(cached);\n                }\n                this.manager.itemEnd(url);\n            }, 0);\n            return cached;\n        }\n        if (loading[url] !== undefined) {\n            loading[url].push({onLoad, onProgress, onError});\n            return;\n        }\n        loading[url] = [];\n        loading[url].push({onLoad, onProgress, onError});\n        const req = new Request(url, {\n            headers: new Headers(this.requestHeader),\n            credentials: this.withCredentials ? 'include' : 'same-origin'\n        });\n        const mimeType = this.mimeType;\n        const responseType = this.responseType;\n        fetch(req).then(response => {\n            if (response.status === 200 || response.status === 0) {\n                // Some browsers return HTTP Status 0 when using non-http protocol\n                // e.g. 'file://' or 'data://'. Handle as success.\n                if (response.status === 0) {\n                    console.warn('FileLoader: HTTP Status 0 received.');\n                }\n                if (typeof ReadableStream === 'undefined' || response.body.getReader === undefined) {\n                    return response;\n                }\n                const callbacks = loading[url];\n                const reader = response.body.getReader();\n                const contentLength = response.headers.get('Content-Length');\n                const total = contentLength ? parseInt(contentLength) : 0;\n                const lengthComputable = total !== 0;\n                let loaded = 0;\n                const stream = new ReadableStream({\n                    start(controller) {\n                        readData();\n\n                        function readData() {\n                            reader.read().then(({done, value}) => {\n                                if (done) {\n                                    controller.close();\n                                } else {\n                                    loaded += value.byteLength;\n                                    const event = new ProgressEvent('progress', {lengthComputable, loaded, total});\n                                    for (let i = 0, il = callbacks.length; i < il; i++) {\n                                        const callback = callbacks[i];\n                                        if (callback.onProgress) {\n                                            callback.onProgress(event);\n                                        }\n                                    }\n                                    controller.enqueue(value);\n                                    readData();\n                                }\n                            });\n                        }\n                    }\n                });\n                return new Response(stream);\n            } else {\n                throw Error(`fetch for \"${response.url}\" responded with ${response.status}: ${response.statusText}`);\n            }\n        }).then(response => {\n            switch (responseType) {\n                case 'arraybuffer':\n                    return response.arrayBuffer();\n                case 'blob':\n                    return response.blob();\n                case 'document':\n                    return response.text()\n                        .then(text => {\n                            const parser = new DOMParser();\n                            return parser.parseFromString(text, mimeType);\n                        });\n                case 'json':\n                    return response.json();\n                default:\n                    if (mimeType === undefined) {\n                        return response.text();\n                    } else {\n                        // sniff encoding\n                        const re = /charset=\"?([^;\"\\s]*)\"?/i;\n                        const exec = re.exec(mimeType);\n                        const label = exec && exec[1] ? exec[1].toLowerCase() : undefined;\n                        const decoder = new TextDecoder(label);\n                        return response.arrayBuffer().then(ab => decoder.decode(ab));\n                    }\n            }\n        }).then(data => {\n            // Add to cache only on HTTP success, so that we do not cache\n            // error response bodies as proper responses to requests.\n            Cache$1.add(url, data);\n            const callbacks = loading[url];\n            delete loading[url];\n            for (let i = 0, il = callbacks.length; i < il; i++) {\n                const callback = callbacks[i];\n                if (callback.onLoad) {\n                    callback.onLoad(data);\n                }\n            }\n        }).catch(err => {\n            // Abort errors and other errors are handled the same\n            const callbacks = loading[url];\n            if (callbacks === undefined) {\n                // When onLoad was called and url was deleted in `loading`\n                this.manager.itemError(url);\n                throw err;\n\n            }\n            delete loading[url];\n            for (let i = 0, il = callbacks.length; i < il; i++) {\n                const callback = callbacks[i];\n                if (callback.onError) {\n                    callback.onError(err);\n                }\n            }\n            this.manager.itemError(url);\n        }).finally(() => {\n            this.manager.itemEnd(url);\n        });\n        this.manager.itemStart(url);\n    }\n\n    setResponseType(value) {\n        this.responseType = value;\n        return this;\n    }\n\n    setMimeType(value) {\n        this.mimeType = value;\n        return this;\n    }\n}\n\n/**\n * @author Deepkolos / https://github.com/deepkolos\n */\n\nclass WorkerPool$1 {\n\n    constructor(pool = 4) {\n        this.pool = pool;\n        this.queue = [];\n        this.workers = [];\n        this.workersResolve = [];\n        this.workerStatus = 0;\n    }\n\n    _initWorker(workerId) {\n        if (!this.workers[workerId]) {\n            const worker = this.workerCreator();\n            worker.addEventListener('message', this._onMessage.bind(this, workerId));\n            this.workers[workerId] = worker;\n        }\n    }\n\n    _getIdleWorker() {\n        for (let i = 0; i < this.pool; i++)\n            if (!(this.workerStatus & (1 << i))) return i;\n        return -1;\n    }\n\n    _onMessage(workerId, msg) {\n        const resolve = this.workersResolve[workerId];\n        resolve && resolve(msg);\n        if (this.queue.length) {\n            const {resolve, msg, transfer} = this.queue.shift();\n            this.workersResolve[workerId] = resolve;\n            this.workers[workerId].postMessage(msg, transfer);\n        } else {\n            this.workerStatus ^= 1 << workerId;\n        }\n    }\n\n    setWorkerCreator(workerCreator) {\n        this.workerCreator = workerCreator;\n    }\n\n    setWorkerLimit(pool) {\n        this.pool = pool;\n    }\n\n    postMessage(msg, transfer) {\n        return new Promise((resolve) => {\n            const workerId = this._getIdleWorker();\n            if (workerId !== -1) {\n                this._initWorker(workerId);\n                this.workerStatus |= 1 << workerId;\n                this.workersResolve[workerId] = resolve;\n                this.workers[workerId].postMessage(msg, transfer);\n            } else {\n                this.queue.push({resolve, msg, transfer});\n            }\n        });\n    }\n\n    destroy() {\n\n        this.workers.forEach((worker) => worker.terminate());\n        this.workersResolve.length = 0;\n        this.workers.length = 0;\n        this.queue.length = 0;\n        this.workerStatus = 0;\n\n    }\n\n}\n\nconst KTX2TransferSRGB = 2;\nconst KTX2_ALPHA_PREMULTIPLIED = 1;\n\nlet activeTranscoders = 0;\n\n/**\n * Transcodes texture data from KTX2.\n *\n * ## Overview\n *\n * * Uses the [Basis Universal GPU Texture Codec](https://github.com/BinomialLLC/basis_universal) to\n * transcode [KTX2](https://github.khronos.org/KTX-Specification/) textures.\n * * {@link XKTLoaderPlugin} uses a KTX2TextureTranscoder to load textures in XKT files.\n * * {@link VBOSceneModel} uses a KTX2TextureTranscoder to enable us to add KTX2-encoded textures.\n * * Loads the Basis Codec from [CDN](https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/) by default, but can\n * also be configured to load the Codec from local files.\n * * We also bundle the Basis Codec with the xeokit-sdk npm package, and in the [repository](https://github.com/xeokit/xeokit-sdk/tree/master/dist/basis).\n *\n * ## What is KTX2?\n *\n * A [KTX2](https://github.khronos.org/KTX-Specification/) file stores GPU texture data in the Khronos Texture 2.0 (KTX2) container format. It contains image data for\n * a texture asset compressed with Basis Universal (BasisU) supercompression that can be transcoded to different formats\n * depending on the support provided by the target devices. KTX2 provides a lightweight format for distributing texture\n * assets to GPUs. Due to BasisU compression, KTX2 files can store any image format supported by GPUs.\n *\n * ## Loading XKT files containing KTX2 textures\n *\n * {@link XKTLoaderPlugin} uses a KTX2TextureTranscoder to load textures in XKT files. An XKTLoaderPlugin has its own\n * default KTX2TextureTranscoder, configured to load the Basis Codec from the [CDN](https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/). If we wish, we can override that with our own\n * KTX2TextureTranscoder, configured to load the Codec locally.\n *\n * In the example below, we'll create a {@link Viewer} and add an {@link XKTLoaderPlugin}\n * configured with a KTX2TextureTranscoder. Then we'll use the XKTLoaderPlugin to load an\n * XKT file that contains KTX2 textures, which the plugin will transcode using\n * its KTX2TextureTranscoder.\n *\n * We'll configure our KTX2TextureTranscoder to load the Basis Codec from a local directory. If we were happy with loading the\n * Codec from our [CDN](https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/) (ie. our app will always have an Internet connection) then we could just leave out the\n * KTX2TextureTranscoder altogether, and let the XKTLoaderPlugin use its internal default KTX2TextureTranscoder, which is configured to\n * load the Codec from the CDN. We'll stick with loading our own Codec, in case we want to run our app without an Internet connection.\n *\n * <a href=\"https://xeokit.github.io/xeokit-sdk/examples/buildings/#xkt_vbo_textures_HousePlan\"><img src=\"https://xeokit.github.io/xeokit-sdk/assets/images/xktWithTextures.png\"></a>\n *\n * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/buildings/#xkt_vbo_textures_HousePlan)]\n *\n * ````javascript\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.camera.eye = [-2.56, 8.38, 8.27];\n * viewer.camera.look = [13.44, 3.31, -14.83];\n * viewer.camera.up = [0.10, 0.98, -0.14];\n *\n * const textureTranscoder = new KTX2TextureTranscoder({\n *     viewer,\n *     transcoderPath: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\" // <------ Path to Basis Universal transcoder\n * });\n *\n * const xktLoader = new XKTLoaderPlugin(viewer, {\n *     textureTranscoder // <<------------- Transcodes KTX2 textures in XKT files\n * });\n *\n * const sceneModel = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./HousePlan.xkt\" // <<------ XKT file with KTX2 textures\n * });\n * ````\n *\n * ## Loading KTX2 files into a VBOSceneModel\n *\n * A {@link SceneModel} that is configured with a KTX2TextureTranscoder will\n * allow us to load textures into it from KTX2-transcoded buffers or files.\n *\n * In the example below, we'll create a {@link Viewer}, containing a {@link VBOSceneModel} configured with a\n * KTX2TextureTranscoder.\n *\n * We'll then programmatically create a simple object within the VBOSceneModel, consisting of\n * a single box mesh with a texture loaded from a KTX2 file, which our VBOSceneModel internally transcodes, using\n * its KTX2TextureTranscoder.\n *\n * As in the previous example, we'll configure our KTX2TextureTranscoder to load the Basis Codec from a local directory.\n *\n * * [Run a similar example](https://xeokit.github.io/xeokit-sdk/examples/scenemodel/#vbo_batching_autocompressed_triangles_textures_ktx2)\n *\n * ````javascript\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * const textureTranscoder = new KTX2TextureTranscoder({\n *     viewer,\n *     transcoderPath: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\" // <------ Path to BasisU transcoder module\n * });\n *\n * const vboSceneModel = new VBOSceneModel(viewer.scene, {\n *      id: \"myModel\",\n *      textureTranscoder // <<-------------------- Configure model with our transcoder\n *  });\n *\n * vboSceneModel.createTexture({\n *      id: \"myColorTexture\",\n *      src: \"../assets/textures/compressed/sample_uastc_zstd.ktx2\" // <<----- KTX2 texture asset\n * });\n *\n * vboSceneModel.createTexture({\n *      id: \"myMetallicRoughnessTexture\",\n *      src: \"../assets/textures/alpha/crosshatchAlphaMap.jpg\" // <<----- JPEG texture asset\n * });\n *\n * vboSceneModel.createTextureSet({\n *      id: \"myTextureSet\",\n *      colorTextureId: \"myColorTexture\",\n *      metallicRoughnessTextureId: \"myMetallicRoughnessTexture\"\n *  });\n *\n * vboSceneModel.createMesh({\n *      id: \"myMesh\",\n *      textureSetId: \"myTextureSet\",\n *      primitive: \"triangles\",\n *      positions: [1, 1, 1, ...],\n *      normals: [0, 0, 1, 0, ...],\n *      uv: [1, 0, 0, ...],\n *      indices: [0, 1, 2, ...],\n *  });\n *\n * vboSceneModel.createEntity({\n *      id: \"myEntity\",\n *      meshIds: [\"myMesh\"]\n *  });\n *\n * vboSceneModel.finalize();\n * ````\n *\n * ## Loading KTX2 ArrayBuffers into a VBOSceneModel\n *\n * A {@link SceneModel} that is configured with a KTX2TextureTranscoder will also allow us to load textures into\n * it from KTX2 ArrayBuffers.\n *\n * In the example below, we'll create a {@link Viewer}, containing a {@link VBOSceneModel} configured with a\n * KTX2TextureTranscoder.\n *\n * We'll then programmatically create a simple object within the VBOSceneModel, consisting of\n * a single mesh with a texture loaded from a KTX2 ArrayBuffer, which our VBOSceneModel internally transcodes, using\n * its KTX2TextureTranscoder.\n *\n * ````javascript\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * const textureTranscoder = new KTX2TextureTranscoder({\n *     viewer,\n *     transcoderPath: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\" // <------ Path to BasisU transcoder module\n * });\n *\n * const vboSceneModel = new VBOSceneModel(viewer.scene, {\n *      id: \"myModel\",\n *      textureTranscoder // <<-------------------- Configure model with our transcoder\n * });\n *\n * utils.loadArraybuffer(\"../assets/textures/compressed/sample_uastc_zstd.ktx2\",(arrayBuffer) => {\n *\n *     vboSceneModel.createTexture({\n *         id: \"myColorTexture\",\n *         buffers: [arrayBuffer] // <<----- KTX2 texture asset\n *     });\n *\n *     vboSceneModel.createTexture({\n *         id: \"myMetallicRoughnessTexture\",\n *         src: \"../assets/textures/alpha/crosshatchAlphaMap.jpg\" // <<----- JPEG texture asset\n *     });\n *\n *     vboSceneModel.createTextureSet({\n *        id: \"myTextureSet\",\n *        colorTextureId: \"myColorTexture\",\n *        metallicRoughnessTextureId: \"myMetallicRoughnessTexture\"\n *     });\n *\n *     vboSceneModel.createMesh({\n *          id: \"myMesh\",\n *          textureSetId: \"myTextureSet\",\n *          primitive: \"triangles\",\n *          positions: [1, 1, 1, ...],\n *          normals: [0, 0, 1, 0, ...],\n *          uv: [1, 0, 0, ...],\n *          indices: [0, 1, 2, ...],\n *     });\n *\n *     vboSceneModel.createEntity({\n *         id: \"myEntity\",\n *         meshIds: [\"myMesh\"]\n *     });\n *\n *     vboSceneModel.finalize();\n * });\n * ````\n *\n * @implements {TextureTranscoder}\n */\nclass KTX2TextureTranscoder {\n\n    /**\n     * Creates a new KTX2TextureTranscoder.\n     *\n     * @param {Viewer} viewer The Viewer that our KTX2TextureTranscoder will be used with. This KTX2TextureTranscoder\n     * must only be used to transcode textures for this Viewer. This is because the Viewer's capabilities will decide\n     * what target GPU formats this KTX2TextureTranscoder will transcode to.\n     * @param {String} [transcoderPath=\"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\"] Path to the Basis\n     * transcoder module that internally does the heavy lifting for our KTX2TextureTranscoder. If we omit this configuration,\n     * then our KTX2TextureTranscoder will load it from ````https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/```` by\n     * default. Therefore, make sure your application is connected to the internet if you wish to use the default transcoder path.\n     * @param {Number} [workerLimit] The maximum number of Workers to use for transcoding.\n     */\n    constructor({viewer, transcoderPath, workerLimit}) {\n\n        this._transcoderPath = transcoderPath || \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\";\n        this._transcoderBinary = null;\n        this._transcoderPending = null;\n        this._workerPool = new WorkerPool$1();\n        this._workerSourceURL = '';\n\n        if (workerLimit) {\n            this._workerPool.setWorkerLimit(workerLimit);\n        }\n\n        const viewerCapabilities = viewer.capabilities;\n\n        this._workerConfig = {\n            astcSupported: viewerCapabilities.astcSupported,\n            etc1Supported: viewerCapabilities.etc1Supported,\n            etc2Supported: viewerCapabilities.etc2Supported,\n            dxtSupported: viewerCapabilities.dxtSupported,\n            bptcSupported: viewerCapabilities.bptcSupported,\n            pvrtcSupported: viewerCapabilities.pvrtcSupported\n        };\n\n        this._supportedFileTypes = [\"xkt2\"];\n    }\n\n    _init() {\n        if (!this._transcoderPending) {\n            const jsLoader = new FileLoader();\n            jsLoader.setPath(this._transcoderPath);\n            jsLoader.setWithCredentials(this.withCredentials);\n            const jsContent = jsLoader.loadAsync('basis_transcoder.js');\n            const binaryLoader = new FileLoader();\n            binaryLoader.setPath(this._transcoderPath);\n            binaryLoader.setResponseType('arraybuffer');\n            binaryLoader.setWithCredentials(this.withCredentials);\n            const binaryContent = binaryLoader.loadAsync('basis_transcoder.wasm');\n            this._transcoderPending = Promise.all([jsContent, binaryContent])\n                .then(([jsContent, binaryContent]) => {\n                    const fn = KTX2TextureTranscoder.BasisWorker.toString();\n                    const body = [\n                        '/* constants */',\n                        'let _EngineFormat = ' + JSON.stringify(KTX2TextureTranscoder.EngineFormat),\n                        'let _TranscoderFormat = ' + JSON.stringify(KTX2TextureTranscoder.TranscoderFormat),\n                        'let _BasisFormat = ' + JSON.stringify(KTX2TextureTranscoder.BasisFormat),\n                        '/* basis_transcoder.js */',\n                        jsContent,\n                        '/* worker */',\n                        fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))\n                    ].join('\\n');\n                    this._workerSourceURL = URL.createObjectURL(new Blob([body]));\n                    this._transcoderBinary = binaryContent;\n                    this._workerPool.setWorkerCreator(() => {\n                        const worker = new Worker(this._workerSourceURL);\n                        const transcoderBinary = this._transcoderBinary.slice(0);\n                        worker.postMessage({\n                            type: 'init',\n                            config: this._workerConfig,\n                            transcoderBinary\n                        }, [transcoderBinary]);\n                        return worker;\n                    });\n                });\n            if (activeTranscoders > 0) {\n                console.warn('KTX2TextureTranscoder: Multiple active KTX2TextureTranscoder may cause performance issues.' + ' Use a single KTX2TextureTranscoder instance, or call .dispose() on old instances.');\n            }\n            activeTranscoders++;\n        }\n        return this._transcoderPending;\n    }\n\n    /**\n     * Transcodes texture data from transcoded buffers into a {@link Texture2D}.\n     *\n     * @param {ArrayBuffer[]} buffers Transcoded texture data. Given as an array of buffers so that we can support multi-image textures, such as cube maps.\n     * @param {*} config Transcoding options.\n     * @param {Texture2D} texture The texture to load.\n     * @returns {Promise} Resolves when the texture has loaded.\n     */\n    transcode(buffers, texture, config = {}) {\n        return new Promise((resolve, reject) => {\n            const taskConfig = config;\n            this._init().then(() => {\n                return this._workerPool.postMessage({\n                    type: 'transcode',\n                    buffers,\n                    taskConfig: taskConfig\n                }, buffers);\n            }).then((e) => {\n                const transcodeResult = e.data;\n                const {mipmaps, width, height, format, type, error, dfdTransferFn, dfdFlags} = transcodeResult;\n                if (type === 'error') {\n                    return reject(error);\n                }\n                texture.setCompressedData({\n                    mipmaps,\n                    props: {\n                        format: format,\n                        minFilter: mipmaps.length === 1 ? LinearFilter : LinearMipmapLinearFilter,\n                        magFilter: mipmaps.length === 1 ? LinearFilter : LinearMipmapLinearFilter,\n                        encoding: dfdTransferFn === KTX2TransferSRGB ? sRGBEncoding : LinearEncoding,\n                        premultiplyAlpha: !!(dfdFlags & KTX2_ALPHA_PREMULTIPLIED)\n                    }\n                });\n                resolve();\n            });\n        });\n    }\n\n    /**\n     * Destroys this KTX2TextureTranscoder\n     */\n    destroy() {\n        URL.revokeObjectURL(this._workerSourceURL);\n        this._workerPool.destroy();\n        activeTranscoders--;\n    }\n}\n\n/**\n * @private\n */\nKTX2TextureTranscoder.BasisFormat = {\n    ETC1S: 0,\n    UASTC_4x4: 1\n};\n\n/**\n * @private\n */\nKTX2TextureTranscoder.TranscoderFormat = {\n    ETC1: 0,\n    ETC2: 1,\n    BC1: 2,\n    BC3: 3,\n    BC4: 4,\n    BC5: 5,\n    BC7_M6_OPAQUE_ONLY: 6,\n    BC7_M5: 7,\n    PVRTC1_4_RGB: 8,\n    PVRTC1_4_RGBA: 9,\n    ASTC_4x4: 10,\n    ATC_RGB: 11,\n    ATC_RGBA_INTERPOLATED_ALPHA: 12,\n    RGBA32: 13,\n    RGB565: 14,\n    BGR565: 15,\n    RGBA4444: 16\n};\n\n/**\n * @private\n */\nKTX2TextureTranscoder.EngineFormat = {\n    RGBAFormat: RGBAFormat,\n    RGBA_ASTC_4x4_Format: RGBA_ASTC_4x4_Format,\n    RGBA_BPTC_Format: RGBA_BPTC_Format,\n    RGBA_ETC2_EAC_Format: RGBA_ETC2_EAC_Format,\n    RGBA_PVRTC_4BPPV1_Format: RGBA_PVRTC_4BPPV1_Format,\n    RGBA_S3TC_DXT5_Format: RGBA_S3TC_DXT5_Format,\n    RGB_ETC1_Format: RGB_ETC1_Format,\n    RGB_ETC2_Format: RGB_ETC2_Format,\n    RGB_PVRTC_4BPPV1_Format: RGB_PVRTC_4BPPV1_Format,\n    RGB_S3TC_DXT1_Format: RGB_S3TC_DXT1_Format\n};\n\n/* WEB WORKER */\n\n/**\n * @private\n * @constructor\n */\nKTX2TextureTranscoder.BasisWorker = function () {\n\n    let config;\n    let transcoderPending;\n    let BasisModule;\n\n    const EngineFormat = _EngineFormat; // eslint-disable-line no-undef\n    const TranscoderFormat = _TranscoderFormat; // eslint-disable-line no-undef\n    const BasisFormat = _BasisFormat; // eslint-disable-line no-undef\n\n    self.addEventListener('message', function (e) {\n        const message = e.data;\n        switch (message.type) {\n            case 'init':\n                config = message.config;\n                init(message.transcoderBinary);\n                break;\n            case 'transcode':\n                transcoderPending.then(() => {\n                    try {\n                        const {\n                            width,\n                            height,\n                            hasAlpha,\n                            mipmaps,\n                            format,\n                            dfdTransferFn,\n                            dfdFlags\n                        } = transcode(message.buffers[0]);\n                        const buffers = [];\n                        for (let i = 0; i < mipmaps.length; ++i) {\n                            buffers.push(mipmaps[i].data.buffer);\n                        }\n                        self.postMessage({\n                            type: 'transcode',\n                            id: message.id,\n                            width,\n                            height,\n                            hasAlpha,\n                            mipmaps,\n                            format,\n                            dfdTransferFn,\n                            dfdFlags\n                        }, buffers);\n                    } catch (error) {\n                        console.error(`[KTX2TextureTranscoder.BasisWorker]: ${error}`);\n                        self.postMessage({type: 'error', id: message.id, error: error.message});\n                    }\n                });\n                break;\n        }\n    });\n\n    function init(wasmBinary) {\n        transcoderPending = new Promise(resolve => {\n            BasisModule = {\n                wasmBinary,\n                onRuntimeInitialized: resolve\n            };\n            BASIS(BasisModule); // eslint-disable-line no-undef\n        }).then(() => {\n            BasisModule.initializeBasis();\n            if (BasisModule.KTX2File === undefined) {\n                console.warn('KTX2TextureTranscoder: Please update Basis Universal transcoder.');\n            }\n        });\n    }\n\n    function transcode(buffer) {\n        const ktx2File = new BasisModule.KTX2File(new Uint8Array(buffer));\n\n        function cleanup() {\n            ktx2File.close();\n            ktx2File.delete();\n        }\n\n        if (!ktx2File.isValid()) {\n            cleanup();\n            throw new Error('KTX2TextureTranscoder: Invalid or unsupported .ktx2 file');\n        }\n        const basisFormat = ktx2File.isUASTC() ? BasisFormat.UASTC_4x4 : BasisFormat.ETC1S;\n        const width = ktx2File.getWidth();\n        const height = ktx2File.getHeight();\n        const levels = ktx2File.getLevels();\n        const hasAlpha = ktx2File.getHasAlpha();\n        const dfdTransferFn = ktx2File.getDFDTransferFunc();\n        const dfdFlags = ktx2File.getDFDFlags();\n        const {transcoderFormat, engineFormat} = getTranscoderFormat(basisFormat, width, height, hasAlpha);\n        if (!width || !height || !levels) {\n            cleanup();\n            throw new Error('KTX2TextureTranscoder: Invalid texture');\n        }\n        if (!ktx2File.startTranscoding()) {\n            cleanup();\n            throw new Error('KTX2TextureTranscoder: .startTranscoding failed');\n        }\n        const mipmaps = [];\n        for (let mip = 0; mip < levels; mip++) {\n            const levelInfo = ktx2File.getImageLevelInfo(mip, 0, 0);\n            const mipWidth = levelInfo.origWidth;\n            const mipHeight = levelInfo.origHeight;\n            const dst = new Uint8Array(ktx2File.getImageTranscodedSizeInBytes(mip, 0, 0, transcoderFormat));\n            const status = ktx2File.transcodeImage(dst, mip, 0, 0, transcoderFormat, 0, -1, -1);\n            if (!status) {\n                cleanup();\n                throw new Error('KTX2TextureTranscoder: .transcodeImage failed.');\n            }\n            mipmaps.push({data: dst, width: mipWidth, height: mipHeight});\n        }\n        cleanup();\n        return {width, height, hasAlpha, mipmaps, format: engineFormat, dfdTransferFn, dfdFlags};\n    }\n\n    // Optimal choice of a transcoder target format depends on the Basis format (ETC1S or UASTC),\n    // device capabilities, and texture dimensions. The list below ranks the formats separately\n    // for ETC1S and UASTC.\n    //\n    // In some cases, transcoding UASTC to RGBA32 might be preferred for higher quality (at\n    // significant memory cost) compared to ETC1/2, BC1/3, and PVRTC. The transcoder currently\n    // chooses RGBA32 only as a last resort and does not expose that option to the caller.\n\n    const FORMAT_OPTIONS = [{\n        if: 'astcSupported',\n        basisFormat: [BasisFormat.UASTC_4x4],\n        transcoderFormat: [TranscoderFormat.ASTC_4x4, TranscoderFormat.ASTC_4x4],\n        engineFormat: [EngineFormat.RGBA_ASTC_4x4_Format, EngineFormat.RGBA_ASTC_4x4_Format],\n        priorityETC1S: Infinity,\n        priorityUASTC: 1,\n        needsPowerOfTwo: false\n    }, {\n        if: 'bptcSupported',\n        basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4],\n        transcoderFormat: [TranscoderFormat.BC7_M5, TranscoderFormat.BC7_M5],\n        engineFormat: [EngineFormat.RGBA_BPTC_Format, EngineFormat.RGBA_BPTC_Format],\n        priorityETC1S: 3,\n        priorityUASTC: 2,\n        needsPowerOfTwo: false\n    }, {\n        if: 'dxtSupported',\n        basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4],\n        transcoderFormat: [TranscoderFormat.BC1, TranscoderFormat.BC3],\n        engineFormat: [EngineFormat.RGB_S3TC_DXT1_Format, EngineFormat.RGBA_S3TC_DXT5_Format],\n        priorityETC1S: 4,\n        priorityUASTC: 5,\n        needsPowerOfTwo: false\n    }, {\n        if: 'etc2Supported',\n        basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4],\n        transcoderFormat: [TranscoderFormat.ETC1, TranscoderFormat.ETC2],\n        engineFormat: [EngineFormat.RGB_ETC2_Format, EngineFormat.RGBA_ETC2_EAC_Format],\n        priorityETC1S: 1,\n        priorityUASTC: 3,\n        needsPowerOfTwo: false\n    }, {\n        if: 'etc1Supported',\n        basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4],\n        transcoderFormat: [TranscoderFormat.ETC1],\n        engineFormat: [EngineFormat.RGB_ETC1_Format],\n        priorityETC1S: 2,\n        priorityUASTC: 4,\n        needsPowerOfTwo: false\n    }, {\n        if: 'pvrtcSupported',\n        basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4],\n        transcoderFormat: [TranscoderFormat.PVRTC1_4_RGB, TranscoderFormat.PVRTC1_4_RGBA],\n        engineFormat: [EngineFormat.RGB_PVRTC_4BPPV1_Format, EngineFormat.RGBA_PVRTC_4BPPV1_Format],\n        priorityETC1S: 5,\n        priorityUASTC: 6,\n        needsPowerOfTwo: true\n    }];\n    const ETC1S_OPTIONS = FORMAT_OPTIONS.sort(function (a, b) {\n        return a.priorityETC1S - b.priorityETC1S;\n    });\n    const UASTC_OPTIONS = FORMAT_OPTIONS.sort(function (a, b) {\n        return a.priorityUASTC - b.priorityUASTC;\n    });\n\n    function getTranscoderFormat(basisFormat, width, height, hasAlpha) {\n        let transcoderFormat;\n        let engineFormat;\n        const options = basisFormat === BasisFormat.ETC1S ? ETC1S_OPTIONS : UASTC_OPTIONS;\n        for (let i = 0; i < options.length; i++) {\n            const opt = options[i];\n            if (!config[opt.if]) continue;\n            if (!opt.basisFormat.includes(basisFormat)) continue;\n            if (hasAlpha && opt.transcoderFormat.length < 2) continue;\n            if (opt.needsPowerOfTwo && !(isPowerOfTwo(width) && isPowerOfTwo(height))) continue;\n            transcoderFormat = opt.transcoderFormat[hasAlpha ? 1 : 0];\n            engineFormat = opt.engineFormat[hasAlpha ? 1 : 0];\n            return {\n                transcoderFormat,\n                engineFormat\n            };\n        }\n        console.warn('KTX2TextureTranscoder: No suitable compressed texture format found. Decoding to RGBA32.');\n        transcoderFormat = TranscoderFormat.RGBA32;\n        engineFormat = EngineFormat.RGBAFormat;\n        return {\n            transcoderFormat,\n            engineFormat\n        };\n    }\n\n    function isPowerOfTwo(value) {\n        if (value <= 2) return true;\n        return (value & value - 1) === 0 && value !== 0;\n    }\n};\n\nconst cachedTranscoders = {};\n\n/**\n * Returns a new {@link KTX2TextureTranscoder}.\n *\n * The ````transcoderPath```` config will be set to: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\"\n *\n * @private\n */\nfunction getKTX2TextureTranscoder(viewer) {\n    const sceneId = viewer.scene.id;\n    let transcoder = cachedTranscoders[sceneId];\n    if (!transcoder) {\n        transcoder = new KTX2TextureTranscoder({viewer});\n        cachedTranscoders[sceneId] = transcoder;\n        viewer.scene.on(\"destroyed\", () => {\n            delete cachedTranscoders[sceneId];\n            transcoder.destroy();\n        });\n    }\n    return transcoder;\n}\n\n/**\n * @author https://github.com/tmarti, with support from https://tribia.com/\n * @license MIT\n *\n * This file takes a geometry given by { positionsCompressed, indices }, and returns\n * equivalent { positionsCompressed, indices } arrays but which only contain unique\n * positionsCompressed.\n *\n * The time is O(N logN) with the number of positionsCompressed due to a pre-sorting\n * step, but is much more GC-friendly and actually faster than the classic O(N)\n * approach based in keeping a hash-based LUT to identify unique positionsCompressed.\n */\nlet comparePositions = null;\n\nfunction compareVertex(a, b) {\n    let res;\n    for (let i = 0; i < 3; i++) {\n        if (0 !== (res = comparePositions[a * 3 + i] - comparePositions[b * 3 + i])) {\n            return res;\n        }\n    }\n    return 0;\n}\n\nlet seqInit = null;\n\nfunction setMaxNumberOfPositions(maxPositions) {\n    if (seqInit !== null && seqInit.length >= maxPositions) {\n        return;\n    }\n    seqInit = new Uint32Array(maxPositions);\n    for (let i = 0; i < maxPositions; i++) {\n        seqInit[i] = i;\n    }\n}\n\n/**\n * This function obtains unique positionsCompressed in the provided object\n * .positionsCompressed array and calculates an index mapping, which is then\n * applied to the provided object .indices and .edgeindices.\n *\n * The input object items are not modified, and instead new set\n * of positionsCompressed, indices and edgeIndices with the applied optimization\n * are returned.\n *\n * The algorithm, instead of being based in a hash-like LUT for\n * identifying unique positionsCompressed, is based in pre-sorting the input\n * positionsCompressed...\n *\n * (it's possible to define a _\"consistent ordering\"_ for the positionsCompressed\n *  as positionsCompressed are quantized and thus not suffer from float number\n *  comparison artifacts)\n *\n * ... so same positionsCompressed are adjacent in the sorted array, and then\n * it's easy to scan linearly the sorted array. During the linear run,\n * we will know that we found a different position because the comparison\n * function will return != 0 between current and previous element.\n *\n * During this linear traversal of the array, a `unique counter` is used\n * in order to calculate the mapping between original indices and unique\n * indices.\n *\n * @param {{positionsCompressed: number[],indices: number[], edgeIndices: number[]}} mesh The input mesh to process, with `positionsCompressed`, `indices` and `edgeIndices` keys.\n *\n * @returns {[Uint16Array, Uint32Array, Uint32Array]} An array with 3 elements: 0 => the uniquified positionsCompressed; 1 and 2 => the remapped edges and edgeIndices arrays\n */\nfunction uniquifyPositions(mesh) {\n    const _positions = mesh.positionsCompressed;\n    const _indices = mesh.indices;\n    const _edgeIndices = mesh.edgeIndices;\n\n    setMaxNumberOfPositions(_positions.length / 3);\n\n    const seq = seqInit.slice(0, _positions.length / 3);\n    const remappings = seqInit.slice(0, _positions.length / 3);\n\n    comparePositions = _positions;\n\n    seq.sort(compareVertex);\n\n    let uniqueIdx = 0;\n\n    remappings[seq[0]] = 0;\n\n    for (let i = 1, len = seq.length; i < len; i++) {\n        if (0 !== compareVertex(seq[i], seq[i - 1])) {\n            uniqueIdx++;\n        }\n        remappings[seq[i]] = uniqueIdx;\n    }\n\n    const numUniquePositions = uniqueIdx + 1;\n    const newPositions = new Uint16Array(numUniquePositions * 3);\n\n    uniqueIdx = 0;\n\n    newPositions [uniqueIdx * 3 + 0] = _positions [seq[0] * 3 + 0];\n    newPositions [uniqueIdx * 3 + 1] = _positions [seq[0] * 3 + 1];\n    newPositions [uniqueIdx * 3 + 2] = _positions [seq[0] * 3 + 2];\n\n    for (let i = 1, len = seq.length; i < len; i++) {\n        if (0 !== compareVertex(seq[i], seq[i - 1])) {\n            uniqueIdx++;\n            newPositions [uniqueIdx * 3 + 0] = _positions [seq[i] * 3 + 0];\n            newPositions [uniqueIdx * 3 + 1] = _positions [seq[i] * 3 + 1];\n            newPositions [uniqueIdx * 3 + 2] = _positions [seq[i] * 3 + 2];\n        }\n        remappings[seq[i]] = uniqueIdx;\n    }\n\n    comparePositions = null;\n\n    const newIndices = new Uint32Array(_indices.length);\n\n    for (let i = 0, len = _indices.length; i < len; i++) {\n        newIndices[i] = remappings [_indices[i]];\n    }\n\n    const newEdgeIndices = new Uint32Array(_edgeIndices.length);\n\n    for (let i = 0, len = _edgeIndices.length; i < len; i++) {\n        newEdgeIndices[i] = remappings [_edgeIndices[i]];\n    }\n\n    return [newPositions, newIndices, newEdgeIndices];\n}\n\n/**\n * @author https://github.com/tmarti, with support from https://tribia.com/\n * @license MIT\n **/\n\nconst MAX_RE_BUCKET_FAN_OUT = 8;\n\nlet bucketsForIndices = null;\n\nfunction compareBuckets(a, b) {\n    const aa = a * 3;\n    const bb = b * 3;\n    let aa1, aa2, aa3, bb1, bb2, bb3;\n    const minBucketA = Math.min(\n        aa1 = bucketsForIndices[aa],\n        aa2 = bucketsForIndices[aa + 1],\n        aa3 = bucketsForIndices[aa + 2]\n    );\n    const minBucketB = Math.min(\n        bb1 = bucketsForIndices[bb],\n        bb2 = bucketsForIndices[bb + 1],\n        bb3 = bucketsForIndices[bb + 2]\n    );\n    if (minBucketA !== minBucketB) {\n        return minBucketA - minBucketB;\n    }\n    const maxBucketA = Math.max(aa1, aa2, aa3);\n    const maxBucketB = Math.max(bb1, bb2, bb3,);\n    if (maxBucketA !== maxBucketB) {\n        return maxBucketA - maxBucketB;\n    }\n    return 0;\n}\n\nfunction preSortIndices(indices, bitsPerBucket) {\n    const seq = new Int32Array(indices.length / 3);\n    for (let i = 0, len = seq.length; i < len; i++) {\n        seq[i] = i;\n    }\n    bucketsForIndices = new Int32Array(indices.length);\n    for (let i = 0, len = indices.length; i < len; i++) {\n        bucketsForIndices[i] = indices[i] >> bitsPerBucket;\n    }\n    seq.sort(compareBuckets);\n    const sortedIndices = new Int32Array(indices.length);\n    for (let i = 0, len = seq.length; i < len; i++) {\n        sortedIndices[i * 3 + 0] = indices[seq[i] * 3 + 0];\n        sortedIndices[i * 3 + 1] = indices[seq[i] * 3 + 1];\n        sortedIndices[i * 3 + 2] = indices[seq[i] * 3 + 2];\n    }\n    return sortedIndices;\n}\n\nlet compareEdgeIndices = null;\n\nfunction compareIndices(a, b) {\n    let retVal = compareEdgeIndices[a * 2] - compareEdgeIndices[b * 2];\n    if (retVal !== 0) {\n        return retVal;\n    }\n    return compareEdgeIndices[a * 2 + 1] - compareEdgeIndices[b * 2 + 1];\n}\n\nfunction preSortEdgeIndices(edgeIndices) {\n    if ((edgeIndices || []).length === 0) {\n        return [];\n    }\n    let seq = new Int32Array(edgeIndices.length / 2);\n    for (let i = 0, len = seq.length; i < len; i++) {\n        seq[i] = i;\n    }\n    for (let i = 0, len = edgeIndices.length; i < len; i += 2) {\n        if (edgeIndices[i] > edgeIndices[i + 1]) {\n            let tmp = edgeIndices[i];\n            edgeIndices[i] = edgeIndices[i + 1];\n            edgeIndices[i + 1] = tmp;\n        }\n    }\n    compareEdgeIndices = new Int32Array(edgeIndices);\n    seq.sort(compareIndices);\n    const sortedEdgeIndices = new Int32Array(edgeIndices.length);\n    for (let i = 0, len = seq.length; i < len; i++) {\n        sortedEdgeIndices[i * 2 + 0] = edgeIndices[seq[i] * 2 + 0];\n        sortedEdgeIndices[i * 2 + 1] = edgeIndices[seq[i] * 2 + 1];\n    }\n    return sortedEdgeIndices;\n}\n\n/**\n * @param {{positionsCompressed: number[], indices: number[], edgeIndices: number[]}} mesh \n * @param {number} bitsPerBucket \n * @param {boolean} checkResult \n * \n * @returns {{positionsCompressed: number[], indices: number[], edgeIndices: number[]}[]}\n */\nfunction rebucketPositions(mesh, bitsPerBucket, checkResult = false) {\n    const positionsCompressed = (mesh.positionsCompressed || []);\n    const indices = preSortIndices(mesh.indices || [], bitsPerBucket);\n    const edgeIndices = preSortEdgeIndices(mesh.edgeIndices || []);\n\n    function edgeSearch(el0, el1) { // Code adapted from https://stackoverflow.com/questions/22697936/binary-search-in-javascript\n        if (el0 > el1) {\n            let tmp = el0;\n            el0 = el1;\n            el1 = tmp;\n        }\n\n        function compare_fn(a, b) {\n            if (a !== el0) {\n                return el0 - a;\n            }\n            if (b !== el1) {\n                return el1 - b;\n            }\n            return 0;\n        }\n\n        let m = 0;\n        let n = (edgeIndices.length >> 1) - 1;\n        while (m <= n) {\n            const k = (n + m) >> 1;\n            const cmp = compare_fn(edgeIndices[k * 2], edgeIndices[k * 2 + 1]);\n            if (cmp > 0) {\n                m = k + 1;\n            } else if (cmp < 0) {\n                n = k - 1;\n            } else {\n                return k;\n            }\n        }\n        return -m - 1;\n    }\n\n    const alreadyOutputEdgeIndices = new Int32Array(edgeIndices.length / 2);\n    alreadyOutputEdgeIndices.fill(0);\n\n    const numPositions = positionsCompressed.length / 3;\n\n    if (numPositions > ((1 << bitsPerBucket) * MAX_RE_BUCKET_FAN_OUT)) {\n        return [mesh];\n    }\n\n    const bucketIndicesRemap = new Int32Array(numPositions);\n    bucketIndicesRemap.fill(-1);\n\n    const buckets = [];\n\n    function addEmptyBucket() {\n        bucketIndicesRemap.fill(-1);\n\n        const newBucket = {\n            positionsCompressed: [],\n            indices: [],\n            edgeIndices: [],\n            maxNumPositions: (1 << bitsPerBucket) - bitsPerBucket,\n            numPositions: 0,\n            bucketNumber: buckets.length,\n        };\n\n        buckets.push(newBucket);\n\n        return newBucket;\n    }\n\n    let currentBucket = addEmptyBucket();\n\n    for (let i = 0, len = indices.length; i < len; i += 3) {\n        let additonalPositionsInBucket = 0;\n\n        const ii0 = indices[i];\n        const ii1 = indices[i + 1];\n        const ii2 = indices[i + 2];\n\n        if (bucketIndicesRemap[ii0] === -1) {\n            additonalPositionsInBucket++;\n        }\n\n        if (bucketIndicesRemap[ii1] === -1) {\n            additonalPositionsInBucket++;\n        }\n\n        if (bucketIndicesRemap[ii2] === -1) {\n            additonalPositionsInBucket++;\n        }\n\n        if ((additonalPositionsInBucket + currentBucket.numPositions) > currentBucket.maxNumPositions) {\n            currentBucket = addEmptyBucket();\n        }\n\n        if (currentBucket.bucketNumber > MAX_RE_BUCKET_FAN_OUT) {\n            return [mesh];\n        }\n\n        if (bucketIndicesRemap[ii0] === -1) {\n            bucketIndicesRemap[ii0] = currentBucket.numPositions++;\n            currentBucket.positionsCompressed.push(positionsCompressed[ii0 * 3]);\n            currentBucket.positionsCompressed.push(positionsCompressed[ii0 * 3 + 1]);\n            currentBucket.positionsCompressed.push(positionsCompressed[ii0 * 3 + 2]);\n        }\n\n        if (bucketIndicesRemap[ii1] === -1) {\n            bucketIndicesRemap[ii1] = currentBucket.numPositions++;\n            currentBucket.positionsCompressed.push(positionsCompressed[ii1 * 3]);\n            currentBucket.positionsCompressed.push(positionsCompressed[ii1 * 3 + 1]);\n            currentBucket.positionsCompressed.push(positionsCompressed[ii1 * 3 + 2]);\n        }\n\n        if (bucketIndicesRemap[ii2] === -1) {\n            bucketIndicesRemap[ii2] = currentBucket.numPositions++;\n            currentBucket.positionsCompressed.push(positionsCompressed[ii2 * 3]);\n            currentBucket.positionsCompressed.push(positionsCompressed[ii2 * 3 + 1]);\n            currentBucket.positionsCompressed.push(positionsCompressed[ii2 * 3 + 2]);\n        }\n\n        currentBucket.indices.push(bucketIndicesRemap[ii0]);\n        currentBucket.indices.push(bucketIndicesRemap[ii1]);\n        currentBucket.indices.push(bucketIndicesRemap[ii2]);\n\n        // Check possible edge1\n        let edgeIndex;\n\n        if ((edgeIndex = edgeSearch(ii0, ii1)) >= 0) {\n            if (alreadyOutputEdgeIndices[edgeIndex] === 0) {\n                alreadyOutputEdgeIndices[edgeIndex] = 1;\n\n                currentBucket.edgeIndices.push(bucketIndicesRemap[edgeIndices[edgeIndex * 2]]);\n                currentBucket.edgeIndices.push(bucketIndicesRemap[edgeIndices[edgeIndex * 2 + 1]]);\n            }\n        }\n\n        if ((edgeIndex = edgeSearch(ii0, ii2)) >= 0) {\n            if (alreadyOutputEdgeIndices[edgeIndex] === 0) {\n                alreadyOutputEdgeIndices[edgeIndex] = 1;\n\n                currentBucket.edgeIndices.push(bucketIndicesRemap[edgeIndices[edgeIndex * 2]]);\n                currentBucket.edgeIndices.push(bucketIndicesRemap[edgeIndices[edgeIndex * 2 + 1]]);\n            }\n        }\n\n        if ((edgeIndex = edgeSearch(ii1, ii2)) >= 0) {\n            if (alreadyOutputEdgeIndices[edgeIndex] === 0) {\n                alreadyOutputEdgeIndices[edgeIndex] = 1;\n\n                currentBucket.edgeIndices.push(bucketIndicesRemap[edgeIndices[edgeIndex * 2]]);\n                currentBucket.edgeIndices.push(bucketIndicesRemap[edgeIndices[edgeIndex * 2 + 1]]);\n            }\n        }\n    }\n\n    const prevBytesPerIndex = bitsPerBucket / 8 * 2;\n    const newBytesPerIndex = bitsPerBucket / 8;\n\n    const originalSize = positionsCompressed.length * 2 + (indices.length + edgeIndices.length) * prevBytesPerIndex;\n\n    let newSize = 0;\n    let newPositions = -positionsCompressed.length / 3;\n\n    buckets.forEach(bucket => {\n        newSize += bucket.positionsCompressed.length * 2 + (bucket.indices.length + bucket.edgeIndices.length) * newBytesPerIndex;\n        newPositions += bucket.positionsCompressed.length / 3;\n    });\n    if (newSize > originalSize) {\n        return [mesh];\n    }\n    if (checkResult) {\n        doCheckResult(buckets, mesh);\n    }\n    return buckets;\n}\n\nfunction doCheckResult(buckets, mesh) {\n    const meshDict = {};\n    const edgesDict = {};\n\n    let edgeIndicesCount = 0;\n\n    buckets.forEach(bucket => {\n        const indices = bucket.indices;\n        const edgeIndices = bucket.edgeIndices;\n        const positionsCompressed = bucket.positionsCompressed;\n\n        for (let i = 0, len = indices.length; i < len; i += 3) {\n            const key = positionsCompressed[indices[i] * 3] + \"_\" + positionsCompressed[indices[i] * 3 + 1] + \"_\" + positionsCompressed[indices[i] * 3 + 2] + \"/\" +\n                positionsCompressed[indices[i + 1] * 3] + \"_\" + positionsCompressed[indices[i + 1] * 3 + 1] + \"_\" + positionsCompressed[indices[i + 1] * 3 + 2] + \"/\" +\n                positionsCompressed[indices[i + 2] * 3] + \"_\" + positionsCompressed[indices[i + 2] * 3 + 1] + \"_\" + positionsCompressed[indices[i + 2] * 3 + 2];\n            meshDict[key] = true;\n        }\n\n        edgeIndicesCount += bucket.edgeIndices.length / 2;\n\n        for (let i = 0, len = edgeIndices.length; i < len; i += 2) {\n            const key = positionsCompressed[edgeIndices[i] * 3] + \"_\" + positionsCompressed[edgeIndices[i] * 3 + 1] + \"_\" + positionsCompressed[edgeIndices[i] * 3 + 2] + \"/\" +\n                positionsCompressed[edgeIndices[i + 1] * 3] + \"_\" + positionsCompressed[edgeIndices[i + 1] * 3 + 1] + \"_\" + positionsCompressed[edgeIndices[i + 1] * 3 + 2] + \"/\";\n            edgesDict[key] = true;\n        }\n    });\n\n    {\n        const indices = mesh.indices;\n        mesh.edgeIndices;\n        const positionsCompressed = mesh.positionsCompressed;\n\n        for (let i = 0, len = indices.length; i < len; i += 3) {\n            const key = positionsCompressed[indices[i] * 3] + \"_\" + positionsCompressed[indices[i] * 3 + 1] + \"_\" + positionsCompressed[indices[i] * 3 + 2] + \"/\" +\n                positionsCompressed[indices[i + 1] * 3] + \"_\" + positionsCompressed[indices[i + 1] * 3 + 1] + \"_\" + positionsCompressed[indices[i + 1] * 3 + 2] + \"/\" +\n                positionsCompressed[indices[i + 2] * 3] + \"_\" + positionsCompressed[indices[i + 2] * 3 + 1] + \"_\" + positionsCompressed[indices[i + 2] * 3 + 2];\n\n            if (!(key in meshDict)) {\n                console.log(\"Not found \" + key);\n                throw \"Ohhhh!\";\n            }\n        }\n\n        //  for (var i = 0, len = edgeIndices.length; i < len; i+=2)\n        //  {\n        //      var key = positionsCompressed[edgeIndices[i]*3] + \"_\" + positionsCompressed[edgeIndices[i]*3+1] + \"_\" + positionsCompressed[edgeIndices[i]*3+2] + \"/\" +\n        //                positionsCompressed[edgeIndices[i+1]*3] + \"_\" + positionsCompressed[edgeIndices[i+1]*3+1] + \"_\" + positionsCompressed[edgeIndices[i+1]*3+2] + \"/\";\n\n        //      if (!(key in edgesDict)) {\n        //          var key2 = edgeIndices[i] + \"_\" + edgeIndices[i+1];\n\n        //          console.log (\"   - Not found \" + key);\n        //          console.log (\"   - Not found \" + key2);\n        //         //  throw \"Ohhhh2!\";\n        //      }\n        //  }\n    }\n}\n\nconst tempFloatRGB = new Float32Array([0, 0, 0]);\nconst tempIntRGB = new Uint16Array([0, 0, 0]);\n\nmath.OBB3();\n\n/**\n * An entity within a {@link SceneModel}\n *\n * * Created with {@link SceneModel#createEntity}\n * * Stored by ID in {@link SceneModel#entities}\n * * Has one or more {@link SceneModelMesh}es\n *\n * @implements {Entity}\n */\nclass SceneModelEntity {\n\n    /**\n     * @private\n     */\n    constructor(model, isObject, id, meshes, flags, lodCullable) {\n\n        this._isObject = isObject;\n\n        /**\n         * The {@link Scene} to which this SceneModelEntity belongs.\n         */\n        this.scene = model.scene;\n\n        /**\n         * The {@link SceneModel} to which this SceneModelEntity belongs.\n         */\n        this.model = model;\n\n        /**\n         * Identifies if it's a SceneModelEntity\n         */\n        this.isSceneModelEntity = true;\n\n        /**\n         * The {@link SceneModelMesh}es belonging to this SceneModelEntity.\n         *\n         * * These are created with {@link SceneModel#createMesh} and registered in {@ilnk SceneModel#meshes}\n         * * Each SceneModelMesh belongs to one SceneModelEntity\n         */\n        this.meshes = meshes;\n\n        this._numPrimitives = 0;\n        this._capMaterial = null;\n\n        for (let i = 0, len = this.meshes.length; i < len; i++) {  // TODO: tidier way? Refactor?\n            const mesh = this.meshes[i];\n            mesh.parent = this;\n            mesh.entity = this;\n            this._numPrimitives += mesh.numPrimitives;\n        }\n\n        /**\n         * The unique ID of this SceneModelEntity.\n         */\n        this.id = id;\n\n        /**\n         * The original system ID of this SceneModelEntity.\n         */\n        this.originalSystemId = math.unglobalizeObjectId(model.id, id);\n\n        this._flags = flags;\n        this._aabb = math.AABB3();\n        this._aabbDirty = true;\n\n        this._offset = math.vec3();\n        this._colorizeUpdated = false;\n        this._opacityUpdated = false;\n\n        this._lodCullable = (!!lodCullable);\n        this._culled = false;\n        this._culledVFC = false;\n        this._culledLOD = false;\n\n        if (this._isObject) {\n            model.scene._registerObject(this);\n        }\n    }\n\n    _transformDirty() {\n        this._aabbDirty = true;\n        this.model._transformDirty();\n\n    }\n\n    _sceneModelDirty() { // Called by SceneModel when SceneModel's matrix is updated\n        this._aabbDirty = true;\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._sceneModelDirty();\n        }\n    }\n\n    /**\n     * World-space 3D axis-aligned bounding box (AABB) of this SceneModelEntity.\n     *\n     * Represented by a six-element Float64Array containing the min/max extents of the\n     * axis-aligned volume, ie. ````[xmin, ymin, zmin, xmax, ymax, zmax]````.\n     *\n     * @type {Float64Array}\n     */\n    get aabb() {\n        if (this._aabbDirty) {\n            math.collapseAABB3(this._aabb);\n            for (let i = 0, len = this.meshes.length; i < len; i++) {\n                math.expandAABB3(this._aabb, this.meshes[i].aabb);\n            }\n            this._aabbDirty = false;\n        }\n        // if (this._aabbDirty) {\n        //     math.AABB3ToOBB3(this._aabb, tempOBB3a);\n        //     math.transformOBB3(this.model.matrix, tempOBB3a);\n        //     math.OBB3ToAABB3(tempOBB3a, this._worldAABB);\n        //     this._worldAABB[0] += this._offset[0];\n        //     this._worldAABB[1] += this._offset[1];\n        //     this._worldAABB[2] += this._offset[2];\n        //     this._worldAABB[3] += this._offset[0];\n        //     this._worldAABB[4] += this._offset[1];\n        //     this._worldAABB[5] += this._offset[2];\n        //     this._aabbDirty = false;\n        // }\n        return this._aabb;\n    }\n\n    get isEntity() {\n        return true;\n    }\n\n    /**\n     * Returns false to indicate that this Entity subtype is not a model.\n     * @returns {boolean}\n     */\n    get isModel() {\n        return false;\n    }\n\n    /**\n     * Returns ````true```` if this SceneModelEntity represents an object.\n     *\n     * When this is ````true````, the SceneModelEntity will be registered by {@link SceneModelEntity#id}\n     * in {@link Scene#objects} and may also have a corresponding {@link MetaObject}.\n     *\n     * @type {Boolean}\n     */\n    get isObject() {\n        return this._isObject;\n    }\n\n    get numPrimitives() {\n        return this._numPrimitives;\n    }\n\n    /**\n     * The approximate number of triangles in this SceneModelEntity.\n     *\n     * @type {Number}\n     */\n    get numTriangles() {\n        return this._numPrimitives;\n    }\n\n    /**\n     * Gets if this SceneModelEntity is visible.\n     *\n     * Only rendered when {@link SceneModelEntity#visible} is ````true````\n     * and {@link SceneModelEntity#culled} is ````false````.\n     *\n     * When {@link SceneModelEntity#isObject} and {@link SceneModelEntity#visible} are\n     * both ````true```` the SceneModelEntity will be registered\n     * by {@link SceneModelEntity#id} in {@link Scene#visibleObjects}.\n     *\n     * @type {Boolean}\n     */\n    get visible() {\n        return this._getFlag(ENTITY_FLAGS.VISIBLE);\n    }\n\n    /**\n     * Sets if this SceneModelEntity is visible.\n     *\n     * Only rendered when {@link SceneModelEntity#visible} is ````true```` and {@link SceneModelEntity#culled} is ````false````.\n     *\n     * When {@link SceneModelEntity#isObject} and {@link SceneModelEntity#visible} are\n     * both ````true```` the SceneModelEntity will be\n     * registered by {@link SceneModelEntity#id} in {@link Scene#visibleObjects}.\n     *\n     * @type {Boolean}\n     */\n    set visible(visible) {\n        if (!!(this._flags & ENTITY_FLAGS.VISIBLE) === visible) {\n            return; // Redundant update\n        }\n        if (visible) {\n            this._flags = this._flags | ENTITY_FLAGS.VISIBLE;\n        } else {\n            this._flags = this._flags & ~ENTITY_FLAGS.VISIBLE;\n        }\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setVisible(this._flags);\n        }\n        if (this._isObject) {\n            this.model.scene._objectVisibilityUpdated(this);\n        }\n        this.model.glRedraw();\n    }\n\n    /**\n     * Gets if this SceneModelEntity is highlighted.\n     *\n     * When {@link SceneModelEntity#isObject} and {@link SceneModelEntity#highlighted} are both ````true```` the SceneModelEntity will be\n     * registered by {@link SceneModelEntity#id} in {@link Scene#highlightedObjects}.\n     *\n     * @type {Boolean}\n     */\n    get highlighted() {\n        return this._getFlag(ENTITY_FLAGS.HIGHLIGHTED);\n    }\n\n    /**\n     * Sets if this SceneModelEntity is highlighted.\n     *\n     * When {@link SceneModelEntity#isObject} and {@link SceneModelEntity#highlighted} are both ````true```` the SceneModelEntity will be\n     * registered by {@link SceneModelEntity#id} in {@link Scene#highlightedObjects}.\n     *\n     * @type {Boolean}\n     */\n    set highlighted(highlighted) {\n        if (!!(this._flags & ENTITY_FLAGS.HIGHLIGHTED) === highlighted) {\n            return; // Redundant update\n        }\n\n        if (highlighted) {\n            this._flags = this._flags | ENTITY_FLAGS.HIGHLIGHTED;\n        } else {\n            this._flags = this._flags & ~ENTITY_FLAGS.HIGHLIGHTED;\n        }\n        for (var i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setHighlighted(this._flags);\n        }\n        if (this._isObject) {\n            this.model.scene._objectHighlightedUpdated(this);\n        }\n        this.model.glRedraw();\n    }\n\n    /**\n     * Gets if this SceneModelEntity is xrayed.\n     *\n     * When {@link SceneModelEntity#isObject} and {@link SceneModelEntity#xrayed} are both ````true``` the SceneModelEntity will be\n     * registered by {@link SceneModelEntity#id} in {@link Scene#xrayedObjects}.\n     *\n     * @type {Boolean}\n     */\n    get xrayed() {\n        return this._getFlag(ENTITY_FLAGS.XRAYED);\n    }\n\n    /**\n     * Sets if this SceneModelEntity is xrayed.\n     *\n     * When {@link SceneModelEntity#isObject} and {@link SceneModelEntity#xrayed} are both ````true``` the SceneModelEntity will be\n     * registered by {@link SceneModelEntity#id} in {@link Scene#xrayedObjects}.\n     *\n     * @type {Boolean}\n     */\n    set xrayed(xrayed) {\n        if (!!(this._flags & ENTITY_FLAGS.XRAYED) === xrayed) {\n            return; // Redundant update\n        }\n        if (xrayed) {\n            this._flags = this._flags | ENTITY_FLAGS.XRAYED;\n        } else {\n            this._flags = this._flags & ~ENTITY_FLAGS.XRAYED;\n        }\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setXRayed(this._flags);\n        }\n        if (this._isObject) {\n            this.model.scene._objectXRayedUpdated(this);\n        }\n        this.model.glRedraw();\n    }\n\n    /**\n     * Gets if this SceneModelEntity is selected.\n     *\n     * When {@link SceneModelEntity#isObject} and {@link SceneModelEntity#selected} are both ````true``` the SceneModelEntity will be\n     * registered by {@link SceneModelEntity#id} in {@link Scene#selectedObjects}.\n     *\n     * @type {Boolean}\n     */\n    get selected() {\n        return this._getFlag(ENTITY_FLAGS.SELECTED);\n    }\n\n    /**\n     * Gets if this SceneModelEntity is selected.\n     *\n     * When {@link SceneModelEntity#isObject} and {@link SceneModelEntity#selected} are both ````true``` the SceneModelEntity will be\n     * registered by {@link SceneModelEntity#id} in {@link Scene#selectedObjects}.\n     *\n     * @type {Boolean}\n     */\n    set selected(selected) {\n        if (!!(this._flags & ENTITY_FLAGS.SELECTED) === selected) {\n            return; // Redundant update\n        }\n        if (selected) {\n            this._flags = this._flags | ENTITY_FLAGS.SELECTED;\n        } else {\n            this._flags = this._flags & ~ENTITY_FLAGS.SELECTED;\n        }\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setSelected(this._flags);\n        }\n        if (this._isObject) {\n            this.model.scene._objectSelectedUpdated(this);\n        }\n        this.model.glRedraw();\n    }\n\n    /**\n     * Gets if this SceneModelEntity's edges are enhanced.\n     *\n     * @type {Boolean}\n     */\n    get edges() {\n        return this._getFlag(ENTITY_FLAGS.EDGES);\n    }\n\n    /**\n     * Sets if this SceneModelEntity's edges are enhanced.\n     *\n     * @type {Boolean}\n     */\n    set edges(edges) {\n        if (!!(this._flags & ENTITY_FLAGS.EDGES) === edges) {\n            return; // Redundant update\n        }\n        if (edges) {\n            this._flags = this._flags | ENTITY_FLAGS.EDGES;\n        } else {\n            this._flags = this._flags & ~ENTITY_FLAGS.EDGES;\n        }\n        for (var i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setEdges(this._flags);\n        }\n        this.model.glRedraw();\n    }\n\n\n    get culledVFC() {\n        return !!(this._culledVFC);\n    }\n\n    set culledVFC(culled) {\n        this._culledVFC = culled;\n        this._setCulled();\n    }\n\n    get culledLOD() {\n        return !!(this._culledLOD);\n    }\n\n    set culledLOD(culled) {\n        this._culledLOD = culled;\n        this._setCulled();\n    }\n\n    /**\n     * Gets if this SceneModelEntity is culled.\n     *\n     * Only rendered when {@link SceneModelEntity#visible} is ````true```` and {@link SceneModelEntity#culled} is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get culled() {\n        return !!(this._culled);\n        // return this._getFlag(ENTITY_FLAGS.CULLED);\n    }\n\n    /**\n     * Sets if this SceneModelEntity is culled.\n     *\n     * Only rendered when {@link SceneModelEntity#visible} is ````true```` and {@link SceneModelEntity#culled} is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set culled(culled) {\n        this._culled = culled;\n        this._setCulled();\n    }\n\n    _setCulled() {\n        let culled = !!(this._culled) || !!(this._culledLOD && this._lodCullable) || !!(this._culledVFC);\n        if (!!(this._flags & ENTITY_FLAGS.CULLED) === culled) {\n            return; // Redundant update\n        }\n        if (culled) {\n            this._flags = this._flags | ENTITY_FLAGS.CULLED;\n        } else {\n            this._flags = this._flags & ~ENTITY_FLAGS.CULLED;\n        }\n        for (var i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setCulled(this._flags);\n        }\n        this.model.glRedraw();\n    }\n\n    /**\n     * Gets if this SceneModelEntity is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * @type {Boolean}\n     */\n    get clippable() {\n        return this._getFlag(ENTITY_FLAGS.CLIPPABLE);\n    }\n\n    /**\n     * Sets if this SceneModelEntity is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * @type {Boolean}\n     */\n    set clippable(clippable) {\n        if ((!!(this._flags & ENTITY_FLAGS.CLIPPABLE)) === clippable) {\n            return; // Redundant update\n        }\n        if (clippable) {\n            this._flags = this._flags | ENTITY_FLAGS.CLIPPABLE;\n        } else {\n            this._flags = this._flags & ~ENTITY_FLAGS.CLIPPABLE;\n        }\n        for (var i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setClippable(this._flags);\n        }\n        this.model.glRedraw();\n    }\n\n    /**\n     * Gets if this SceneModelEntity is included in boundary calculations.\n     *\n     * @type {Boolean}\n     */\n    get collidable() {\n        return this._getFlag(ENTITY_FLAGS.COLLIDABLE);\n    }\n\n    /**\n     * Sets if this SceneModelEntity is included in boundary calculations.\n     *\n     * @type {Boolean}\n     */\n    set collidable(collidable) {\n        if (!!(this._flags & ENTITY_FLAGS.COLLIDABLE) === collidable) {\n            return; // Redundant update\n        }\n        if (collidable) {\n            this._flags = this._flags | ENTITY_FLAGS.COLLIDABLE;\n        } else {\n            this._flags = this._flags & ~ENTITY_FLAGS.COLLIDABLE;\n        }\n        for (var i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setCollidable(this._flags);\n        }\n    }\n\n    /**\n     * Gets if this SceneModelEntity is pickable.\n     *\n     * Picking is done via calls to {@link Scene#pick}.\n     *\n     * @type {Boolean}\n     */\n    get pickable() {\n        return this._getFlag(ENTITY_FLAGS.PICKABLE);\n    }\n\n    /**\n     * Sets if this SceneModelEntity is pickable.\n     *\n     * Picking is done via calls to {@link Scene#pick}.\n     *\n     * @type {Boolean}\n     */\n    set pickable(pickable) {\n        if (!!(this._flags & ENTITY_FLAGS.PICKABLE) === pickable) {\n            return; // Redundant update\n        }\n        if (pickable) {\n            this._flags = this._flags | ENTITY_FLAGS.PICKABLE;\n        } else {\n            this._flags = this._flags & ~ENTITY_FLAGS.PICKABLE;\n        }\n        for (var i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setPickable(this._flags);\n        }\n    }\n\n    /**\n     * Gets the SceneModelEntity's RGB colorize color, multiplies by the SceneModelEntity's rendered fragment colors.\n     *\n     * Each element of the color is in range ````[0..1]````.\n     *\n     * @type {Number[]}\n     */\n    get colorize() { // [0..1, 0..1, 0..1]\n        if (this.meshes.length === 0) {\n            return null;\n        }\n        const colorize = this.meshes[0]._colorize;\n        tempFloatRGB[0] = colorize[0] / 255.0; // Unquantize\n        tempFloatRGB[1] = colorize[1] / 255.0;\n        tempFloatRGB[2] = colorize[2] / 255.0;\n        return tempFloatRGB;\n    }\n\n    /**\n     * Sets the SceneModelEntity's RGB colorize color, multiplies by the SceneModelEntity's rendered fragment colors.\n     *\n     * Each element of the color is in range ````[0..1]````.\n     *\n     * @type {Number[]}\n     */\n    set colorize(color) { // [0..1, 0..1, 0..1]\n        if (color) {\n            tempIntRGB[0] = Math.floor(color[0] * 255.0); // Quantize\n            tempIntRGB[1] = Math.floor(color[1] * 255.0);\n            tempIntRGB[2] = Math.floor(color[2] * 255.0);\n            for (let i = 0, len = this.meshes.length; i < len; i++) {\n                this.meshes[i]._setColorize(tempIntRGB);\n            }\n        } else {\n            for (let i = 0, len = this.meshes.length; i < len; i++) {\n                this.meshes[i]._setColorize(null);\n            }\n        }\n        if (this._isObject) {\n            const colorized = (!!color);\n            this.scene._objectColorizeUpdated(this, colorized);\n            this._colorizeUpdated = colorized;\n        }\n        this.model.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModelEntity's opacity factor.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    get opacity() {\n        if (this.meshes.length > 0) {\n            return (this.meshes[0]._colorize[3] / 255.0);\n        } else {\n            return 1.0;\n        }\n    }\n\n    /**\n     * Sets the SceneModelEntity's opacity factor.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    set opacity(opacity) {\n        if (this.meshes.length === 0) {\n            return;\n        }\n        const opacityUpdated = (opacity !== null && opacity !== undefined);\n        const lastOpacityQuantized = this.meshes[0]._colorize[3];\n        let opacityQuantized = 255;\n        if (opacityUpdated) {\n            if (opacity < 0) {\n                opacity = 0;\n            } else if (opacity > 1) {\n                opacity = 1;\n            }\n            opacityQuantized = Math.floor(opacity * 255.0); // Quantize\n            if (lastOpacityQuantized === opacityQuantized) {\n                return;\n            }\n        } else {\n            opacityQuantized = 255.0;\n            if (lastOpacityQuantized === opacityQuantized) {\n                return;\n            }\n        }\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setOpacity(opacityQuantized, this._flags);\n        }\n        if (this._isObject) {\n            this.scene._objectOpacityUpdated(this, opacityUpdated);\n            this._opacityUpdated = opacityUpdated;\n        }\n        this.model.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModelEntity's 3D World-space offset.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    get offset() {\n        return this._offset;\n    }\n\n    /**\n     * Sets the SceneModelEntity's 3D World-space offset.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    set offset(offset) {\n        if (offset) {\n            this._offset[0] = offset[0];\n            this._offset[1] = offset[1];\n            this._offset[2] = offset[2];\n        } else {\n            this._offset[0] = 0;\n            this._offset[1] = 0;\n            this._offset[2] = 0;\n        }\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._setOffset(this._offset);\n        }\n        this._aabbDirty = true;\n        this.model._aabbDirty = true;\n        this.scene._aabbDirty = true;\n        this.scene._objectOffsetUpdated(this, offset);\n        this.model.glRedraw();\n    }\n\n    get saoEnabled() {\n        return this.model.saoEnabled;\n    }\n\n    /**\n     * Sets the SceneModelEntity's capMaterial that will be used on the caps generated when this entity is sliced\n     *\n     * Default value is ````null````.\n     *\n     * @type {Material}\n     */\n    set capMaterial(value) {\n        if (this.scene.readableGeometryEnabled) {\n            this._capMaterial = value;\n            this.scene._sectionCaps._onCapMaterialUpdated(this);\n        } else {\n            throw \"The `capMaterial` assignment requires `Viewer::readableGeometryEnabled` to be `true`\";\n        }\n    }\n\n    /**\n     * Gets the SceneModelEntity's capMaterial.\n     *\n     * Default value is ````null````.\n     *\n     * @type {Material}\n     */\n    get capMaterial() {\n        return this._capMaterial;\n    }\n\n    getEachVertex(callback) {\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i].getEachVertex(callback);\n        }\n    }\n\n    getEachIndex(callback) {\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i].getEachIndex(callback);\n        }\n    }\n\n    getGeometryData() {\n        let positionsBase = 0;\n        const positions = [];\n        const indices = [];\n\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            const mesh = this.meshes[i];\n\n            if (mesh.layer.readGeometryData) {\n                const meshGeom = mesh.layer.readGeometryData(mesh.portionId);\n\n                for (let j = 0, len = meshGeom.indices.length; j < len; j++) {\n                    indices.push(meshGeom.indices[j]+positionsBase);\n                }\n\n                for (let j = 0, len = meshGeom.positions.length; j < len; j++) {\n                    positions.push(meshGeom.positions[j]);\n                }\n\n                positionsBase += meshGeom.positions.length / 3;\n            }\n        }\n\n        return { indices, positions };\n    }\n\n    /**\n     * Returns the volume of this SceneModelEntity.\n     *\n     * Only works when {@link Scene.readableGeometryEnabled | Scene.readableGeometryEnabled} is `true` and the\n     * SceneModelEntity contains solid triangle meshes; returns `0` otherwise.\n     *\n     * @returns {number}\n     */\n    get volume() {\n        let volume = 0;\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            const meshVolume = this.meshes[i].volume;\n            if (meshVolume < 0) {\n                return -1;\n            }\n            volume += meshVolume;\n        }\n        return volume;\n    }\n\n    /**\n     * Returns the surface area of this SceneModelEntity.\n     *\n     * Only works when {@link Scene.readableGeometryEnabled | Scene.readableGeometryEnabled} is `true` and the\n     * SceneModelEntity contains triangle meshes; returns `0` otherwise.\n     *\n     * @returns {number}\n     */\n    get surfaceArea() {\n        let surfaceArea = 0;\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            const meshSurfaceArea = this.meshes[i].surfaceArea;\n            if (meshSurfaceArea >= 0) {\n                surfaceArea += meshSurfaceArea;\n            }\n        }\n        return surfaceArea > 0 ? surfaceArea : -1;\n    }\n\n    _getFlag(flag) {\n        return !!(this._flags & flag);\n    }\n\n    _finalize() {\n        const scene = this.model.scene;\n        if (this._isObject) {\n            if (this.visible) {\n                scene._objectVisibilityUpdated(this);\n            }\n            if (this.highlighted) {\n                scene._objectHighlightedUpdated(this);\n            }\n            if (this.xrayed) {\n                scene._objectXRayedUpdated(this);\n            }\n            if (this.selected) {\n                scene._objectSelectedUpdated(this);\n            }\n        }\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._finalize(this._flags);\n        }\n    }\n\n    _finalize2() {\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._finalize2();\n        }\n    }\n\n    _destroy() {\n        const scene = this.model.scene;\n        if (this._isObject) {\n            scene._deregisterObject(this);\n            if (this.visible) {\n                scene._deRegisterVisibleObject(this);\n            }\n            if (this.xrayed) {\n                scene._deRegisterXRayedObject(this);\n            }\n            if (this.selected) {\n                scene._deRegisterSelectedObject(this);\n            }\n            if (this.highlighted) {\n                scene._deRegisterHighlightedObject(this);\n            }\n            if (this._colorizeUpdated) {\n                this.scene._deRegisterColorizedObject(this);\n            }\n            if (this._opacityUpdated) {\n                this.scene._deRegisterOpacityObject(this);\n            }\n            if (this._offset && (this._offset[0] !== 0 || this._offset[1] !== 0 || this._offset[2] !== 0)) {\n                this.scene._deRegisterOffsetObject(this);\n            }\n        }\n        for (let i = 0, len = this.meshes.length; i < len; i++) {\n            this.meshes[i]._destroy();\n        }\n        scene._aabbDirty = true;\n    }\n}\n\nconst angleAxis = math.vec4(4);\nconst q1 = math.vec4();\nconst q2 = math.vec4();\nconst xAxis = math.vec3([1, 0, 0]);\nconst yAxis = math.vec3([0, 1, 0]);\nconst zAxis = math.vec3([0, 0, 1]);\n\nmath.vec3(3);\nmath.vec3(3);\n\nconst identityMat = math.identityMat4();\n\n/**\n * A dynamically-updatable transform within a {@link SceneModel}.\n *\n * * Can be composed into hierarchies\n * * Shared by multiple {@link SceneModelMesh}es\n * * Created with {@link SceneModel#createTransform}\n * * Stored by ID in {@link SceneModel#transforms}\n * * Referenced by {@link SceneModelMesh#transform}\n */\nclass SceneModelTransform {\n\n    /**\n     * @private\n     */\n    constructor(cfg) {\n        this._model = cfg.model;\n\n        /**\n         * Unique ID of this SceneModelTransform.\n         *\n         * The SceneModelTransform is registered against this ID in {@link SceneModel#transforms}.\n         */\n        this.id = cfg.id;\n\n        this._parentTransform = cfg.parent;\n        this._childTransforms = [];\n        this._meshes = [];\n        this._scale = new Float32Array([1,1,1]);\n        this._quaternion = math.identityQuaternion(new Float32Array(4));\n        this._rotation = new Float32Array(3);\n        this._position = new Float32Array(3);\n        this._localMatrix = math.identityMat4(new Float32Array(16));\n        this._worldMatrix = math.identityMat4(new Float32Array(16));\n        this._localMatrixDirty = true;\n        this._worldMatrixDirty = true;\n\n        if (cfg.matrix) {\n            this.matrix = cfg.matrix;\n        } else {\n            this.scale = cfg.scale;\n            this.position = cfg.position;\n            if (cfg.quaternion) ; else {\n                this.rotation = cfg.rotation;\n            }\n        }\n        if (cfg.parent) {\n            cfg.parent._addChildTransform(this);\n        }\n    }\n\n    _addChildTransform(childTransform) {\n        this._childTransforms.push(childTransform);\n        childTransform._parentTransform = this;\n        childTransform._transformDirty();\n        childTransform._setSubtreeAABBsDirty(this);\n    }\n\n    _addMesh(mesh) {\n        this._meshes.push(mesh);\n        mesh.transform = this;\n        // childTransform._setWorldMatrixDirty();\n        // childTransform._setAABBDirty();\n    }\n\n    /**\n     * The optional parent SceneModelTransform.\n     *\n     * @type {SceneModelTransform}\n     */\n    get parentTransform() {\n        return this._parentTransform;\n    }\n\n    /**\n     * The {@link SceneModelMesh}es transformed by this SceneModelTransform.\n     *\n     * @returns {[]}\n     */\n    get meshes() {\n        return this._meshes;\n    }\n\n    /**\n     * Sets the SceneModelTransform's local translation.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    set position(value) {\n        this._position.set(value || [0, 0, 0]);\n        this._setLocalMatrixDirty();\n        this._model.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModelTransform's translation.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    get position() {\n        return this._position;\n    }\n\n    /**\n     * Sets the SceneModelTransform's rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    set rotation(value) {\n        this._rotation.set(value || [0, 0, 0]);\n        math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\n        this._setLocalMatrixDirty();\n        this._model.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModelTransform's rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    get rotation() {\n        return this._rotation;\n    }\n\n    /**\n     * Sets the SceneModelTransform's rotation quaternion.\n     *\n     * Default value is ````[0,0,0,1]````.\n     *\n     * @type {Number[]}\n     */\n    set quaternion(value) {\n        this._quaternion.set(value || [0, 0, 0, 1]);\n        math.quaternionToEuler(this._quaternion, \"XYZ\", this._rotation);\n        this._setLocalMatrixDirty();\n        this._model.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModelTransform's rotation quaternion.\n     *\n     * Default value is ````[0,0,0,1]````.\n     *\n     * @type {Number[]}\n     */\n    get quaternion() {\n        return this._quaternion;\n    }\n\n    /**\n     * Sets the SceneModelTransform's scale.\n     *\n     * Default value is ````[1,1,1]````.\n     *\n     * @type {Number[]}\n     */\n    set scale(value) {\n        this._scale.set(value || [1, 1, 1]);\n        this._setLocalMatrixDirty();\n        this._model.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModelTransform's scale.\n     *\n     * Default value is ````[1,1,1]````.\n     *\n     * @type {Number[]}\n     */\n    get scale() {\n        return this._scale;\n    }\n\n    /**\n     * Sets the SceneModelTransform's transform matrix.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @type {Number[]}\n     */\n    set matrix(value) {\n        if (!this._localMatrix) {\n            this._localMatrix = math.identityMat4();\n        }\n        this._localMatrix.set(value || identityMat);\n        math.decomposeMat4(this._localMatrix, this._position, this._quaternion, this._scale);\n        this._localMatrixDirty = false;\n        this._transformDirty();\n        this._model.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModelTransform's transform matrix.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @type {Number[]}\n     */\n    get matrix() {\n        if (this._localMatrixDirty) {\n            if (!this._localMatrix) {\n                this._localMatrix = math.identityMat4();\n            }\n            math.composeMat4(this._position, this._quaternion, this._scale, this._localMatrix);\n            this._localMatrixDirty = false;\n        }\n        return this._localMatrix;\n    }\n\n    /**\n     * Gets the SceneModelTransform's World matrix.\n     *\n     * @property worldMatrix\n     * @type {Number[]}\n     */\n    get worldMatrix() {\n        if (this._worldMatrixDirty) {\n            this._buildWorldMatrix();\n        }\n        return this._worldMatrix;\n    }\n\n    /**\n     * Rotates the SceneModelTransform about the given axis by the given increment.\n     *\n     * @param {Number[]} axis Local axis about which to rotate.\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotate(axis, angle) {\n        angleAxis[0] = axis[0];\n        angleAxis[1] = axis[1];\n        angleAxis[2] = axis[2];\n        angleAxis[3] = angle * math.DEGTORAD;\n        math.angleAxisToQuaternion(angleAxis, q1);\n        math.mulQuaternions(this.quaternion, q1, q2);\n        this.quaternion = q2;\n        this._setLocalMatrixDirty();\n        this._model.glRedraw();\n        return this;\n    }\n\n    /**\n     * Rotates the SceneModelTransform about the given World-space axis by the given increment.\n     *\n     * @param {Number[]} axis Local axis about which to rotate.\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateOnWorldAxis(axis, angle) {\n        angleAxis[0] = axis[0];\n        angleAxis[1] = axis[1];\n        angleAxis[2] = axis[2];\n        angleAxis[3] = angle * math.DEGTORAD;\n        math.angleAxisToQuaternion(angleAxis, q1);\n        math.mulQuaternions(q1, this.quaternion, q1);\n        //this.quaternion.premultiply(q1);\n        return this;\n    }\n\n    /**\n     * Rotates the SceneModelTransform about the local X-axis by the given increment.\n     *\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateX(angle) {\n        return this.rotate(xAxis, angle);\n    }\n\n    /**\n     * Rotates the SceneModelTransform about the local Y-axis by the given increment.\n     *\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateY(angle) {\n        return this.rotate(yAxis, angle);\n    }\n\n    /**\n     * Rotates the SceneModelTransform about the local Z-axis by the given increment.\n     *\n     * @param {Number} angle Angle increment in degrees.\n     */\n    rotateZ(angle) {\n        return this.rotate(zAxis, angle);\n    }\n\n    /**\n     * Translates the SceneModelTransform along the local axis by the given increment.\n     *\n     * @param {Number[]} axis Normalized local space 3D vector along which to translate.\n     * @param {Number} distance Distance to translate along  the vector.\n     */\n    translate(axis) {\n        this._position[0] += axis[0];\n        this._position[1] += axis[1];\n        this._position[2] += axis[2];\n        this._setLocalMatrixDirty();\n        this._model.glRedraw();\n        return this;\n    }\n\n    /**\n     * Translates the SceneModelTransform along the local X-axis by the given increment.\n     *\n     * @param {Number} distance Distance to translate along  the X-axis.\n     */\n    translateX(distance) {\n        this._position[0] += distance;\n        this._setLocalMatrixDirty();\n        this._model.glRedraw();\n        return this;\n    }\n\n    /**\n     * Translates the SceneModelTransform along the local Y-axis by the given increment.\n     *\n     * @param {Number} distance Distance to translate along  the Y-axis.\n     */\n    translateY(distance) {\n        this._position[1] += distance;\n        this._setLocalMatrixDirty();\n        this._model.glRedraw();\n        return this;\n    }\n\n    /**\n     * Translates the SceneModelTransform along the local Z-axis by the given increment.\n     *\n     * @param {Number} distance Distance to translate along  the Z-axis.\n     */\n    translateZ(distance) {\n        this._position[2] += distance;\n        this._setLocalMatrixDirty();\n        this._model.glRedraw();\n        return this;\n    }\n\n    _setLocalMatrixDirty() {\n        this._localMatrixDirty = true;\n        this._transformDirty();\n    }\n\n    _transformDirty() {\n        this._worldMatrixDirty = true;\n        for (let i = 0, len = this._childTransforms.length; i < len; i++) {\n            const childTransform = this._childTransforms[i];\n            childTransform._transformDirty();\n            if (childTransform._meshes && childTransform._meshes.length > 0) {\n               const meshes = childTransform._meshes;\n               for (let j =0, lenj = meshes.length; j < lenj; j++) {\n                 meshes[j]._transformDirty();\n               }\n            }\n        }\n        if (this._meshes && this._meshes.length > 0) {\n            const meshes = this._meshes;\n            for (let j =0, lenj = meshes.length; j < lenj; j++) {\n                meshes[j]._transformDirty();\n            }\n        }\n    }\n\n    _buildWorldMatrix() {\n        const localMatrix = this.matrix;\n        if (!this._parentTransform) {\n            for (let i = 0, len = localMatrix.length; i < len; i++) {\n                this._worldMatrix[i] = localMatrix[i];\n            }\n        } else {\n            math.mulMat4(this._parentTransform.worldMatrix, localMatrix, this._worldMatrix);\n        }\n        this._worldMatrixDirty = false;\n    }\n\n    _setSubtreeAABBsDirty(sceneTransform) {\n        sceneTransform._aabbDirty = true;\n        if (sceneTransform._childTransforms) {\n            for (let i = 0, len = sceneTransform._childTransforms.length; i < len; i++) {\n                this._setSubtreeAABBsDirty(sceneTransform._childTransforms[i]);\n            }\n        }\n    }\n}\n\nconst tempVec3a$c = math.vec3();\n\nconst tempOBB3 = math.OBB3();\nconst tempQuaternion = math.vec4();\n\nconst DEFAULT_SCALE = math.vec3([1, 1, 1]);\nconst DEFAULT_POSITION = math.vec3([0, 0, 0]);\nmath.vec3([0, 0, 0]);\nconst DEFAULT_QUATERNION = math.identityQuaternion();\nconst DEFAULT_MATRIX = math.identityMat4();\n\nconst DEFAULT_COLOR_TEXTURE_ID = \"defaultColorTexture\";\nconst DEFAULT_METAL_ROUGH_TEXTURE_ID = \"defaultMetalRoughTexture\";\nconst DEFAULT_NORMALS_TEXTURE_ID = \"defaultNormalsTexture\";\nconst DEFAULT_EMISSIVE_TEXTURE_ID = \"defaultEmissiveTexture\";\nconst DEFAULT_OCCLUSION_TEXTURE_ID = \"defaultOcclusionTexture\";\nconst DEFAULT_TEXTURE_SET_ID = \"defaultTextureSet\";\n\nconst defaultCompressedColor = new Uint8Array([255, 255, 255]);\n\nconst VBO_INSTANCED = 0;\nconst VBO_BATCHED = 1;\nconst DTX = 2;\n\n/**\n * @desc A high-performance model representation for efficient rendering and low memory usage.\n *\n * # Examples\n *\n * Internally, SceneModel uses a combination of several different techniques to render and represent\n * the different parts of a typical model. Each of the live examples at these links is designed to \"unit test\" one of these\n * techniques, in isolation. If some bug occurs in SceneModel, we use these tests to debug, but they also\n * serve to demonstrate how to use the capabilities of SceneModel programmatically.\n *\n * * [Loading building models into SceneModels](/examples/buildings)\n * * [Loading city models into SceneModels](/examples/cities)\n * * [Loading LiDAR scans into SceneModels](/examples/lidar)\n * * [Loading CAD models into SceneModels](/examples/cad)\n * * [SceneModel feature tests](/examples/scenemodel)\n *\n * # Overview\n *\n * While xeokit's standard [scene graph](https://github.com/xeokit/xeokit-sdk/wiki/Scene-Graphs) is great for gizmos and medium-sized models, it doesn't scale up to millions of objects in terms of memory and rendering efficiency.\n *\n * For huge models, we have the ````SceneModel```` representation, which is optimized to pack large amounts of geometry into memory and render it efficiently using WebGL.\n *\n * ````SceneModel```` is the default model representation loaded by  (at least) {@link GLTFLoaderPlugin}, {@link XKTLoaderPlugin} and  {@link WebIFCLoaderPlugin}.\n *\n * In this tutorial you'll learn how to use ````SceneModel```` to create high-detail content programmatically. Ordinarily you'd be learning about ````SceneModel```` if you were writing your own model loader plugins.\n *\n * # Contents\n *\n * - [SceneModel](#DataTextureSceneModel)\n * - [GPU-Resident Geometry](#gpu-resident-geometry)\n * - [Picking](#picking)\n * - [Example 1: Geometry Instancing](#example-1--geometry-instancing)\n * - [Finalizing a SceneModel](#finalizing-a-DataTextureSceneModel)\n * - [Finding Entities](#finding-entities)\n * - [Example 2: Geometry Batching](#example-2--geometry-batching)\n * - [Classifying with Metadata](#classifying-with-metadata)\n * - [Querying Metadata](#querying-metadata)\n * - [Metadata Structure](#metadata-structure)\n * - [RTC Coordinates](#rtc-coordinates-for-double-precision)\n *   - [Example 3: RTC Coordinates with Geometry Instancing](#example-2--rtc-coordinates-with-geometry-instancing)\n *   - [Example 4: RTC Coordinates with Geometry Batching](#example-2--rtc-coordinates-with-geometry-batching)\n *\n * ## SceneModel\n *\n * ````SceneModel```` uses two rendering techniques internally:\n *\n * 1. ***Geometry batching*** for unique geometries, combining those into a single WebGL geometry buffer, to render in one draw call, and\n * 2. ***geometry instancing*** for geometries that are shared by multiple meshes, rendering all instances of each shared geometry in one draw call.\n *\n * <br>\n * These techniques come with certain limitations:\n *\n * * Non-realistic rendering - while scene graphs can use xeokit's full set of material workflows, ````SceneModel```` uses simple Lambertian shading without textures.\n * * Static transforms - transforms within a ````SceneModel```` are static and cannot be dynamically translated, rotated and scaled the way {@link Node}s and {@link Mesh}es in scene graphs can.\n * * Immutable model representation - while scene graph {@link Node}s and\n * {@link Mesh}es can be dynamically plugged together, ````SceneModel```` is immutable,\n * since it packs its geometries into buffers and instanced arrays.\n *\n * ````SceneModel````'s API allows us to exploit batching and instancing, while exposing its elements as\n * abstract {@link Entity} types.\n *\n * {@link Entity} is the abstract base class for\n * the various xeokit components that represent models, objects, or anonymous visible elements. An Entity has a unique ID and can be\n * individually shown, hidden, selected, highlighted, ghosted, culled, picked and clipped, and has its own World-space boundary.\n *\n * * A ````SceneModel```` is an {@link Entity} that represents a model.\n * * A ````SceneModel```` represents each of its objects with an {@link Entity}.\n * * Each {@link Entity} has one or more meshes that define its shape.\n * * Each mesh has either its own unique geometry, or shares a geometry with other meshes.\n *\n * ## GPU-Resident Geometry\n *\n * For a low memory footprint, ````SceneModel```` stores its geometries in GPU memory only, compressed (quantized) as integers. Unfortunately, GPU-resident geometry is\n * not readable by JavaScript.\n *\n *\n * ## Example 1: Geometry Instancing\n *\n * In the example below, we'll use a ````SceneModel````\n * to build a simple table model using geometry instancing.\n *\n * We'll start by adding a reusable box-shaped geometry to our ````SceneModel````.\n *\n * Then, for each object in our model we'll add an {@link Entity}\n * that has a mesh that instances our box geometry, transforming and coloring the instance.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/index.html#sceneRepresentation_SceneModel_instancing)\n *\n * ````javascript\n * import {Viewer, SceneModel} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * // Build a SceneModel representing a table\n * // with four legs, using geometry instancing\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n *     id: \"table\",\n *     isModel: true, // <--- Registers SceneModel in viewer.scene.models\n *     position: [0, 0, 0],\n *     scale: [1, 1, 1],\n *     rotation: [0, 0, 0]\n * });\n *\n * // Create a reusable geometry within the SceneModel\n * // We'll instance this geometry by five meshes\n *\n * sceneModel.createGeometry({\n *\n *     id: \"myBoxGeometry\",\n *\n *     // The primitive type - allowed values are \"points\", \"lines\" and \"triangles\".\n *     // See the OpenGL/WebGL specification docs\n *     // for how the coordinate arrays are supposed to be laid out.\n *     primitive: \"triangles\",\n *\n *     // The vertices - eight for our cube, each\n *     // one spanning three array elements for X,Y and Z\n *     positions: [\n *          1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // v0-v1-v2-v3 front\n *          1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, // v0-v3-v4-v1 right\n *          1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, // v0-v1-v6-v1 top\n *          -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // v1-v6-v7-v2 left\n *          -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, // v7-v4-v3-v2 bottom\n *          1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1 // v4-v7-v6-v1 back\n *     ],\n *\n *     // Normal vectors, one for each vertex\n *     normals: [\n *         0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0-v1-v2-v3 front\n *         1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4-v5 right\n *         0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0-v5-v6-v1 top\n *         -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1-v6-v7-v2 left\n *         0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, // v7-v4-v3-v2 bottom\n *         0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1 // v4-v7-v6-v5 back\n *     ],\n *\n *     // Indices - these organise the positions and and normals\n *     // into geometric primitives in accordance with the \"primitive\" parameter,\n *     // in this case a set of three indices for each triangle.\n *     //\n *     // Note that each triangle is specified in counter-clockwise winding order.\n *     //\n *     indices: [\n *         0, 1, 2, 0, 2, 3, // front\n *         4, 5, 6, 4, 6, 7, // right\n *         8, 9, 10, 8, 10, 11, // top\n *         12, 13, 14, 12, 14, 15, // left\n *         16, 17, 18, 16, 18, 19, // bottom\n *         20, 21, 22, 20, 22, 23\n *     ]\n * });\n *\n * // Red table leg\n *\n * sceneModel.createMesh({\n *     id: \"redLegMesh\",\n *     geometryId: \"myBoxGeometry\",\n *     position: [-4, -6, -4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n *     id: \"redLeg\",\n *     meshIds: [\"redLegMesh\"],\n *     isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Green table leg\n *\n * sceneModel.createMesh({\n *     id: \"greenLegMesh\",\n *     geometryId: \"myBoxGeometry\",\n *     position: [4, -6, -4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n *     id: \"greenLeg\",\n *     meshIds: [\"greenLegMesh\"],\n *     isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Blue table leg\n *\n * sceneModel.createMesh({\n *     id: \"blueLegMesh\",\n *     geometryId: \"myBoxGeometry\",\n *     position: [4, -6, 4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n *     id: \"blueLeg\",\n *     meshIds: [\"blueLegMesh\"],\n *     isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Yellow table leg\n *\n * sceneModel.createMesh({\n *      id: \"yellowLegMesh\",\n *      geometryId: \"myBoxGeometry\",\n *      position: [-4, -6, 4],\n *      scale: [1, 3, 1],\n *      rotation: [0, 0, 0],\n *      color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n *     id: \"yellowLeg\",\n *     meshIds: [\"yellowLegMesh\"],\n *     isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Purple table top\n *\n * sceneModel.createMesh({\n *     id: \"purpleTableTopMesh\",\n *     geometryId: \"myBoxGeometry\",\n *     position: [0, -3, 0],\n *     scale: [6, 0.5, 6],\n *     rotation: [0, 0, 0],\n *     color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n *     id: \"purpleTableTop\",\n *     meshIds: [\"purpleTableTopMesh\"],\n *     isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *  ````\n *\n * ## Finalizing a SceneModel\n *\n * Before we can view and interact with our ````SceneModel````, we need to **finalize** it. Internally, this causes the ````SceneModel```` to build the\n * vertex buffer objects (VBOs) that support our geometry instances. When using geometry batching (see next example),\n * this causes ````SceneModel```` to build the VBOs that combine the batched geometries. Note that you can do both instancing and\n * batching within the same ````SceneModel````.\n *\n * Once finalized, we can't add anything more to our ````SceneModel````.\n *\n * ```` javascript\n * SceneModel.finalize();\n * ````\n *\n * ## Finding Entities\n *\n * As mentioned earlier, {@link Entity} is\n * the abstract base class for components that represent models, objects, or just\n * anonymous visible elements.\n *\n * Since we created configured our ````SceneModel```` with ````isModel: true````,\n * we're able to find it as an Entity by ID in ````viewer.scene.models````. Likewise, since\n * we configured each of its Entities with ````isObject: true````, we're able to\n * find them in  ````viewer.scene.objects````.\n *\n *\n * ````javascript\n * // Get the whole table model Entity\n * const table = viewer.scene.models[\"table\"];\n *\n *  // Get some leg object Entities\n * const redLeg = viewer.scene.objects[\"redLeg\"];\n * const greenLeg = viewer.scene.objects[\"greenLeg\"];\n * const blueLeg = viewer.scene.objects[\"blueLeg\"];\n * ````\n *\n * ## Example 2: Geometry Batching\n *\n * Let's once more use a ````SceneModel````\n * to build the simple table model, this time exploiting geometry batching.\n *\n *  [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/index.html#sceneRepresentation_SceneModel_batching)\n *\n * ````javascript\n * import {Viewer, SceneModel} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * // Create a SceneModel representing a table with four legs, using geometry batching\n * const sceneModel = new SceneModel(viewer.scene, {\n *     id: \"table\",\n *     isModel: true,  // <--- Registers SceneModel in viewer.scene.models\n *     position: [0, 0, 0],\n *     scale: [1, 1, 1],\n *     rotation: [0, 0, 0]\n * });\n *\n * // Red table leg\n *\n * sceneModel.createMesh({\n *     id: \"redLegMesh\",\n *\n *     // Geometry arrays are same as for the earlier batching example\n *     primitive: \"triangles\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n *     position: [-4, -6, -4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n *     id: \"redLeg\",\n *     meshIds: [\"redLegMesh\"],\n *     isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Green table leg\n *\n * sceneModel.createMesh({\n *     id: \"greenLegMesh\",\n *     primitive: \"triangles\",\n *     primitive: \"triangles\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n *     position: [4, -6, -4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n *     id: \"greenLeg\",\n *     meshIds: [\"greenLegMesh\"],\n *     isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Blue table leg\n *\n * sceneModel.createMesh({\n *     id: \"blueLegMesh\",\n *     primitive: \"triangles\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n *     position: [4, -6, 4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n *     id: \"blueLeg\",\n *     meshIds: [\"blueLegMesh\"],\n *     isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Yellow table leg object\n *\n * sceneModel.createMesh({\n *     id: \"yellowLegMesh\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n *     position: [-4, -6, 4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n *     id: \"yellowLeg\",\n *     meshIds: [\"yellowLegMesh\"],\n *     isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Purple table top\n *\n * sceneModel.createMesh({\n *     id: \"purpleTableTopMesh\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n *     position: [0, -3, 0],\n *     scale: [6, 0.5, 6],\n *     rotation: [0, 0, 0],\n *     color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n *     id: \"purpleTableTop\",\n *     meshIds: [\"purpleTableTopMesh\"],\n *     isObject: true // <---- Registers Entity by ID on viewer.scene.objects\n * });\n *\n * // Finalize the SceneModel.\n *\n * SceneModel.finalize();\n *\n * // Find BigModelNodes by their model and object IDs\n *\n * // Get the whole table model\n * const table = viewer.scene.models[\"table\"];\n *\n * // Get some leg objects\n * const redLeg = viewer.scene.objects[\"redLeg\"];\n * const greenLeg = viewer.scene.objects[\"greenLeg\"];\n * const blueLeg = viewer.scene.objects[\"blueLeg\"];\n * ````\n *\n * ## Classifying with Metadata\n *\n * In the previous examples, we used ````SceneModel```` to build\n * two versions of the same table model, to demonstrate geometry batching and geometry instancing.\n *\n * We'll now classify our {@link Entity}s with metadata. This metadata\n * will work the same for both our examples, since they create the exact same structure of {@link Entity}s\n * to represent their models and objects. The abstract Entity type is, after all, intended to provide an abstract interface through which differently-implemented scene content can be accessed uniformly.\n *\n * To create the metadata, we'll create a {@link MetaModel} for our model,\n * with a {@link MetaObject} for each of it's objects. The MetaModel and MetaObjects\n * get the same IDs as the {@link Entity}s that represent their model and objects within our scene.\n *\n * ```` javascript\n * const furnitureMetaModel = viewer.metaScene.createMetaModel(\"furniture\", {         // Creates a MetaModel in the MetaScene\n *\n *      \"projectId\": \"myTableProject\",\n *      \"revisionId\": \"V1.0\",\n *\n *      \"metaObjects\": [\n *          {                               // Creates a MetaObject in the MetaModel\n *              \"id\": \"table\",\n *              \"name\": \"Table\",            // Same ID as an object Entity\n *              \"type\": \"furniture\",        // Arbitrary type, could be IFC type\n *              \"properties\": {             // Arbitrary properties, could be IfcPropertySet\n *                  \"cost\": \"200\"\n *              }\n *          },\n *          {\n *              \"id\": \"redLeg\",\n *              \"name\": \"Red table Leg\",\n *              \"type\": \"leg\",\n *              \"parent\": \"table\",           // References first MetaObject as parent\n *              \"properties\": {\n *                  \"material\": \"wood\"\n *              }\n *          },\n *          {\n *              \"id\": \"greenLeg\",           // Node with corresponding id does not need to exist\n *              \"name\": \"Green table leg\",  // and MetaObject does not need to exist for Node with an id\n *              \"type\": \"leg\",\n *              \"parent\": \"table\",\n *              \"properties\": {\n *                  \"material\": \"wood\"\n *              }\n *          },\n *          {\n *              \"id\": \"blueLeg\",\n *              \"name\": \"Blue table leg\",\n *              \"type\": \"leg\",\n *              \"parent\": \"table\",\n *              \"properties\": {\n *                  \"material\": \"wood\"\n *              }\n *          },\n *          {\n *              \"id\": \"yellowLeg\",\n *              \"name\": \"Yellow table leg\",\n *              \"type\": \"leg\",\n *              \"parent\": \"table\",\n *              \"properties\": {\n *                  \"material\": \"wood\"\n *              }\n *          },\n *          {\n *              \"id\": \"tableTop\",\n *              \"name\": \"Purple table top\",\n *              \"type\": \"surface\",\n *              \"parent\": \"table\",\n *              \"properties\": {\n *                  \"material\": \"formica\",\n *                  \"width\": \"60\",\n *                  \"depth\": \"60\",\n *                  \"thickness\": \"5\"\n *              }\n *          }\n *      ]\n *  });\n * ````\n *\n * ## Querying Metadata\n *\n * Having created and classified our model (either the instancing or batching example), we can now find the {@link MetaModel}\n * and {@link MetaObject}s using the IDs of their\n * corresponding {@link Entity}s.\n *\n * ````JavaScript\n * const furnitureMetaModel = scene.metaScene.metaModels[\"furniture\"];\n *\n * const redLegMetaObject = scene.metaScene.metaObjects[\"redLeg\"];\n * ````\n *\n * In the snippet below, we'll log metadata on each {@link Entity} we click on:\n *\n * ````JavaScript\n * viewer.scene.input.on(\"mouseclicked\", function (coords) {\n *\n *      const hit = viewer.scene.pick({\n *          canvasPos: coords\n *      });\n *\n *      if (hit) {\n *          const entity = hit.entity;\n *          const metaObject = viewer.metaScene.metaObjects[entity.id];\n *          if (metaObject) {\n *              console.log(JSON.stringify(metaObject.getJSON(), null, \"\\t\"));\n *          }\n *      }\n *  });\n * ````\n *\n * ## Metadata Structure\n *\n * The {@link MetaModel}\n * organizes its {@link MetaObject}s in\n * a tree that describes their structural composition:\n *\n * ````JavaScript\n * // Get metadata on the root object\n * const tableMetaObject = furnitureMetaModel.rootMetaObject;\n *\n * // Get metadata on the leg objects\n * const redLegMetaObject = tableMetaObject.children[0];\n * const greenLegMetaObject = tableMetaObject.children[1];\n * const blueLegMetaObject = tableMetaObject.children[2];\n * const yellowLegMetaObject = tableMetaObject.children[3];\n * ````\n *\n * Given an {@link Entity}, we can find the object or model of which it is a part, or the objects that comprise it. We can also generate UI\n * components from the metadata, such as the tree view demonstrated in [this demo](https://xeokit.github.io/xeokit-sdk/examples/index.html#BIMOffline_glTF_OTCConferenceCenter).\n *\n * This hierarchy allows us to express the hierarchical structure of a model while representing it in\n * various ways in the 3D scene (such as with ````SceneModel````, which\n * has a non-hierarchical scene representation).\n *\n * Note also that a {@link MetaObject} does not need to have a corresponding\n * {@link Entity} and vice-versa.\n *\n * # RTC Coordinates for Double Precision\n *\n * ````SceneModel```` can emulate 64-bit precision on GPUs using relative-to-center (RTC) coordinates.\n *\n * Consider a model that contains many small objects, but with such large spatial extents that 32 bits of GPU precision (accurate to ~7 digits) will not be sufficient to render all of the the objects without jittering.\n *\n * To prevent jittering, we could spatially subdivide the objects into \"tiles\". Each tile would have a center position, and the positions of the objects within the tile would be relative to that center (\"RTC coordinates\").\n *\n * While the center positions of the tiles would be 64-bit values, the object positions only need to be 32-bit.\n *\n * Internally, when rendering an object with RTC coordinates, xeokit first temporarily translates the camera viewing matrix by the object's tile's RTC center, on the CPU, using 64-bit math.\n *\n * Then xeokit loads the viewing matrix into its WebGL shaders, where math happens at 32-bit precision. Within the shaders, the matrix is effectively down-cast to 32-bit precision, and the object's 32-bit vertex positions are transformed by the matrix.\n *\n * We see no jittering, because with RTC a detectable loss of GPU accuracy only starts happening to objects as they become very distant from the camera viewpoint, at which point they are too small to be discernible anyway.\n *\n * ## RTC Coordinates with Geometry Instancing\n *\n * To use RTC with ````SceneModel```` geometry instancing, we specify an RTC center for the geometry via its ````origin```` parameter. Then ````SceneModel```` assumes that all meshes that instance that geometry are within the same RTC coordinate system, ie. the meshes ````position```` and ````rotation```` properties are assumed to be relative to the geometry's ````origin````.\n *\n * For simplicity, our example's meshes all instance the same geometry. Therefore, our example model has only one RTC center.\n *\n * Note that the axis-aligned World-space boundary (AABB) of our model is ````[ -6, -9, -6, 1000000006, -2.5, 1000000006]````.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/index.html#sceneRepresentation_SceneModel_batching)\n *\n * ````javascript\n * const origin = [100000000, 0, 100000000];\n *\n * sceneModel.createGeometry({\n *     id: \"box\",\n *     primitive: \"triangles\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg1\",\n *     geometryId: \"box\",\n *     position: [-4, -6, -4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [1, 0.3, 0.3],\n *     origin: origin\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg1\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg2\",\n *     geometryId: \"box\",\n *     position: [4, -6, -4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [0.3, 1.0, 0.3],\n *     origin: origin\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg2\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg3\",\n *     geometryId: \"box\",\n *     position: [4, -6, 4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [0.3, 0.3, 1.0],\n *     origin: origin\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg3\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg4\",\n *     geometryId: \"box\",\n *     position: [-4, -6, 4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [1.0, 1.0, 0.0],\n *     origin: origin\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg4\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"top\",\n *     geometryId: \"box\",\n *     position: [0, -3, 0],\n *     scale: [6, 0.5, 6],\n *     rotation: [0, 0, 0],\n *     color: [1.0, 0.3, 1.0],\n *     origin: origin\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"top\"],\n *     isObject: true\n * });\n * ````\n *\n * ## RTC Coordinates with Geometry Batching\n *\n * To use RTC with ````SceneModel```` geometry batching, we specify an RTC center (````origin````) for each mesh. For performance, we try to have as many meshes share the same value for ````origin```` as possible. Each mesh's ````positions````, ````position```` and ````rotation```` properties are assumed to be relative to ````origin````.\n *\n * For simplicity, the meshes in our example all share the same RTC center.\n *\n * The axis-aligned World-space boundary (AABB) of our model is ````[ -6, -9, -6, 1000000006, -2.5, 1000000006]````.\n *\n * [![](http://xeokit.io/img/docs/sceneGraph.png)](https://xeokit.github.io/xeokit-sdk/examples/index.html#sceneRepresentation_SceneModel_batching)\n *\n * ````javascript\n * const origin = [100000000, 0, 100000000];\n *\n * sceneModel.createMesh({\n *     id: \"leg1\",\n *     origin: origin, // This mesh's positions and transforms are relative to the RTC center\n *     primitive: \"triangles\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n *     position: [-4, -6, -4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg1\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg2\",\n *     origin: origin, // This mesh's positions and transforms are relative to the RTC center\n *     primitive: \"triangles\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n *     position: [4, -6, -4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg2\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg3\",\n *     origin: origin, // This mesh's positions and transforms are relative to the RTC center\n *     primitive: \"triangles\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n *     position: [4, -6, 4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg3\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg4\",\n *     origin: origin, // This mesh's positions and transforms are relative to the RTC center\n *     primitive: \"triangles\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n *     position: [-4, -6, 4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg4\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"top\",\n *     origin: origin, // This mesh's positions and transforms are relative to the RTC center\n *     primitive: \"triangles\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n *     position: [0, -3, 0],\n *     scale: [6, 0.5, 6],\n *     rotation: [0, 0, 0],\n *     color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"top\"],\n *     isObject: true\n * });\n * ````\n *\n * ## Positioning at World-space coordinates\n *\n * To position a SceneModel at given double-precision World coordinates, we can\n * configure the ````origin```` of the SceneModel itself. The ````origin```` is a double-precision\n * 3D World-space position at which the SceneModel will be located.\n *\n * Note that ````position```` is a single-precision offset relative to ````origin````.\n *\n * ````javascript\n * const origin = [100000000, 0, 100000000];\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n *     id: \"table\",\n *     isModel: true,\n *     origin: origin, // Everything in this SceneModel is relative to this RTC center\n *     position: [0, 0, 0],\n *     scale: [1, 1, 1],\n *     rotation: [0, 0, 0]\n * });\n *\n * sceneModel.createGeometry({\n *     id: \"box\",\n *     primitive: \"triangles\",\n *     positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],\n *     normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],\n *     indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg1\",\n *     geometryId: \"box\",\n *     position: [-4, -6, -4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [1, 0.3, 0.3]\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg1\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg2\",\n *     geometryId: \"box\",\n *     position: [4, -6, -4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [0.3, 1.0, 0.3]\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg2\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg3\",\n *     geometryId: \"box\",\n *     position: [4, -6, 4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [0.3, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg3\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"leg4\",\n *     geometryId: \"box\",\n *     position: [-4, -6, 4],\n *     scale: [1, 3, 1],\n *     rotation: [0, 0, 0],\n *     color: [1.0, 1.0, 0.0]\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"leg4\"],\n *     isObject: true\n * });\n *\n * sceneModel.createMesh({\n *     id: \"top\",\n *     geometryId: \"box\",\n *     position: [0, -3, 0],\n *     scale: [6, 0.5, 6],\n *     rotation: [0, 0, 0],\n *     color: [1.0, 0.3, 1.0]\n * });\n *\n * sceneModel.createEntity({\n *     meshIds: [\"top\"],\n *     isObject: true\n * });\n * ````\n *\n * # Textures\n *\n * ## Loading KTX2 Texture Files into a SceneModel\n *\n * A {@link SceneModel} that is configured with a {@link KTX2TextureTranscoder} will\n * allow us to load textures into it from KTX2 buffers or files.\n *\n * In the example below, we'll create a {@link Viewer}, containing a {@link SceneModel} configured with a\n * {@link KTX2TextureTranscoder}. We'll then programmatically create a simple object within the SceneModel, consisting of\n * a single mesh with a texture loaded from a KTX2 file, which our SceneModel internally transcodes, using\n * its {@link KTX2TextureTranscoder}. Note how we configure our {@link KTX2TextureTranscoder} with a path to the Basis Universal\n * transcoder WASM module.\n *\n * ````javascript\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * const textureTranscoder = new KTX2TextureTranscoder({\n *     viewer,\n *     transcoderPath: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\" // <------ Path to BasisU transcoder module\n * });\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n *      id: \"myModel\",\n *      textureTranscoder // <<-------------------- Configure model with our transcoder\n *  });\n *\n * sceneModel.createTexture({\n *      id: \"myColorTexture\",\n *      src: \"../assets/textures/compressed/sample_uastc_zstd.ktx2\" // <<----- KTX2 texture asset\n * });\n *\n * sceneModel.createTexture({\n *      id: \"myMetallicRoughnessTexture\",\n *      src: \"../assets/textures/alpha/crosshatchAlphaMap.jpg\" // <<----- JPEG texture asset\n * });\n *\n * sceneModel.createTextureSet({\n *      id: \"myTextureSet\",\n *      colorTextureId: \"myColorTexture\",\n *      metallicRoughnessTextureId: \"myMetallicRoughnessTexture\"\n *  });\n *\n * sceneModel.createMesh({\n *      id: \"myMesh\",\n *      textureSetId: \"myTextureSet\",\n *      primitive: \"triangles\",\n *      positions: [1, 1, 1, ...],\n *      normals: [0, 0, 1, 0, ...],\n *      uv: [1, 0, 0, ...],\n *      indices: [0, 1, 2, ...],\n *  });\n *\n * sceneModel.createEntity({\n *      id: \"myEntity\",\n *      meshIds: [\"myMesh\"]\n *  });\n *\n * sceneModel.finalize();\n * ````\n *\n * ## Loading KTX2 Textures from ArrayBuffers into a SceneModel\n *\n * A SceneModel that is configured with a {@link KTX2TextureTranscoder} will allow us to load textures into\n * it from KTX2 ArrayBuffers.\n *\n * In the example below, we'll create a {@link Viewer}, containing a {@link SceneModel} configured with a\n * {@link KTX2TextureTranscoder}. We'll then programmatically create a simple object within the SceneModel, consisting of\n * a single mesh with a texture loaded from a KTX2 ArrayBuffer, which our SceneModel internally transcodes, using\n * its {@link KTX2TextureTranscoder}.\n *\n * ````javascript\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-21.80, 4.01, 6.56];\n * viewer.scene.camera.look = [0, -5.75, 0];\n * viewer.scene.camera.up = [0.37, 0.91, -0.11];\n *\n * const textureTranscoder = new KTX2TextureTranscoder({\n *     viewer,\n *     transcoderPath: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\" // <------ Path to BasisU transcoder module\n * });\n *\n * const sceneModel = new SceneModel(viewer.scene, {\n *      id: \"myModel\",\n *      textureTranscoder // <<-------------------- Configure model with our transcoder\n * });\n *\n * utils.loadArraybuffer(\"../assets/textures/compressed/sample_uastc_zstd.ktx2\",(arrayBuffer) => {\n *\n *     sceneModel.createTexture({\n *         id: \"myColorTexture\",\n *         buffers: [arrayBuffer] // <<----- KTX2 texture asset\n *     });\n *\n *     sceneModel.createTexture({\n *         id: \"myMetallicRoughnessTexture\",\n *         src: \"../assets/textures/alpha/crosshatchAlphaMap.jpg\" // <<----- JPEG texture asset\n *     });\n *\n *     sceneModel.createTextureSet({\n *        id: \"myTextureSet\",\n *        colorTextureId: \"myColorTexture\",\n *        metallicRoughnessTextureId: \"myMetallicRoughnessTexture\"\n *     });\n *\n *     sceneModel.createMesh({\n *          id: \"myMesh\",\n *          textureSetId: \"myTextureSet\",\n *          primitive: \"triangles\",\n *          positions: [1, 1, 1, ...],\n *          normals: [0, 0, 1, 0, ...],\n *          uv: [1, 0, 0, ...],\n *          indices: [0, 1, 2, ...],\n *     });\n *\n *     sceneModel.createEntity({\n *         id: \"myEntity\",\n *         meshIds: [\"myMesh\"]\n *     });\n *\n *     sceneModel.finalize();\n * });\n * ````\n *\n * @implements {Entity}\n */\nclass SceneModel extends Component {\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent scene, generated automatically when omitted.\n     * @param {Boolean} [cfg.isModel] Specify ````true```` if this SceneModel represents a model, in which case the SceneModel will be registered by {@link SceneModel#id} in {@link Scene#models} and may also have a corresponding {@link MetaModel} with matching {@link MetaModel#id}, registered by that ID in {@link MetaScene#metaModels}.\n     * @param {Number[]} [cfg.origin=[0,0,0]] World-space double-precision 3D origin.\n     * @param {Number[]} [cfg.position=[0,0,0]] Local, single-precision 3D position, relative to the origin parameter.\n     * @param {Number[]} [cfg.scale=[1,1,1]] Local scale.\n     * @param {Number[]} [cfg.rotation=[0,0,0]] Local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] Local modelling transform matrix. Overrides the position, scale and rotation parameters.\n     * @param {Boolean} [cfg.visible=true] Indicates if the SceneModel is initially visible.\n     * @param {Boolean} [cfg.culled=false] Indicates if the SceneModel is initially culled from view.\n     * @param {Boolean} [cfg.pickable=true] Indicates if the SceneModel is initially pickable.\n     * @param {Boolean} [cfg.clippable=true] Indicates if the SceneModel is initially clippable.\n     * @param {Boolean} [cfg.collidable=true] Indicates if the SceneModel is initially included in boundary calculations.\n     * @param {Boolean} [cfg.xrayed=false] Indicates if the SceneModel is initially xrayed.\n     * @param {Boolean} [cfg.highlighted=false] Indicates if the SceneModel is initially highlighted.\n     * @param {Boolean} [cfg.selected=false] Indicates if the SceneModel is initially selected.\n     * @param {Boolean} [cfg.edges=false] Indicates if the SceneModel's edges are initially emphasized.\n     * @param {Number[]} [cfg.colorize=[1.0,1.0,1.0]] SceneModel's initial RGB colorize color, multiplies by the rendered fragment colors.\n     * @param {Number} [cfg.opacity=1.0] SceneModel's initial opacity factor, multiplies by the rendered fragment alpha.\n     * @param {Number} [cfg.backfaces=false] When we set this ````true````, then we force rendering of backfaces for this SceneModel. When\n     * we leave this ````false````, then we allow the Viewer to decide when to render backfaces. In that case, the\n     * Viewer will hide backfaces on watertight meshes, show backfaces on open meshes, and always show backfaces on meshes when we slice them open with {@link SectionPlane}s.\n     * @param {Boolean} [cfg.saoEnabled=true] Indicates if Scalable Ambient Obscurance (SAO) will apply to this SceneModel. SAO is configured by the Scene's {@link SAO} component.\n     * @param {Boolean} [cfg.pbrEnabled=true] Indicates if physically-based rendering (PBR) will apply to the SceneModel when {@link Scene#pbrEnabled} is ````true````.\n     * @param {Boolean} [cfg.colorTextureEnabled=true] Indicates if base color textures will be rendered for the SceneModel when {@link Scene#colorTextureEnabled} is ````true````.\n     * @param {Number} [cfg.edgeThreshold=10] When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n     * @param {Number} [cfg.maxGeometryBatchSize=50000000] Maximum geometry batch size, as number of vertices. This is optionally supplied\n     * to limit the size of the batched geometry arrays that SceneModel internally creates for batched geometries.\n     * A lower value means less heap allocation/de-allocation while creating/loading batched geometries, but more draw calls and\n     * slower rendering speed. A high value means larger heap allocation/de-allocation while creating/loading, but less draw calls\n     * and faster rendering speed. It's recommended to keep this somewhere roughly between ````50000```` and ````50000000```.\n     * @param {TextureTranscoder} [cfg.textureTranscoder] Transcoder that will be used internally by {@link SceneModel#createTexture}\n     * to convert transcoded texture data. Only required when we'll be providing transcoded data\n     * to {@link SceneModel#createTexture}. We assume that all transcoded texture data added to a  ````SceneModel````\n     * will then in a format supported by this transcoder.\n     * @param {Boolean} [cfg.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to\n     * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable\n     * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point\n     * primitives. Only works while {@link DTX#enabled} is also ````true````.\n     * @param {Number} [cfg.renderOrder=0] Specifies the rendering order for this SceneModel. This is used to control the order in which\n     * SceneModels are drawn when they have transparent objects, to give control over the order in which those objects are blended within the transparent\n     * render pass.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this.renderOrder = cfg.renderOrder || 0;\n\n        this._dtxEnabled = this.scene.dtxEnabled && (cfg.dtxEnabled !== false);\n\n        this._enableVertexWelding = false; // Not needed for most objects, and very expensive, so disabled\n        this._enableIndexBucketing = false; // Until fixed: https://github.com/xeokit/xeokit-sdk/issues/1204\n\n        this._textureTranscoder = cfg.textureTranscoder || getKTX2TextureTranscoder(this.scene.viewer);\n\n        this._maxGeometryBatchSize = cfg.maxGeometryBatchSize ?? 5000000;\n\n        this._aabb = math.collapseAABB3();\n        this._aabbDirty = true;\n\n        this._quantizationRanges = {};\n\n        this._vboLayers = {};\n        this._dtxLayers = {};\n\n        this._meshList = [];\n\n        this.layerList = []; // For GL state efficiency when drawing, InstancingLayers are in first part, BatchingLayers are in second\n        this._layersToFinalize = [];\n\n        this._entityList = [];\n        this._entitiesToFinalize = [];\n\n        this._geometries = {};\n        this._dtxBuckets = {}; // Geometries with optimizations used for data texture representation\n        this._textures = {};\n        this._textureSets = {};\n        this._transforms = {};\n        this._meshes = {};\n        this._unusedMeshes = {};\n        this._entities = {};\n\n        /** @private **/\n        this.renderFlags = new RenderFlags();\n\n        /**\n         * @private\n         */\n        this.numGeometries = 0; // Number of geometries created with createGeometry()\n\n        // These counts are used to avoid unnecessary render passes\n        // They are incremented or decremented exclusively by BatchingLayer and InstancingLayer\n\n        /**\n         * @private\n         */\n        this.numPortions = 0;\n\n        /**\n         * @private\n         */\n        this.numVisibleLayerPortions = 0;\n\n        /**\n         * @private\n         */\n        this.numTransparentLayerPortions = 0;\n\n        /**\n         * @private\n         */\n        this.numXRayedLayerPortions = 0;\n\n        /**\n         * @private\n         */\n        this.numHighlightedLayerPortions = 0;\n\n        /**\n         * @private\n         */\n        this.numSelectedLayerPortions = 0;\n\n        /**\n         * @private\n         */\n        this.numEdgesLayerPortions = 0;\n\n        /**\n         * @private\n         */\n        this.numPickableLayerPortions = 0;\n\n        /**\n         * @private\n         */\n        this.numClippableLayerPortions = 0;\n\n        /**\n         * @private\n         */\n        this.numCulledLayerPortions = 0;\n\n        this.numEntities = 0;\n        this._numTriangles = 0;\n        this._numLines = 0;\n        this._numPoints = 0;\n        this._layersFinalized = false;\n\n        this._edgeThreshold = cfg.edgeThreshold || 10;\n\n        // Build static matrix\n\n        this._origin = math.vec3(cfg.origin || [0, 0, 0]);\n        this._position = math.vec3(cfg.position || [0, 0, 0]);\n        this._rotation = math.vec3(cfg.rotation || [0, 0, 0]);\n        this._quaternion = math.vec4(cfg.quaternion || [0, 0, 0, 1]);\n        this._conjugateQuaternion = math.vec4(cfg.quaternion || [0, 0, 0, 1]);\n\n        if (cfg.rotation) {\n            math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\n        }\n        this._scale = math.vec3(cfg.scale || [1, 1, 1]);\n\n        this._worldRotationMatrix = math.mat4();\n        this._worldRotationMatrixConjugate = math.mat4();\n        this._matrix = math.mat4();\n        this._matrixDirty = true;\n\n        this._rebuildMatrices();\n\n        this._worldNormalMatrix = math.mat4();\n        math.inverseMat4(this._matrix, this._worldNormalMatrix);\n        math.transposeMat4(this._worldNormalMatrix);\n\n        if (cfg.matrix || cfg.position || cfg.rotation || cfg.scale || cfg.quaternion) {\n            this._viewMatrix = math.mat4();\n            this._viewNormalMatrix = math.mat4();\n            this._viewMatrixDirty = true;\n            this._matrixNonIdentity = true;\n        }\n\n        this._opacity = 1.0;\n        this._colorize = [1, 1, 1];\n\n        this._saoEnabled = (cfg.saoEnabled !== false);\n        this._pbrEnabled = (cfg.pbrEnabled !== false);\n        this._colorTextureEnabled = (cfg.colorTextureEnabled !== false);\n\n        this._isModel = cfg.isModel;\n        if (this._isModel) {\n            this.scene._registerModel(this);\n        }\n\n        this._onCameraViewMatrix = this.scene.camera.on(\"matrix\", () => {\n            this._viewMatrixDirty = true;\n        });\n\n        this._meshesWithDirtyMatrices = [];\n        this._numMeshesWithDirtyMatrices = 0;\n\n        this._onTick = this.scene.on(\"tick\", () => {\n            while (this._numMeshesWithDirtyMatrices > 0) {\n                this._meshesWithDirtyMatrices[--this._numMeshesWithDirtyMatrices]._updateMatrix();\n            }\n        });\n\n        // Every SceneModelMesh gets at least the default TextureSet,\n        // which contains empty default textures filled with color\n        const defineTex = (texId, preloadColor) => {\n            return this._textures[texId] = new SceneModelTexture({\n                id: texId,\n                texture: new Texture2D({\n                    gl: this.scene.canvas.gl,\n                    preloadColor: preloadColor\n                })\n            });\n        };\n\n        this._textureSets[DEFAULT_TEXTURE_SET_ID] = new SceneModelTextureSet({\n            id: DEFAULT_TEXTURE_SET_ID,\n            colorTexture:             defineTex(DEFAULT_COLOR_TEXTURE_ID,       [1, 1, 1, 1]), // [r, g, b, a]}),\n            metallicRoughnessTexture: defineTex(DEFAULT_METAL_ROUGH_TEXTURE_ID, [0, 1, 1, 1]), // [_, roughness, metalness, _],\n            normalsTexture:           defineTex(DEFAULT_NORMALS_TEXTURE_ID,     [0, 0, 0, 0]), // [x, y, z, _] - these must be zeros\n            emissiveTexture:          defineTex(DEFAULT_EMISSIVE_TEXTURE_ID,    [0, 0, 0, 1]), // [x, y, z, _]\n            occlusionTexture:         defineTex(DEFAULT_OCCLUSION_TEXTURE_ID,   [1, 1, 1, 1])  // [x, y, z, _]\n        });\n\n        this.visible = cfg.visible;\n        this.culled = cfg.culled;\n        this.pickable = cfg.pickable;\n        this.clippable = cfg.clippable;\n        this.collidable = cfg.collidable;\n        this.castsShadow = cfg.castsShadow;\n        this.receivesShadow = cfg.receivesShadow;\n        this.xrayed = cfg.xrayed;\n        this.highlighted = cfg.highlighted;\n        this.selected = cfg.selected;\n        this.edges = cfg.edges;\n        this.colorize = cfg.colorize;\n        this.opacity = cfg.opacity;\n        this.backfaces = cfg.backfaces;\n    }\n\n    _meshMatrixDirty(mesh) {\n        this._meshesWithDirtyMatrices[this._numMeshesWithDirtyMatrices++] = mesh;\n    }\n\n    //------------------------------------------------------------------------------------------------------------------\n    // SceneModel members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns true to indicate that this Component is a SceneModel.\n     * @type {Boolean}\n     */\n    get isPerformanceModel() {\n        return true;\n    }\n\n    /**\n     * The {@link SceneModelTransform}s in this SceneModel.\n     *\n     * Each {#link SceneModelTransform} is stored here against its {@link SceneModelTransform.id}.\n     *\n     * @returns {*|{}}\n     */\n    get transforms() {\n        return this._transforms;\n    }\n\n    /**\n     * The {@link SceneModelTexture}s in this SceneModel.\n     *\n     * * Each {@link SceneModelTexture} is created with {@link SceneModel.createTexture}.\n     * * Each {@link SceneModelTexture} is stored here against its {@link SceneModelTexture.id}.\n     *\n     * @returns {*|{}}\n     */\n    get textures() {\n        return this._textures;\n    }\n\n    /**\n     * The {@link SceneModelTextureSet}s in this SceneModel.\n     *\n     * Each {@link SceneModelTextureSet} is stored here against its {@link SceneModelTextureSet.id}.\n     *\n     * @returns {*|{}}\n     */\n    get textureSets() {\n        return this._textureSets;\n    }\n\n    /**\n     * The {@link SceneModelMesh}es in this SceneModel.\n     *\n     * Each {@SceneModelMesh} is stored here against its {@link SceneModelMesh.id}.\n     *\n     * @returns {*|{}}\n     */\n    get meshes() {\n        return this._meshes;\n    }\n\n    /**\n     * The {@link SceneModelEntity}s in this SceneModel.\n     *\n     * Each {#link SceneModelEntity} in this SceneModel that represents an object is\n     * stored here against its {@link SceneModelTransform.id}.\n     *\n     * @returns {*|{}}\n     */\n    get objects() {\n        return this._entities;\n    }\n\n    /**\n     * Gets the 3D World-space origin for this SceneModel.\n     *\n     * Each {@link SceneModelMesh.origin}, if supplied, is relative to this origin.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Float64Array}\n     */\n    get origin() {\n        return this._origin;\n    }\n\n    /**\n     * Sets the SceneModel's local translation.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    set position(value) {\n        this._position.set(value || [0, 0, 0]);\n        this._setWorldMatrixDirty();\n        this._sceneModelDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModel's local translation.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    get position() {\n        return this._position;\n    }\n\n    /**\n     * Sets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    set rotation(value) {\n        this._rotation.set(value || [0, 0, 0]);\n        math.eulerToQuaternion(this._rotation, \"XYZ\", this._quaternion);\n        this._setWorldMatrixDirty();\n        this._sceneModelDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @type {Number[]}\n     */\n    get rotation() {\n        return this._rotation;\n    }\n\n    /**\n     * Sets the SceneModel's local rotation quaternion.\n     *\n     * Default value is ````[0,0,0,1]````.\n     *\n     * @type {Number[]}\n     */\n    set quaternion(value) {\n        this._quaternion.set(value || [0, 0, 0, 1]);\n        math.quaternionToEuler(this._quaternion, \"XYZ\", this._rotation);\n        this._setWorldMatrixDirty();\n        this._sceneModelDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModel's local rotation quaternion.\n     *\n     * Default value is ````[0,0,0,1]````.\n     *\n     * @type {Number[]}\n     */\n    get quaternion() {\n        return this._quaternion;\n    }\n\n    /**\n     * Sets the SceneModel's local scale.\n     *\n     * Default value is ````[1,1,1]````.\n     *\n     * @type {Number[]}\n     * @deprecated\n     */\n    set scale(value) {\n        // NOP - deprecated\n    }\n\n    /**\n     * Gets the SceneModel's local scale.\n     *\n     * Default value is ````[1,1,1]````.\n     *\n     * @type {Number[]}\n     * @deprecated\n     */\n    get scale() {\n        return this._scale;\n    }\n\n    /**\n     * Sets the SceneModel's local modeling transform matrix.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @type {Number[]}\n     */\n    set matrix(value) {\n        this._matrix.set(value || DEFAULT_MATRIX);\n        math.decomposeMat4(this._matrix, this._position, this._quaternion, this._scale);\n        math.quaternionToEuler(this._quaternion, \"XYZ\", this._rotation);\n        this._matrixDirty = false;\n        this._setWorldMatrixDirty();\n        this._sceneModelDirty();\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the SceneModel's local modeling transform matrix.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @type {Number[]}\n     */\n    get matrix() {\n        this._rebuildMatrices();\n        return this._matrix;\n    }\n\n    /**\n     * Gets the SceneModel's local modeling rotation transform matrix.\n     *\n     * @type {Number[]}\n     */\n    get rotationMatrix() {\n        this._rebuildMatrices();\n        return this._worldRotationMatrix;\n    }\n\n    _rebuildMatrices() {\n        if (this._matrixDirty) {\n            math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrix);\n            math.conjugateQuaternion(this._quaternion, this._conjugateQuaternion);\n            math.quaternionToRotationMat4(this._conjugateQuaternion, this._worldRotationMatrixConjugate);\n            math.scaleMat4v(this._scale, this._worldRotationMatrix);\n            math.scaleMat4v(this._scale, this._worldRotationMatrixConjugate);\n            this._matrix.set(this._worldRotationMatrix);\n            math.translateMat4v(this._position, this._matrix);\n            this._matrixDirty = false;\n            this._viewMatrixDirty = true;\n        }\n    }\n\n    /**\n     * Gets the conjugate of the SceneModel's local modeling rotation transform matrix.\n     *\n     * This is used for RTC view matrix management in renderers.\n     *\n     * @type {Number[]}\n     */\n    get rotationMatrixConjugate() {\n        this._rebuildMatrices();\n        return this._worldRotationMatrixConjugate;\n    }\n\n    _setWorldMatrixDirty() {\n        this._matrixDirty = true;\n        this._aabbDirty = true;\n    }\n\n    _transformDirty() {\n        this._matrixDirty = true;\n        this._aabbDirty = true;\n        this.scene._aabbDirty = true;\n    }\n\n    _sceneModelDirty() {\n        this.scene._aabbDirty = true;\n        this._aabbDirty = true;\n        this.scene._aabbDirty = true;\n        this._matrixDirty = true;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i]._sceneModelDirty(); // Entities need to retransform their World AABBs by SceneModel's worldMatrix\n        }\n    }\n\n    /**\n     * Gets the SceneModel's World matrix.\n     *\n     * @property worldMatrix\n     * @type {Number[]}\n     */\n    get worldMatrix() {\n        return this.matrix;\n    }\n\n    /**\n     * Gets the SceneModel's World normal matrix.\n     *\n     * @type {Number[]}\n     */\n    get worldNormalMatrix() {\n        return this._worldNormalMatrix;\n    }\n\n    _rebuildViewMatrices() {\n        this._rebuildMatrices();\n        if (this._viewMatrixDirty) {\n            math.mulMat4(this.scene.camera.viewMatrix, this._matrix, this._viewMatrix);\n            math.inverseMat4(this._viewMatrix, this._viewNormalMatrix);\n            math.transposeMat4(this._viewNormalMatrix);\n            this._viewMatrixDirty = false;\n        }\n    }\n\n    /**\n     * Called by private renderers in ./lib, returns the view matrix with which to\n     * render this SceneModel. The view matrix is the concatenation of the\n     * Camera view matrix with the Performance model's world (modeling) matrix.\n     *\n     * @private\n     */\n    get viewMatrix() {\n        if (!this._viewMatrix) {\n            return this.scene.camera.viewMatrix;\n        }\n        this._rebuildViewMatrices();\n        return this._viewMatrix;\n    }\n\n    /**\n     * Called by private renderers in ./lib, returns the view normal matrix with which to render this SceneModel.\n     *\n     * @private\n     */\n    get viewNormalMatrix() {\n        if (!this._viewNormalMatrix) {\n            return this.scene.camera.viewNormalMatrix;\n        }\n        this._rebuildViewMatrices();\n        return this._viewNormalMatrix;\n    }\n\n    /**\n     * Sets if backfaces are rendered for this SceneModel.\n     *\n     * Default is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get backfaces() {\n        return this._backfaces;\n    }\n\n    /**\n     * Sets if backfaces are rendered for this SceneModel.\n     *\n     * Default is ````false````.\n     *\n     * When we set this ````true````, then backfaces are always rendered for this SceneModel.\n     *\n     * When we set this ````false````, then we allow the Viewer to decide whether to render backfaces. In this case,\n     * the Viewer will:\n     *\n     *  * hide backfaces on watertight meshes,\n     *  * show backfaces on open meshes, and\n     *  * always show backfaces on meshes when we slice them open with {@link SectionPlane}s.\n     *\n     * @type {Boolean}\n     */\n    set backfaces(backfaces) {\n        backfaces = !!backfaces;\n        this._backfaces = backfaces;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the list of {@link SceneModelEntity}s within this SceneModel.\n     *\n     * @returns {SceneModelEntity[]}\n     */\n    get entityList() {\n        return this._entityList;\n    }\n\n    /**\n     * Returns true to indicate that SceneModel is an {@link Entity}.\n     * @type {Boolean}\n     */\n    get isEntity() {\n        return true;\n    }\n\n    /**\n     * Returns ````true```` if this SceneModel represents a model.\n     *\n     * When ````true```` the SceneModel will be registered by {@link SceneModel#id} in\n     * {@link Scene#models} and may also have a {@link MetaObject} with matching {@link MetaObject#id}.\n     *\n     * @type {Boolean}\n     */\n    get isModel() {\n        return this._isModel;\n    }\n\n    //------------------------------------------------------------------------------------------------------------------\n    // SceneModel members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Returns ````false```` to indicate that SceneModel never represents an object.\n     *\n     * @type {Boolean}\n     */\n    get isObject() {\n        return false;\n    }\n\n    /**\n     * Gets the SceneModel's World-space 3D axis-aligned bounding box.\n     *\n     * Represented by a six-element Float64Array containing the min/max extents of the\n     * axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n     *\n     * @type {Number[]}\n     */\n    get aabb() {\n        if (this._aabbDirty) {\n            math.collapseAABB3(this._aabb);\n            for (let i = 0, len = this._entityList.length; i < len; i++) {\n                math.expandAABB3(this._aabb, this._entityList[i].aabb);\n            }\n            this._aabbDirty = false;\n        }\n        return this._aabb;\n    }\n\n    /**\n     * The approximate number of triangle primitives in this SceneModel.\n     *\n     * @type {Number}\n     */\n    get numTriangles() {\n        return this._numTriangles;\n    }\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Entity members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * The approximate number of line primitives in this SceneModel.\n     *\n     * @type {Number}\n     */\n    get numLines() {\n        return this._numLines;\n    }\n\n    /**\n     * The approximate number of point primitives in this SceneModel.\n     *\n     * @type {Number}\n     */\n    get numPoints() {\n        return this._numPoints;\n    }\n\n    /**\n     * Gets if any {@link SceneModelEntity}s in this SceneModel are visible.\n     *\n     * The SceneModel is only rendered when {@link SceneModel#visible} is ````true```` and {@link SceneModel#culled} is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get visible() {\n        return (this.numVisibleLayerPortions > 0);\n    }\n\n    /**\n     * Sets if this SceneModel is visible.\n     *\n     * The SceneModel is only rendered when {@link SceneModel#visible} is ````true```` and {@link SceneModel#culled} is ````false````.\n     **\n     * @type {Boolean}\n     */\n    set visible(visible) {\n        visible = visible !== false;\n        this._visible = visible;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].visible = visible;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if any {@link SceneModelEntity}s in this SceneModel are xrayed.\n     *\n     * @type {Boolean}\n     */\n    get xrayed() {\n        return (this.numXRayedLayerPortions > 0);\n    }\n\n    /**\n     * Sets if all {@link SceneModelEntity}s in this SceneModel are xrayed.\n     *\n     * @type {Boolean}\n     */\n    set xrayed(xrayed) {\n        xrayed = !!xrayed;\n        this._xrayed = xrayed;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].xrayed = xrayed;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if any {@link SceneModelEntity}s in this SceneModel are highlighted.\n     *\n     * @type {Boolean}\n     */\n    get highlighted() {\n        return (this.numHighlightedLayerPortions > 0);\n    }\n\n    /**\n     * Sets if all {@link SceneModelEntity}s in this SceneModel are highlighted.\n     *\n     * @type {Boolean}\n     */\n    set highlighted(highlighted) {\n        highlighted = !!highlighted;\n        this._highlighted = highlighted;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].highlighted = highlighted;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if any {@link SceneModelEntity}s in this SceneModel are selected.\n     *\n     * @type {Boolean}\n     */\n    get selected() {\n        return (this.numSelectedLayerPortions > 0);\n    }\n\n    /**\n     * Sets if all {@link SceneModelEntity}s in this SceneModel are selected.\n     *\n     * @type {Boolean}\n     */\n    set selected(selected) {\n        selected = !!selected;\n        this._selected = selected;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].selected = selected;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if any {@link SceneModelEntity}s in this SceneModel have edges emphasised.\n     *\n     * @type {Boolean}\n     */\n    get edges() {\n        return (this.numEdgesLayerPortions > 0);\n    }\n\n    /**\n     * Sets if all {@link SceneModelEntity}s in this SceneModel have edges emphasised.\n     *\n     * @type {Boolean}\n     */\n    set edges(edges) {\n        edges = !!edges;\n        this._edges = edges;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].edges = edges;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this SceneModel is culled from view.\n     *\n     * The SceneModel is only rendered when {@link SceneModel#visible} is true and {@link SceneModel#culled} is false.\n     *\n     * @type {Boolean}\n     */\n    get culled() {\n        return this._culled;\n    }\n\n    /**\n     * Sets if this SceneModel is culled from view.\n     *\n     * The SceneModel is only rendered when {@link SceneModel#visible} is true and {@link SceneModel#culled} is false.\n     *\n     * @type {Boolean}\n     */\n    set culled(culled) {\n        culled = !!culled;\n        this._culled = culled;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].culled = culled;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if {@link SceneModelEntity}s in this SceneModel are clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * @type {Boolean}\n     */\n    get clippable() {\n        return this._clippable;\n    }\n\n    /**\n     * Sets if {@link SceneModelEntity}s in this SceneModel are clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * @type {Boolean}\n     */\n    set clippable(clippable) {\n        clippable = clippable !== false;\n        this._clippable = clippable;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].clippable = clippable;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this SceneModel is collidable.\n     *\n     * @type {Boolean}\n     */\n    get collidable() {\n        return this._collidable;\n    }\n\n    /**\n     * Sets if {@link SceneModelEntity}s in this SceneModel are collidable.\n     *\n     * @type {Boolean}\n     */\n    set collidable(collidable) {\n        collidable = collidable !== false;\n        this._collidable = collidable;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].collidable = collidable;\n        }\n    }\n\n    /**\n     * Gets if this SceneModel is pickable.\n     *\n     * Picking is done via calls to {@link Scene#pick}.\n     *\n     * @type {Boolean}\n     */\n    get pickable() {\n        return (this.numPickableLayerPortions > 0);\n    }\n\n    /**\n     * Sets if {@link SceneModelEntity}s in this SceneModel are pickable.\n     *\n     * Picking is done via calls to {@link Scene#pick}.\n     *\n     * @type {Boolean}\n     */\n    set pickable(pickable) {\n        pickable = pickable !== false;\n        this._pickable = pickable;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].pickable = pickable;\n        }\n    }\n\n    /**\n     * Gets the RGB colorize color for this SceneModel.\n     *\n     * Each element of the color is in range ````[0..1]````.\n     *\n     * @type {Number[]}\n     */\n    get colorize() {\n        return this._colorize;\n    }\n\n    /**\n     * Sets the RGB colorize color for this SceneModel.\n     *\n     * Multiplies by rendered fragment colors.\n     *\n     * Each element of the color is in range ````[0..1]````.\n     *\n     * @type {Number[]}\n     */\n    set colorize(colorize) {\n        this._colorize = colorize;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].colorize = colorize;\n        }\n    }\n\n    /**\n     * Gets this SceneModel's opacity factor.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    get opacity() {\n        return this._opacity;\n    }\n\n    /**\n     * Sets the opacity factor for this SceneModel.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    set opacity(opacity) {\n        this._opacity = opacity;\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i].opacity = opacity;\n        }\n    }\n\n    /**\n     * Gets if this SceneModel casts a shadow.\n     *\n     * @type {Boolean}\n     */\n    get castsShadow() {\n        return this._castsShadow;\n    }\n\n    /**\n     * Sets if this SceneModel casts a shadow.\n     *\n     * @type {Boolean}\n     */\n    set castsShadow(castsShadow) {\n        castsShadow = (castsShadow !== false);\n        if (castsShadow !== this._castsShadow) {\n            this._castsShadow = castsShadow;\n            this.glRedraw();\n        }\n    }\n\n    /**\n     * Sets if this SceneModel can have shadow cast upon it.\n     *\n     * @type {Boolean}\n     */\n    get receivesShadow() {\n        return this._receivesShadow;\n    }\n\n    /**\n     * Sets if this SceneModel can have shadow cast upon it.\n     *\n     * @type {Boolean}\n     */\n    set receivesShadow(receivesShadow) {\n        receivesShadow = (receivesShadow !== false);\n        if (receivesShadow !== this._receivesShadow) {\n            this._receivesShadow = receivesShadow;\n            this.glRedraw();\n        }\n    }\n\n    /**\n     * Gets if Scalable Ambient Obscurance (SAO) will apply to this SceneModel.\n     *\n     * SAO is configured by the Scene's {@link SAO} component.\n     *\n     *  Only works when {@link SAO#enabled} is also true.\n     *\n     * @type {Boolean}\n     */\n    get saoEnabled() {\n        return this._saoEnabled;\n    }\n\n    /**\n     * Gets if physically-based rendering (PBR) is enabled for this SceneModel.\n     *\n     * Only works when {@link Scene#pbrEnabled} is also true.\n     *\n     * @type {Boolean}\n     */\n    get pbrEnabled() {\n        return this._pbrEnabled;\n    }\n\n    /**\n     * Gets if color textures are enabled for this SceneModel.\n     *\n     * Only works when {@link Scene#colorTextureEnabled} is also true.\n     *\n     * @type {Boolean}\n     */\n    get colorTextureEnabled() {\n        return this._colorTextureEnabled;\n    }\n\n    /**\n     * Returns true to indicate that SceneModel is implements {@link Drawable}.\n     *\n     * @type {Boolean}\n     */\n    get isDrawable() {\n        return true;\n    }\n\n    /** @private */\n    get isStateSortable() {\n        return false\n    }\n\n    /**\n     * Configures the appearance of xrayed {@link SceneModelEntity}s within this SceneModel.\n     *\n     * This is the {@link Scene#xrayMaterial}.\n     *\n     * @type {EmphasisMaterial}\n     */\n    get xrayMaterial() {\n        return this.scene.xrayMaterial;\n    }\n\n    /**\n     * Configures the appearance of highlighted {@link SceneModelEntity}s within this SceneModel.\n     *\n     * This is the {@link Scene#highlightMaterial}.\n     *\n     * @type {EmphasisMaterial}\n     */\n    get highlightMaterial() {\n        return this.scene.highlightMaterial;\n    }\n\n    /**\n     * Configures the appearance of selected {@link SceneModelEntity}s within this SceneModel.\n     *\n     * This is the {@link Scene#selectedMaterial}.\n     *\n     * @type {EmphasisMaterial}\n     */\n    get selectedMaterial() {\n        return this.scene.selectedMaterial;\n    }\n\n    /**\n     * Configures the appearance of edges of {@link SceneModelEntity}s within this SceneModel.\n     *\n     * This is the {@link Scene#edgeMaterial}.\n     *\n     * @type {EdgeMaterial}\n     */\n    get edgeMaterial() {\n        return this.scene.edgeMaterial;\n    }\n\n    //------------------------------------------------------------------------------------------------------------------\n    // Drawable members\n    //------------------------------------------------------------------------------------------------------------------\n\n    /**\n     * Called by private renderers in ./lib, returns the picking view matrix with which to\n     * ray-pick on this SceneModel.\n     *\n     * @private\n     */\n    getPickViewMatrix(pickViewMatrix) {\n        if (!this._viewMatrix) {\n            return pickViewMatrix;\n        }\n        return this._viewMatrix;\n    }\n\n    /**\n     *\n     * @param cfg\n     */\n    createQuantizationRange(cfg) {\n        if (cfg.id === undefined || cfg.id === null) {\n            this.error(\"[createQuantizationRange] Config missing: id\");\n            return;\n        }\n        if (cfg.aabb) {\n            this.error(\"[createQuantizationRange] Config missing: aabb\");\n            return;\n        }\n        if (this._quantizationRanges[cfg.id]) {\n            this.error(\"[createQuantizationRange] QuantizationRange already created: \" + cfg.id);\n            return;\n        }\n        this._quantizationRanges[cfg.id] = {\n            id: cfg.id,\n            aabb: cfg.aabb,\n            matrix: createPositionsDecodeMatrix(cfg.aabb, math.mat4())\n        };\n    }\n\n    _createDefaultIndices(numIndices) {\n        const indices = [];\n        for (let i = 0; i < numIndices; i++) {\n            indices.push(i);\n        }\n        return indices;\n    }\n\n    /**\n     * Creates a reusable geometry within this SceneModel.\n     *\n     * We can then supply the geometry ID to {@link SceneModel#createMesh} when we want to create meshes that\n     * instance the geometry.\n     *\n     * @param {*} cfg Geometry properties.\n     * @param {String|Number} cfg.id Mandatory ID for the geometry, to refer to with {@link SceneModel#createMesh}.\n     * @param {String} cfg.primitive The primitive type. Accepted values are 'points', 'lines', 'triangles', 'solid' and 'surface'.\n     * @param {Number[]} [cfg.positions] Flat array of uncompressed 3D vertex positions positions. Required for all primitive types. Overridden by ````positionsCompressed````.\n     * @param {Number[]} [cfg.positionsCompressed] Flat array of quantized 3D vertex positions. Overrides ````positions````, and must be accompanied by ````positionsDecodeMatrix````.\n     * @param {Number[]} [cfg.positionsDecodeMatrix] A 4x4 matrix for decompressing ````positionsCompressed````. Must be accompanied by ````positionsCompressed````.\n     * @param {Number[]} [cfg.normals] Flat array of normal vectors. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n     * @param {Number[]} [cfg.normalsCompressed] Flat array of oct-encoded normal vectors. Overrides ````normals````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n     * @param {Number[]} [cfg.colors] Flat array of uncompressed RGBA vertex colors, as float values in range ````[0..1]````. Ignored when ````geometryId```` is given. Overridden by ````color```` and ````colorsCompressed````.\n     * @param {Number[]} [cfg.colorsCompressed] Flat array of compressed RGBA vertex colors, as unsigned short integers in range ````[0..255]````. Ignored when ````geometryId```` is given. Overrides ````colors```` and is overridden by ````color````.\n     * @param {Number[]} [cfg.uv] Flat array of uncompressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n     * @param {Number[]} [cfg.uvCompressed] Flat array of compressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Overrides ````uv````. Must be accompanied by ````uvDecodeMatrix````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n     * @param {Number[]} [cfg.uvDecodeMatrix] A 3x3 matrix for decompressing ````uvCompressed````.\n     * @param {Number[]} [cfg.indices] Array of primitive connectivity indices. Not required for `points` primitives.\n     * @param {Number[]} [cfg.edgeIndices] Array of edge line indices. Used only with 'triangles', 'solid' and 'surface' primitives. Automatically generated internally if not supplied, using the optional ````edgeThreshold```` given to the ````SceneModel```` constructor.\n     */\n    createGeometry(cfg) {\n        if (cfg.id === undefined || cfg.id === null) {\n            this.error(\"[createGeometry] Config missing: id\");\n            return;\n        }\n        if (this._geometries[cfg.id]) {\n            this.error(\"[createGeometry] Geometry already created: \" + cfg.id);\n            return;\n        }\n        if (cfg.primitive === undefined || cfg.primitive === null) {\n            cfg.primitive = \"triangles\";\n        }\n        if (cfg.primitive !== \"points\" && cfg.primitive !== \"lines\" && cfg.primitive !== \"triangles\" && cfg.primitive !== \"solid\" && cfg.primitive !== \"surface\") {\n            this.error(`[createGeometry] Unsupported value for 'primitive': '${cfg.primitive}' - supported values are 'points', 'lines', 'triangles', 'solid' and 'surface'. Defaulting to 'triangles'.`);\n            return;\n        }\n        if (!cfg.positions && !cfg.positionsCompressed && !cfg.buckets) {\n            this.error(\"[createGeometry] Param expected: `positions`,  `positionsCompressed' or 'buckets\");\n            return null;\n        }\n        if (cfg.positionsCompressed && !cfg.positionsDecodeMatrix && !cfg.positionsDecodeBoundary) {\n            this.error(\"[createGeometry] Param expected: `positionsDecodeMatrix` or 'positionsDecodeBoundary' (required for `positionsCompressed')\");\n            return null;\n        }\n        if (cfg.positionsDecodeMatrix && cfg.positionsDecodeBoundary) {\n            this.error(\"[createGeometry] Only one of these params expected: `positionsDecodeMatrix` or 'positionsDecodeBoundary' (required for `positionsCompressed')\");\n            return null;\n        }\n        if (cfg.uvCompressed && !cfg.uvDecodeMatrix) {\n            this.error(\"[createGeometry] Param expected: `uvDecodeMatrix` (required for `uvCompressed')\");\n            return null;\n        }\n        if (!cfg.buckets && !cfg.indices && (cfg.primitive === \"triangles\" || cfg.primitive === \"solid\" || cfg.primitive === \"surface\")) {\n            cfg.indices = this._createDefaultIndices((cfg.positions || cfg.positionsCompressed).length / 3);\n        }\n        if (!cfg.buckets && !cfg.indices && cfg.primitive !== \"points\") {\n            this.error(`[createGeometry] Param expected: indices (required for '${cfg.primitive}' primitive type)`);\n            return null;\n        }\n        if (cfg.positionsDecodeBoundary) {\n            cfg.positionsDecodeMatrix = createPositionsDecodeMatrix(cfg.positionsDecodeBoundary, math.mat4());\n        }\n        if (cfg.positions) {\n            const aabb = math.collapseAABB3();\n            cfg.positionsDecodeMatrix = math.mat4();\n            math.expandAABB3Points3(aabb, cfg.positions);\n            cfg.positionsCompressed = quantizePositions(cfg.positions, aabb, cfg.positionsDecodeMatrix);\n            cfg.aabb = aabb;\n        } else if (cfg.positionsCompressed) {\n            const aabb = math.collapseAABB3();\n            cfg.positionsDecodeMatrix = new Float64Array(cfg.positionsDecodeMatrix);\n            cfg.positionsCompressed = new Uint16Array(cfg.positionsCompressed);\n            math.expandAABB3Points3(aabb, cfg.positionsCompressed);\n            geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n            cfg.aabb = aabb;\n        } else if (cfg.buckets) {\n            const aabb = math.collapseAABB3();\n            this._dtxBuckets[cfg.id] = cfg.buckets;\n            for (let i = 0, len = cfg.buckets.length; i < len; i++) {\n                const bucket = cfg.buckets[i];\n                if (bucket.positions) {\n                    math.expandAABB3Points3(aabb, bucket.positions);\n                } else if (bucket.positionsCompressed) {\n                    math.expandAABB3Points3(aabb, bucket.positionsCompressed);\n                }\n            }\n            if (cfg.positionsDecodeMatrix) {\n                geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n            }\n            cfg.aabb = aabb;\n        }\n        if (cfg.colorsCompressed && cfg.colorsCompressed.length > 0) {\n            cfg.colorsCompressed = new Uint8Array(cfg.colorsCompressed);\n        } else if (cfg.colors && cfg.colors.length > 0) {\n            const colors = cfg.colors;\n            const colorsCompressed = new Uint8Array(colors.length);\n            for (let i = 0, len = colors.length; i < len; i++) {\n                colorsCompressed[i] = colors[i] * 255;\n            }\n            cfg.colorsCompressed = colorsCompressed;\n        }\n        if (!cfg.buckets && !cfg.edgeIndices && (cfg.primitive === \"triangles\" || cfg.primitive === \"solid\" || cfg.primitive === \"surface\")) {\n            if (cfg.positions) {\n                cfg.edgeIndices = buildEdgeIndices(cfg.positions, cfg.indices, null, 5.0);\n            } else {\n                cfg.edgeIndices = buildEdgeIndices(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);\n            }\n        }\n        if (cfg.uv) {\n            const bounds = geometryCompressionUtils.getUVBounds(cfg.uv);\n            const result = geometryCompressionUtils.compressUVs(cfg.uv, bounds.min, bounds.max);\n            cfg.uvCompressed = result.quantized;\n            cfg.uvDecodeMatrix = result.decodeMatrix;\n        } else if (cfg.uvCompressed) {\n            cfg.uvCompressed = new Uint16Array(cfg.uvCompressed);\n            cfg.uvDecodeMatrix = new Float64Array(cfg.uvDecodeMatrix);\n        }\n        if (cfg.normals) { // HACK\n            cfg.normals = null;\n        }\n        this._geometries [cfg.id] = cfg;\n        this._numTriangles += (cfg.indices ? Math.round(cfg.indices.length / 3) : 0);\n        this.numGeometries++;\n    }\n\n    /**\n     * Creates a texture within this SceneModel.\n     *\n     * We can then supply the texture ID to {@link SceneModel#createTextureSet} when we want to create texture sets that use the texture.\n     *\n     * @param {*} cfg Texture properties.\n     * @param {String|Number} cfg.id Mandatory ID for the texture, to refer to with {@link SceneModel#createTextureSet}.\n     * @param {String} [cfg.src] Image file for the texture. Assumed to be transcoded if not having a recognized image file\n     * extension (jpg, jpeg, png etc.). If transcoded, then assumes ````SceneModel```` is configured with a {@link TextureTranscoder}.\n     * @param {ArrayBuffer[]} [cfg.buffers] Transcoded texture data. Assumes ````SceneModel```` is\n     * configured with a {@link TextureTranscoder}. This parameter is given as an array of buffers so we can potentially support multi-image textures, such as cube maps.\n     * @param {HTMLImageElement} [cfg.image] HTML Image object to load into this texture. Overrides ````src```` and ````buffers````. Never transcoded.\n     * @param {Number} [cfg.minFilter=LinearMipmapLinearFilter] How the texture is sampled when a texel covers less than one pixel.\n     * Supported values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}.\n     * @param {Number} [cfg.magFilter=LinearFilter] How the texture is sampled when a texel covers more than one pixel. Supported values are {@link LinearFilter} and {@link NearestFilter}.\n     * @param {Number} [cfg.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n     * @param {Number} [cfg.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}..\n     * @param {Number} [cfg.wrapR=RepeatWrapping] Wrap parameter for texture coordinate *R*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.\n     * @param {Boolean} [cfg.flipY=false] Flips this Texture's source data along its vertical axis when ````true````.\n     * @param  {Number} [cfg.encoding=LinearEncoding] Encoding format. Supported values are {@link LinearEncoding} and {@link sRGBEncoding}.\n     */\n    createTexture(cfg) {\n        const textureId = cfg.id;\n        if (textureId === undefined || textureId === null) {\n            this.error(\"[createTexture] Config missing: id\");\n            return;\n        }\n        if (this._textures[textureId]) {\n            this.error(\"[createTexture] Texture already created: \" + textureId);\n            return;\n        }\n        if (!cfg.src && !cfg.image && !cfg.buffers) {\n            this.error(\"[createTexture] Param expected: `src`, `image' or 'buffers'\");\n            return null;\n        }\n        let minFilter = cfg.minFilter || LinearMipmapLinearFilter;\n        if (minFilter !== LinearFilter &&\n            minFilter !== LinearMipMapNearestFilter &&\n            minFilter !== LinearMipmapLinearFilter &&\n            minFilter !== NearestMipMapLinearFilter &&\n            minFilter !== NearestMipMapNearestFilter) {\n            this.error(`[createTexture] Unsupported value for 'minFilter' - \n            supported values are LinearFilter, LinearMipMapNearestFilter, NearestMipMapNearestFilter, \n            NearestMipMapLinearFilter and LinearMipmapLinearFilter. Defaulting to LinearMipmapLinearFilter.`);\n            minFilter = LinearMipmapLinearFilter;\n        }\n        let magFilter = cfg.magFilter || LinearFilter;\n        if (magFilter !== LinearFilter && magFilter !== NearestFilter) {\n            this.error(`[createTexture] Unsupported value for 'magFilter' - supported values are LinearFilter and NearestFilter. Defaulting to LinearFilter.`);\n            magFilter = LinearFilter;\n        }\n        let wrapS = cfg.wrapS || RepeatWrapping;\n        if (wrapS !== ClampToEdgeWrapping && wrapS !== MirroredRepeatWrapping && wrapS !== RepeatWrapping) {\n            this.error(`[createTexture] Unsupported value for 'wrapS' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`);\n            wrapS = RepeatWrapping;\n        }\n        let wrapT = cfg.wrapT || RepeatWrapping;\n        if (wrapT !== ClampToEdgeWrapping && wrapT !== MirroredRepeatWrapping && wrapT !== RepeatWrapping) {\n            this.error(`[createTexture] Unsupported value for 'wrapT' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`);\n            wrapT = RepeatWrapping;\n        }\n        let wrapR = cfg.wrapR || RepeatWrapping;\n        if (wrapR !== ClampToEdgeWrapping && wrapR !== MirroredRepeatWrapping && wrapR !== RepeatWrapping) {\n            this.error(`[createTexture] Unsupported value for 'wrapR' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`);\n            wrapR = RepeatWrapping;\n        }\n        let encoding = cfg.encoding || LinearEncoding;\n        if (encoding !== LinearEncoding && encoding !== sRGBEncoding) {\n            this.error(\"[createTexture] Unsupported value for 'encoding' - supported values are LinearEncoding and sRGBEncoding. Defaulting to LinearEncoding.\");\n            encoding = LinearEncoding;\n        }\n        const texture = new Texture2D({\n            gl: this.scene.canvas.gl,\n            minFilter,\n            magFilter,\n            wrapS,\n            wrapT,\n            wrapR,\n            // flipY: cfg.flipY,\n            encoding\n        });\n        if (cfg.preloadColor) {\n            texture.setPreloadColor(cfg.preloadColor);\n        }\n        if (cfg.image) { // Ignore transcoder for Images\n            const image = cfg.image;\n            image.crossOrigin = \"Anonymous\";\n            if (image.compressed) {\n                // see `parsedImage` in @loaders.gl/gltf/src/lib/parsers/parse-gltf.ts\n                // NOTE: @loaders.gl in its current version discards potential mipmaps, leaving only a single one\n                const data = image.data;\n                texture.setCompressedData({\n                    mipmaps: data,\n                    props: {\n                        format: data[0].format,\n                        minFilter: minFilter,\n                        magFilter: magFilter\n                    }\n                });\n            } else {\n                texture.setImage(image, {minFilter, magFilter, wrapS, wrapT, wrapR, flipY: cfg.flipY, encoding});\n            }\n        } else if (cfg.src) {\n            const ext = cfg.src.split('.').pop();\n            switch (ext) { // Don't transcode recognized image file types\n                case \"jpeg\":\n                case \"jpg\":\n                case \"png\":\n                case \"gif\":\n                    const image = new Image();\n                    image.onload = () => {\n                        texture.setImage(image, {\n                            minFilter,\n                            magFilter,\n                            wrapS,\n                            wrapT,\n                            wrapR,\n                            flipY: cfg.flipY,\n                            encoding\n                        });\n                        this.glRedraw();\n                    };\n                    image.src = cfg.src; // URL or Base64 string\n                    break;\n                default: // Assume other file types need transcoding\n                    if (!this._textureTranscoder) {\n                        this.error(`[createTexture] Can't create texture from 'src' - SceneModel needs to be configured with a TextureTranscoder for this file type ('${ext}')`);\n                    } else {\n                        utils.loadArraybuffer(cfg.src, (arrayBuffer) => {\n                                if (!arrayBuffer.byteLength) {\n                                    this.error(`[createTexture] Can't create texture from 'src': file data is zero length`);\n                                    return;\n                                }\n                                this._textureTranscoder.transcode([arrayBuffer], texture).then(() => {\n                                    this.glRedraw();\n                                });\n                            },\n                            function (errMsg) {\n                                this.error(`[createTexture] Can't create texture from 'src': ${errMsg}`);\n                            });\n                    }\n                    break;\n            }\n        } else if (cfg.buffers) { // Buffers implicitly require transcoding\n            if (!this._textureTranscoder) {\n                this.error(`[createTexture] Can't create texture from 'buffers' - SceneModel needs to be configured with a TextureTranscoder for this option`);\n            } else {\n                this._textureTranscoder.transcode(cfg.buffers, texture).then(() => {\n                    this.glRedraw();\n                });\n            }\n        }\n        this._textures[textureId] = new SceneModelTexture({id: textureId, texture});\n    }\n\n    /**\n     * Creates a texture set within this SceneModel.\n     *\n     * * Stores the new {@link SceneModelTextureSet} in {@link SceneModel#textureSets}.\n     *\n     * A texture set is a collection of textures that can be shared among meshes. We can then supply the texture set\n     * ID to {@link SceneModel#createMesh} when we want to create meshes that use the texture set.\n     *\n     * The textures can work as a texture atlas, where each mesh can have geometry UVs that index\n     * a different part of the textures. This allows us to minimize the number of textures in our models, which\n     * means faster rendering.\n     *\n     * @param {*} cfg Texture set properties.\n     * @param {String|Number} cfg.id Mandatory ID for the texture set, to refer to with {@link SceneModel#createMesh}.\n     * @param {*} [cfg.colorTextureId] ID of *RGBA* base color texture, with color in *RGB* and alpha in *A*.\n     * @param {*} [cfg.metallicRoughnessTextureId] ID of *RGBA* metal-roughness texture, with the metallic factor in *R*, and roughness factor in *G*.\n     * @param {*} [cfg.normalsTextureId] ID of *RGBA* normal map texture, with normal map vectors in *RGB*.\n     * @param {*} [cfg.emissiveTextureId] ID of *RGBA* emissive map texture, with emissive color in *RGB*.\n     * @param {*} [cfg.occlusionTextureId] ID of *RGBA* occlusion map texture, with occlusion factor in *R*.\n     * @returns {SceneModelTransform} The new texture set.\n     */\n    createTextureSet(cfg) {\n        const textureSetId = cfg.id;\n        if (textureSetId === undefined || textureSetId === null) {\n            this.error(\"[createTextureSet] Config missing: id\");\n            return false;\n        }\n        if (this._textureSets[textureSetId]) {\n            this.error(`[createTextureSet] Texture set already created: ${textureSetId}`);\n            return false;\n        }\n\n        const getTexture = (cfgId, defaultKey) => {\n            const id = cfgId ?? defaultKey;\n            if (id in this._textures) {\n                return this._textures[id];\n            } else {\n                throw cfgId;\n            }\n        };\n\n        try {\n            const textureSet = new SceneModelTextureSet({\n                id: textureSetId,\n                model: this,\n                alphaCutoff: cfg.alphaCutoff,\n                colorTexture:             getTexture(cfg.colorTextureId,             DEFAULT_COLOR_TEXTURE_ID),\n                metallicRoughnessTexture: getTexture(cfg.metallicRoughnessTextureId, DEFAULT_METAL_ROUGH_TEXTURE_ID),\n                normalsTexture:           getTexture(cfg.normalsTextureId,           DEFAULT_NORMALS_TEXTURE_ID),\n                emissiveTexture:          getTexture(cfg.emissiveTextureId,          DEFAULT_EMISSIVE_TEXTURE_ID),\n                occlusionTexture:         getTexture(cfg.occlusionTextureId,         DEFAULT_OCCLUSION_TEXTURE_ID)\n            });\n            this._textureSets[textureSetId] = textureSet;\n            return textureSet;\n        } catch (id) {\n            this.error(`[createTextureSet] Texture not found: ${id} - ensure that you create it first with createTexture()`);\n            return false;\n        }\n    }\n\n    /**\n     * Creates a new {@link SceneModelTransform} within this SceneModel.\n     *\n     * * Stores the new {@link SceneModelTransform} in {@link SceneModel#transforms}.\n     * * Can be connected into hierarchies\n     * * Each {@link SceneModelTransform} can be used by unlimited {@link SceneModelMesh}es\n     *\n     * @param {*} cfg Transform creation parameters.\n     * @param {String} cfg.id Mandatory ID for the new transform. Must not clash with any existing components within the {@link Scene}.\n     * @param {String} [cfg.parentTransformId] ID of a parent transform, previously created with {@link SceneModel#createTextureSet}.\n     * @param {Number[]} [cfg.position=[0,0,0]] Local 3D position of the mesh. Overridden by ````transformId````.\n     * @param {Number[]} [cfg.scale=[1,1,1]] Scale of the transform.\n     * @param {Number[]} [cfg.rotation=[0,0,0]] Rotation of the transform as Euler angles given in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Modelling transform matrix. Overrides the ````position````, ````scale```` and ````rotation```` parameters.\n     * @returns {SceneModelTransform} The new transform.\n     */\n    createTransform(cfg) {\n        if (cfg.id === undefined || cfg.id === null) {\n            this.error(\"[createTransform] SceneModel.createTransform() config missing: id\");\n            return;\n        }\n        if (this._transforms[cfg.id]) {\n            this.error(`[createTransform] SceneModel already has a transform with this ID: ${cfg.id}`);\n            return;\n        }\n        let parentTransform;\n        if (cfg.parentTransformId) {\n            parentTransform = this._transforms[cfg.parentTransformId];\n            if (!parentTransform) {\n                this.error(\"[createTransform] SceneModel.createTransform() config missing: id\");\n                return;\n            }\n        }\n        const transform = new SceneModelTransform({\n            id: cfg.id,\n            model: this,\n            parent: parentTransform,\n            matrix: cfg.matrix,\n            position: cfg.position,\n            scale: cfg.scale,\n            rotation: cfg.rotation,\n            quaternion: cfg.quaternion\n        });\n        this._transforms[transform.id] = transform;\n        return transform;\n    }\n\n    /**\n     * Creates a new {@link SceneModelMesh} within this SceneModel.\n     *\n     * * It prepares and saves data for a SceneModelMesh {@link SceneModel#meshes} creation. SceneModelMesh will be created only once the SceneModelEntity (which references this particular SceneModelMesh) will be created.\n     * * The SceneModelMesh can either define its own geometry or share it with other SceneModelMeshes. To define own geometry, provide the\n     * various geometry arrays to this method. To share a geometry, provide the ID of a geometry created earlier\n     * with {@link SceneModel#createGeometry}.\n     * * If you accompany the arrays with an  ````origin````, then ````createMesh()```` will assume\n     * that the geometry ````positions```` are in relative-to-center (RTC) coordinates, with ````origin```` being the\n     * origin of their RTC coordinate system.\n     *\n     * @param {object} cfg Object properties.\n     * @param {String} cfg.id Mandatory ID for the new mesh. Must not clash with any existing components within the {@link Scene}.\n     * @param {String|Number} [cfg.textureSetId] ID of a {@link SceneModelTextureSet} previously created with {@link SceneModel#createTextureSet}.\n     * @param {String|Number} [cfg.transformId] ID of a {@link SceneModelTransform} to instance, previously created with {@link SceneModel#createTransform}. Overrides all other transform parameters given to this method.\n     * @param {String|Number} [cfg.geometryId] ID of a geometry to instance, previously created with {@link SceneModel#createGeometry}. Overrides all other geometry parameters given to this method.\n     * @param {String} cfg.primitive The primitive type. Accepted values are 'points', 'lines', 'triangles', 'solid' and 'surface'.\n     * @param {Number[]} [cfg.positions] Flat array of uncompressed 3D vertex positions positions. Required for all primitive types. Overridden by ````positionsCompressed````.\n     * @param {Number[]} [cfg.positionsCompressed] Flat array of quantized 3D vertex positions. Overrides ````positions````, and must be accompanied by ````positionsDecodeMatrix````.\n     * @param {Number[]} [cfg.positionsDecodeMatrix] A 4x4 matrix for decompressing ````positionsCompressed````. Must be accompanied by ````positionsCompressed````.\n     * @param {Number[]} [cfg.normals] Flat array of normal vectors. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n     * @param {Number[]} [cfg.normalsCompressed] Flat array of oct-encoded normal vectors. Overrides ````normals````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.\n     * @param {Number[]} [cfg.colors] Flat array of uncompressed RGBA vertex colors, as float values in range ````[0..1]````. Ignored when ````geometryId```` is given. Overridden by ````color```` and ````colorsCompressed````.\n     * @param {Number[]} [cfg.colorsCompressed] Flat array of compressed RGBA vertex colors, as unsigned short integers in range ````[0..255]````. Ignored when ````geometryId```` is given. Overrides ````colors```` and is overridden by ````color````.\n     * @param {Number[]} [cfg.uv] Flat array of uncompressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n     * @param {Number[]} [cfg.uvCompressed] Flat array of compressed vertex UV coordinates. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Overrides ````uv````. Must be accompanied by ````uvDecodeMatrix````. Only used with \"triangles\", \"solid\" and \"surface\" primitives. Required for textured rendering.\n     * @param {Number[]} [cfg.uvDecodeMatrix] A 3x3 matrix for decompressing ````uvCompressed````.\n     * @param {Number[]} [cfg.indices] Array of primitive connectivity indices. Not required for `points` primitives.\n     * @param {Number[]} [cfg.edgeIndices] Array of edge line indices. Used only with 'triangles', 'solid' and 'surface' primitives. Automatically generated internally if not supplied, using the optional ````edgeThreshold```` given to the ````SceneModel```` constructor.\n     * @param {Number[]} [cfg.origin] Optional geometry origin, relative to {@link SceneModel#origin}. When this is given, then ````positions```` are assumed to be relative to this.\n     * @param {Number[]} [cfg.position=[0,0,0]] Local 3D position of the mesh. Overridden by ````transformId````.\n     * @param {Number[]} [cfg.scale=[1,1,1]] Scale of the mesh.  Overridden by ````transformId````.\n     * @param {Number[]} [cfg.rotation=[0,0,0]] Rotation of the mesh as Euler angles given in degrees, for each of the X, Y and Z axis.  Overridden by ````transformId````.\n     * @param {Number[]} [cfg.quaternion] Rotation of the mesh as a quaternion.  Overridden by ````rotation````.\n     * @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Mesh modelling transform matrix. Overrides the ````position````, ````scale```` and ````rotation```` parameters. Also  overridden by ````transformId````.\n     * @param {Number[]} [cfg.color=[1,1,1]] RGB color in range ````[0..1, 0..1, 0..1]````. Overridden by texture set ````colorTexture````. Overrides ````colors```` and ````colorsCompressed````.\n     * @param {Number} [cfg.opacity=1] Opacity in range ````[0..1]````. Overridden by texture set ````colorTexture````.\n     * @param {Number} [cfg.metallic=0] Metallic factor in range ````[0..1]````. Overridden by texture set ````metallicRoughnessTexture````.\n     * @param {Number} [cfg.roughness=1] Roughness factor in range ````[0..1]````. Overridden by texture set ````metallicRoughnessTexture````.\n     * @returns {SceneModelMesh} The new mesh.\n     */\n    createMesh(cfg) {\n\n        if (cfg.id === undefined || cfg.id === null) {\n            this.error(\"[createMesh] SceneModel.createMesh() config missing: id\");\n            return false;\n        }\n\n        if (this._meshes[cfg.id]) {\n            this.error(`[createMesh] SceneModel already has a mesh with this ID: ${cfg.id}`);\n            return false;\n        }\n\n        const geometryId = cfg.geometryId;\n        const instancing = geometryId !== undefined;\n\n        if (instancing) {\n            if (cfg.positions || cfg.positionsCompressed || cfg.indices || cfg.edgeIndices || cfg.normals || cfg.normalsCompressed || cfg.uv || cfg.uvCompressed || cfg.positionsDecodeMatrix) {\n                this.error(`Mesh geometry parameters not expected when instancing a geometry (not expected: positions, positionsCompressed, indices, edgeIndices, normals, normalsCompressed, uv, uvCompressed, positionsDecodeMatrix)`);\n                return false;\n            }\n\n            cfg.geometry = this._geometries[geometryId];\n            if (!cfg.geometry) {\n                this.error(`[createMesh] Geometry not found: ${geometryId} - ensure that you create it first with createGeometry()`);\n                return false;\n            }\n        } else {\n            cfg.primitive ??= \"triangles\";\n        }\n\n        const primitive = instancing ? cfg.geometry.primitive : cfg.primitive;\n        const isTriangular = (primitive === \"triangles\") || (primitive === \"solid\") || (primitive === \"surface\");\n        const textureSetId = cfg.textureSetId;\n        const useDTX = this._dtxEnabled && isTriangular && (! textureSetId);\n\n        cfg.origin = cfg.origin ? math.addVec3(this._origin, cfg.origin, math.vec3()) : this._origin;\n\n        if (! instancing) {\n\n            // Batched geometry\n\n            if (primitive !== \"points\" && primitive !== \"lines\" && primitive !== \"triangles\" && primitive !== \"solid\" && primitive !== \"surface\") {\n                this.error(`Unsupported value for 'primitive': '${primitive}'  ('geometryId' is absent) - supported values are 'points', 'lines', 'triangles', 'solid' and 'surface'.`);\n                return false;\n            }\n            if (!cfg.positions && !cfg.positionsCompressed && !cfg.buckets) {\n                this.error(\"Param expected: 'positions',  'positionsCompressed' or `buckets`  ('geometryId' is absent)\");\n                return false;\n            }\n            if (cfg.positions && (cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary)) {\n                this.error(\"Illegal params: 'positions' not expected with 'positionsDecodeMatrix'/'positionsDecodeBoundary' ('geometryId' is absent)\");\n                return false;\n            }\n            if (cfg.positionsCompressed && !cfg.positionsDecodeMatrix && !cfg.positionsDecodeBoundary) {\n                this.error(\"Param expected: 'positionsCompressed' should be accompanied by 'positionsDecodeMatrix'/'positionsDecodeBoundary' ('geometryId' is absent)\");\n                return false;\n            }\n            if (cfg.uvCompressed && !cfg.uvDecodeMatrix) {\n                this.error(\"Param expected: 'uvCompressed' should be accompanied by `uvDecodeMatrix` ('geometryId' is absent)\");\n                return false;\n            }\n            if (!cfg.buckets && !cfg.indices) {\n                if (isTriangular) {\n                    cfg.indices = this._createDefaultIndices((cfg.positions || cfg.positionsCompressed).length / 3);\n                } else if (primitive === \"lines\") {\n                    this.error(`Param expected: indices (required for '${primitive}' primitive type)`);\n                    return false;\n                }\n            }\n            if ((cfg.matrix || cfg.position || cfg.rotation || cfg.scale) && (cfg.positionsCompressed || cfg.positionsDecodeBoundary)) {\n                this.error(\"Unexpected params: 'matrix', 'rotation', 'scale', 'position' not allowed with 'positionsCompressed'\");\n                return false;\n            }\n\n            // MATRIX - optional for batching\n\n            if (cfg.matrix) {\n                cfg.meshMatrix = cfg.matrix;\n            } else if (cfg.scale || cfg.rotation || cfg.position || cfg.quaternion) {\n                const scale = cfg.scale || DEFAULT_SCALE;\n                const position = cfg.position || DEFAULT_POSITION;\n                const quaternion = (cfg.rotation\n                                    ? math.eulerToQuaternion(cfg.rotation, \"XYZ\", tempQuaternion)\n                                    : cfg.quaternion || DEFAULT_QUATERNION);\n                cfg.meshMatrix = math.composeMat4(position, quaternion, scale, math.mat4());\n            }\n\n            if (cfg.positionsDecodeBoundary) {\n                cfg.positionsDecodeMatrix = createPositionsDecodeMatrix(cfg.positionsDecodeBoundary, math.mat4());\n            }\n\n            // RTC && COMPRESSION\n\n            if (cfg.positions) {\n                const rtcPositions = [];\n                const rtcNeeded = worldToRTCPositions(cfg.positions, rtcPositions, tempVec3a$c);\n                if (rtcNeeded) {\n                    cfg.positions = rtcPositions;\n                    cfg.origin = math.addVec3(cfg.origin, tempVec3a$c, math.vec3());\n                }\n\n                const aabb = math.collapseAABB3();\n                if (useDTX) {\n                    cfg.positionsDecodeMatrix = math.mat4();\n                    math.expandAABB3Points3(aabb, cfg.positions);\n                    cfg.positionsCompressed = quantizePositions(cfg.positions, aabb, cfg.positionsDecodeMatrix);\n                } else {\n                    if (cfg.meshMatrix) {\n                        math.transformPositions3(cfg.meshMatrix, cfg.positions, cfg.positions);\n                        cfg.meshMatrix = null; // Positions now baked, don't need any more\n                    }\n                    math.expandAABB3Points3(aabb, cfg.positions);\n                }\n                cfg.aabb = aabb;\n            } else if (cfg.positionsCompressed) {\n                const aabb = math.collapseAABB3();\n                math.expandAABB3Points3(aabb, cfg.positionsCompressed);\n                geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n                cfg.aabb = aabb;\n            }\n\n            if (useDTX && cfg.buckets) {\n                const aabb = math.collapseAABB3();\n                cfg.buckets.forEach(bucket => {\n                    const positions = bucket.positions || bucket.positionsCompressed;\n                    if (positions) {\n                        math.expandAABB3Points3(aabb, positions);\n                    }\n                });\n                if (cfg.positionsDecodeMatrix) {\n                    geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);\n                }\n                cfg.aabb = aabb;\n            }\n\n            // EDGES\n\n            if (isTriangular && (! cfg.buckets)) {\n                cfg.edgeIndices ||= buildEdgeIndices(cfg.positions || cfg.positionsCompressed, cfg.indices, cfg.positions ? null : cfg.positionsDecodeMatrix, 2.0);\n            }\n\n        } else {\n\n            // INSTANCING\n\n            cfg.positionsDecodeMatrix = cfg.geometry.positionsDecodeMatrix;\n\n            cfg.aabb = math.AABB3(cfg.geometry.aabb);\n\n            const transformId = cfg.transformId;\n            if (transformId) {\n\n                // TRANSFORM\n\n                cfg.transform = this._transforms[transformId];\n\n                if (!cfg.transform) {\n                    this.error(`[createMesh] Transform not found: ${transformId} - ensure that you create it first with createTransform()`);\n                    return false;\n                }\n\n            } else {\n\n                // MATRIX\n\n                if (cfg.matrix) {\n                    cfg.meshMatrix = cfg.matrix;\n                } else if (cfg.scale || cfg.rotation || cfg.position || cfg.quaternion) {\n                    const scale = cfg.scale || DEFAULT_SCALE;\n                    const position = cfg.position || DEFAULT_POSITION;\n                    const quaternion = (cfg.rotation\n                                        ? math.eulerToQuaternion(cfg.rotation, \"XYZ\", tempQuaternion)\n                                        : cfg.quaternion || DEFAULT_QUATERNION);\n                    cfg.meshMatrix = math.composeMat4(position, quaternion, scale, math.mat4());\n                }\n            }\n        }\n\n        if (cfg.meshMatrix) {\n            math.AABB3ToOBB3(cfg.aabb, tempOBB3);\n            math.transformOBB3(cfg.meshMatrix, tempOBB3, tempOBB3);\n            math.OBB3ToAABB3(tempOBB3, cfg.aabb);\n        }\n\n        cfg.color = cfg.color ? new Uint8Array(cfg.color.slice(0, 3).map(v => Math.floor(v * 255))) : defaultCompressedColor;\n        cfg.opacity = Math.floor((cfg.opacity ?? 1) * 255);\n\n        if (useDTX) {\n            cfg.type = DTX;\n\n            // BUCKETING\n            if (instancing) {\n                cfg.buckets = this._dtxBuckets[geometryId]; // lazy generated, reused\n            }\n            if (!cfg.buckets) {\n                cfg.buckets = createDTXBuckets(instancing ? cfg.geometry : cfg, this._enableVertexWelding, this._enableIndexBucketing);\n                if (instancing) {\n                    this._dtxBuckets[geometryId] = cfg.buckets;\n                }\n            }\n\n        } else {\n            cfg.type = instancing ? VBO_INSTANCED : VBO_BATCHED;\n\n            // PBR\n            cfg.metallic  = Math.floor((cfg.metallic  ?? 0) * 255);\n            cfg.roughness = Math.floor((cfg.roughness ?? 1) * 255);\n\n            // TEXTURE\n            // cfg.textureSetId = cfg.textureSetId || DEFAULT_TEXTURE_SET_ID;\n            if (textureSetId) {\n                cfg.textureSet = this._textureSets[textureSetId];\n                if ((! instancing) && (!cfg.textureSet)) {\n                    this.error(`[createMesh] Texture set not found: ${textureSetId} - ensure that you create it first with createTextureSet()`);\n                    return false;\n                }\n            }\n        }\n\n        cfg.numPrimitives = this._getNumPrimitives(cfg);\n\n        const mesh = new SceneModelMesh(this, cfg.id, cfg.color, cfg.opacity, cfg.transform, cfg.textureSet);\n        const pickId = this.scene._renderer.getPickID(mesh);\n        mesh.pickId = pickId;\n        mesh.origin = math.vec3(cfg.origin);\n        mesh.layer = (cfg.type === DTX) ? this._getDTXLayer(cfg) : this._getVBOLayer(cfg.type === VBO_INSTANCED, cfg);\n        mesh.aabb = cfg.aabb;\n        cfg.pickColor = new Uint8Array([pickId & 0xFF, pickId >> 8 & 0xFF, pickId >> 16 & 0xFF, pickId >> 24 & 0xFF]); // Quantized pick color\n        cfg.solid = (cfg.primitive === \"solid\");\n        cfg.meshMatrix = cfg.transform ? cfg.transform.worldMatrix : cfg.meshMatrix;\n        mesh.portionId = mesh.layer.createPortion(mesh, cfg);\n        mesh.numPrimitives = cfg.numPrimitives;\n        this._meshes[cfg.id] = mesh;\n        this._unusedMeshes[cfg.id] = mesh;\n        this._meshList.push(mesh);\n        return mesh;\n    }\n\n    _getNumPrimitives(cfg) {\n        let countIndices = 0;\n        const primitive = cfg.geometry ? cfg.geometry.primitive : cfg.primitive;\n        switch (primitive) {\n            case \"triangles\":\n            case \"solid\":\n            case \"surface\":\n                switch (cfg.type) {\n                    case DTX:\n                        for (let i = 0, len = cfg.buckets.length; i < len; i++) {\n                            countIndices += cfg.buckets[i].indices.length;\n                        }\n                        break;\n                    case VBO_BATCHED:\n                        countIndices += cfg.indices.length;\n                        break;\n                    case VBO_INSTANCED:\n                        countIndices += cfg.geometry.indices.length;\n                        break;\n                }\n                return Math.round(countIndices / 3);\n            case \"points\":\n                switch (cfg.type) {\n                    case DTX:\n                        for (let i = 0, len = cfg.buckets.length; i < len; i++) {\n                            countIndices += cfg.buckets[i].positionsCompressed.length;\n                        }\n                        break;\n                    case VBO_BATCHED:\n                        countIndices += cfg.positions ? cfg.positions.length : cfg.positionsCompressed.length;\n                        break;\n                    case VBO_INSTANCED:\n                        const geometry = cfg.geometry;\n                        countIndices += geometry.positions ? geometry.positions.length : geometry.positionsCompressed.length;\n                        break;\n                }\n                return Math.round(countIndices);\n            case \"lines\":\n            case \"line-strip\":\n                switch (cfg.type) {\n                    case DTX:\n                        for (let i = 0, len = cfg.buckets.length; i < len; i++) {\n                            countIndices += cfg.buckets[i].indices.length;\n                        }\n                        break;\n                    case VBO_BATCHED:\n                        countIndices += cfg.indices.length;\n                        break;\n                    case VBO_INSTANCED:\n                        countIndices += cfg.geometry.indices.length;\n                        break;\n                }\n                return Math.round(countIndices / 2);\n        }\n        return 0;\n    }\n\n    _getDTXLayer(cfg) {\n        const origin = cfg.origin;\n        const primitive = cfg.geometry ? cfg.geometry.primitive : cfg.primitive;\n        const layerId = `.${primitive}.${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}`;\n        let dtxLayer = this._dtxLayers[layerId];\n        if (dtxLayer) {\n            if (!dtxLayer.canCreatePortion(cfg)) {\n                //  dtxLayer.finalize();\n                delete this._dtxLayers[layerId];\n                dtxLayer = null;\n            } else {\n                return dtxLayer;\n            }\n        }\n        switch (primitive) {\n            case \"triangles\":\n            case \"solid\":\n            case \"surface\":\n                dtxLayer = new DTXLayer(this, primitive, origin);\n                break;\n            default:\n                return;\n        }\n        this._dtxLayers[layerId] = dtxLayer;\n        this.layerList.push(dtxLayer);\n        this._layersToFinalize.push(dtxLayer);\n        return dtxLayer;\n    }\n\n    _getVBOLayer(instancing, cfg) {\n        const geometry = instancing && cfg.geometry;\n        const primitive = instancing ? geometry.primitive : cfg.primitive;\n        const origin = cfg.origin;\n        const posDecode = (! instancing) && (cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary);\n        const positionsDecodeHash = posDecode ? this._createHashStringFromMatrix(posDecode) : \"-\";\n        const textureSetId = cfg.textureSetId || \"-\";\n        const geometryId = instancing ? cfg.geometryId : \"-\";\n        const layerId = (instancing ? \"instancing\" : \"batching\") + `.${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}.${primitive}.${positionsDecodeHash}.${textureSetId}.${geometryId}`;\n\n        if ((! instancing) && (layerId in this._vboLayers)) {\n            const layer = this._vboLayers[layerId];\n            const lenPositions = cfg.positionsCompressed ? cfg.positionsCompressed.length : cfg.positions.length;\n            if (! layer.canCreatePortion(lenPositions, (primitive === \"points\") ? 0 : cfg.indices.length)) {\n                layer.finalize();\n                delete this._vboLayers[layerId];\n            }\n        }\n\n        if (! (layerId in this._vboLayers)) {\n            const layer = new VBOLayer(this, primitive, origin, {\n                textureSet: cfg.textureSet,\n                ...(instancing ? {\n                    geometry: geometry,\n                } : {\n                    maxGeometryBatchSize: this._maxGeometryBatchSize,\n                    positionsDecodeMatrix: cfg.positionsDecodeMatrix,  // Can be undefined\n                    uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined\n                })\n            });\n            this.layerList.push(layer);\n            this._layersToFinalize.push(layer);\n            this._vboLayers[layerId] = layer;\n        }\n        return this._vboLayers[layerId];\n    }\n\n    _createHashStringFromMatrix(matrix) {\n        const matrixString = matrix.join(\";\");\n        let hash = 0;\n        for (let i = 0; i < matrixString.length; i++) {\n            const char = matrixString.charCodeAt(i);\n            hash = (hash << 5) - hash + char;\n            hash |= 0; // Convert to 32-bit integer\n        }\n        const hashString = (hash >>> 0).toString(16);\n        return hashString;\n    }\n\n    /**\n     * Creates a {@link SceneModelEntity} within this SceneModel.\n     *\n     * * Gives the SceneModelEntity one or more {@link SceneModelMesh}es previously created with\n     * {@link SceneModel#createMesh}. A SceneModelMesh can only belong to one SceneModelEntity, so you'll get an\n     * error if you try to reuse a mesh among multiple SceneModelEntitys.\n     * * The SceneModelEntity can have a {@link SceneModelTextureSet}, previously created with\n     * {@link SceneModel#createTextureSet}. A SceneModelTextureSet can belong to multiple SceneModelEntitys.\n     * * The SceneModelEntity can have a geometry, previously created with\n     * {@link SceneModel#createTextureSet}. A geometry is a \"virtual component\" and can belong to multiple SceneModelEntitys.\n     *\n     * @param {Object} cfg SceneModelEntity configuration.\n     * @param {String} cfg.id Optional ID for the new SceneModelEntity. Must not clash with any existing components within the {@link Scene}.\n     * @param {String[]} cfg.meshIds IDs of one or more meshes created previously with {@link SceneModel@createMesh}.\n     * @param {Boolean} [cfg.isObject] Set ````true```` if the {@link SceneModelEntity} represents an object, in which case it will be registered by {@link SceneModelEntity#id} in {@link Scene#objects} and can also have a corresponding {@link MetaObject} with matching {@link MetaObject#id}, registered by that ID in {@link MetaScene#metaObjects}.\n     * @param {Boolean} [cfg.visible=true] Indicates if the SceneModelEntity is initially visible.\n     * @param {Boolean} [cfg.culled=false] Indicates if the SceneModelEntity is initially culled from view.\n     * @param {Boolean} [cfg.pickable=true] Indicates if the SceneModelEntity is initially pickable.\n     * @param {Boolean} [cfg.clippable=true] Indicates if the SceneModelEntity is initially clippable.\n     * @param {Boolean} [cfg.collidable=true] Indicates if the SceneModelEntity is initially included in boundary calculations.\n     * @param {Boolean} [cfg.castsShadow=true] Indicates if the SceneModelEntity initially casts shadows.\n     * @param {Boolean} [cfg.receivesShadow=true]  Indicates if the SceneModelEntity initially receives shadows.\n     * @param {Boolean} [cfg.xrayed=false] Indicates if the SceneModelEntity is initially xrayed. XRayed appearance is configured by {@link SceneModel#xrayMaterial}.\n     * @param {Boolean} [cfg.highlighted=false] Indicates if the SceneModelEntity is initially highlighted. Highlighted appearance is configured by {@link SceneModel#highlightMaterial}.\n     * @param {Boolean} [cfg.selected=false] Indicates if the SceneModelEntity is initially selected. Selected appearance is configured by {@link SceneModel#selectedMaterial}.\n     * @param {Boolean} [cfg.edges=false] Indicates if the SceneModelEntity's edges are initially emphasized. Edges appearance is configured by {@link SceneModel#edgeMaterial}.\n     * @returns {SceneModelEntity} The new SceneModelEntity.\n     */\n    createEntity(cfg) {\n        if (cfg.id === undefined) {\n            cfg.id = math.createUUID();\n        } else if (this.scene.components[cfg.id]) {\n            this.error(`Scene already has a Component with this ID: ${cfg.id} - will assign random ID`);\n            cfg.id = math.createUUID();\n        }\n        if (cfg.meshIds === undefined) {\n            this.error(\"Config missing: meshIds\");\n            return null;\n        }\n\n        const notFalse = v => v !== false;\n        let flags = 0;\n        flags |= (this._visible     && notFalse(cfg.visible)     && ENTITY_FLAGS.VISIBLE);\n        flags |= (this._pickable    && notFalse(cfg.pickable)    && ENTITY_FLAGS.PICKABLE);\n        flags |= (this._culled      && notFalse(cfg.culled)      && ENTITY_FLAGS.CULLED);\n        flags |= (this._clippable   && notFalse(cfg.clippable)   && ENTITY_FLAGS.CLIPPABLE);\n        flags |= (this._collidable  && notFalse(cfg.collidable)  && ENTITY_FLAGS.COLLIDABLE);\n        flags |= (this._xrayed      && notFalse(cfg.xrayed)      && ENTITY_FLAGS.XRAYED);\n        flags |= (this._highlighted && notFalse(cfg.highlighted) && ENTITY_FLAGS.HIGHLIGHTED);\n        flags |= (this._selected    && notFalse(cfg.selected)    && ENTITY_FLAGS.SELECTED);\n        flags |= (this._edges       && notFalse(cfg.edges)       && ENTITY_FLAGS.EDGES);\n        cfg.flags = flags;\n\n        let meshes = [];\n        for (let i = 0, len = cfg.meshIds.length; i < len; i++) {\n            const meshId = cfg.meshIds[i];\n            let mesh = this._meshes[meshId]; // Trying to get already created mesh\n            if (!mesh) { // Checks if there is already created mesh for this meshId\n                this.error(`Mesh with this ID not found: \"${meshId}\" - ignoring this mesh`); // There is no such cfg\n                continue;\n            }\n            if (mesh.parent) {\n                this.error(`Mesh with ID \"${meshId}\" already belongs to object with ID \"${mesh.parent.id}\" - ignoring this mesh`);\n                continue;\n            }\n            meshes.push(mesh);\n            delete this._unusedMeshes[meshId];\n        }\n        const lodCullable = true;\n        const entity = new SceneModelEntity(\n            this,\n            cfg.isObject,\n            cfg.id,\n            meshes,\n            cfg.flags,\n            lodCullable); // Internally sets SceneModelEntity#parent to this SceneModel\n        this._entityList.push(entity);\n        this._entities[cfg.id] = entity;\n        this._entitiesToFinalize.push(entity);\n        this.numEntities++;\n        return entity;\n    }\n\n    /**\n     * Pre-renders all meshes that have been added, even if the SceneModel has not bee finalized yet.\n     * This is use for progressively showing the SceneModel while it is being loaded or constructed.\n     * @returns {boolean}\n     */\n    preFinalize() {\n        if (this.destroyed) {\n            return false;\n        }\n        if (this._layersToFinalize.length === 0) {\n            return false;\n        }\n        this._createDummyEntityForUnusedMeshes();\n        for (let i = 0, len = this._layersToFinalize.length; i < len; i++) {\n            const layer = this._layersToFinalize[i];\n            layer.finalize();\n        }\n        this._vboLayers = {};\n        this._dtxLayers = {};\n        this._layersToFinalize = [];\n        for (let i = 0, len = this._entitiesToFinalize.length; i < len; i++) {\n            const entity = this._entitiesToFinalize[i];\n            entity._finalize();\n        }\n        for (let i = 0, len = this._entitiesToFinalize.length; i < len; i++) {\n            const entity = this._entitiesToFinalize[i];\n            entity._finalize2();\n        }\n        this._entitiesToFinalize = [];\n        this.scene._aabbDirty = true;\n        this._viewMatrixDirty = true;\n        this._matrixDirty = true;\n        this._aabbDirty = true;\n        this._setWorldMatrixDirty();\n        this._sceneModelDirty();\n        this.position = this._position;\n        // Sort layers to reduce WebGL shader switching when rendering them\n        this.layerList.sort((a, b) => {\n            if (a.sortId < b.sortId) {\n                return -1;\n            }\n            if (a.sortId > b.sortId) {\n                return 1;\n            }\n            return 0;\n        });\n        for (let i = 0, len = this.layerList.length; i < len; i++) {\n            const layer = this.layerList[i];\n            layer.layerIndex = i;\n        }\n        this.glRedraw();\n        this._layersFinalized = true;\n    }\n\n    /**\n     * Finalizes this SceneModel.\n     *\n     * Once finalized, you can't add anything more to this SceneModel.\n     */\n    finalize() {\n        if (this.destroyed) {\n            return;\n        }\n        this.preFinalize();\n        this._geometries = {};\n        this._dtxBuckets = {};\n        this._textures = {};\n        this._textureSets = {};\n    }\n\n    /** @private */\n    stateSortCompare(drawable1, drawable2) {\n    }\n\n    /** @private */\n    rebuildRenderFlags() {\n        this.renderFlags.reset();\n        this._updateRenderFlagsVisibleLayers();\n        if (this.renderFlags.numLayers > 0 && this.renderFlags.numVisibleLayers === 0) {\n            this.renderFlags.culled = true;\n            return;\n        }\n        this._updateRenderFlags();\n    }\n\n    /**\n     * @private\n     */\n    _updateRenderFlagsVisibleLayers() {\n        const renderFlags = this.renderFlags;\n        renderFlags.numLayers = this.layerList.length;\n        renderFlags.numVisibleLayers = 0;\n        for (let layerIndex = 0, len = this.layerList.length; layerIndex < len; layerIndex++) {\n            const layer = this.layerList[layerIndex];\n            const layerVisible = this._getActiveSectionPlanesForLayer(layer);\n            if (layerVisible) {\n                renderFlags.visibleLayers[renderFlags.numVisibleLayers++] = layerIndex;\n            }\n        }\n    }\n\n    /** @private */\n    _createDummyEntityForUnusedMeshes() {\n        const unusedMeshIds = Object.keys(this._unusedMeshes);\n        if (unusedMeshIds.length > 0) {\n            const entityId = `${this.id}-${math.createUUID()}`;\n            this.warn(`Creating dummy SceneModelEntity \"${entityId}\" for unused SceneMeshes: [${unusedMeshIds.join(\",\")}]`);\n            this.createEntity({\n                id: entityId,\n                meshIds: unusedMeshIds,\n                isObject: true\n            });\n        }\n        this._unusedMeshes = {};\n    }\n\n    _getActiveSectionPlanesForLayer(layer) {\n        const renderFlags = this.renderFlags;\n        const sectionPlanes = this.scene._sectionPlanesState.sectionPlanes;\n        const numSectionPlanes = sectionPlanes.length;\n        const baseIndex = layer.layerIndex * numSectionPlanes;\n        if (numSectionPlanes > 0) {\n            for (let i = 0; i < numSectionPlanes; i++) {\n                const sectionPlane = sectionPlanes[i];\n                if (!sectionPlane.active) {\n                    renderFlags.sectionPlanesActivePerLayer[baseIndex + i] = false;\n                } else {\n                    renderFlags.sectionPlanesActivePerLayer[baseIndex + i] = true;\n                    renderFlags.sectioned = true;\n                }\n            }\n        }\n        return true;\n    }\n\n    _updateRenderFlags() {\n        if (this.numVisibleLayerPortions === 0) {\n            return;\n        }\n        if (this.numCulledLayerPortions === this.numPortions) {\n            return;\n        }\n        const renderFlags = this.renderFlags;\n        renderFlags.colorOpaque = (this.numTransparentLayerPortions < this.numPortions);\n        if (this.numTransparentLayerPortions > 0) {\n            renderFlags.colorTransparent = true;\n        }\n        if (this.numXRayedLayerPortions > 0) {\n            const xrayMaterial = this.scene.xrayMaterial._state;\n            if (xrayMaterial.fill) {\n                if (xrayMaterial.fillAlpha < 1.0) {\n                    renderFlags.xrayedSilhouetteTransparent = true;\n                } else {\n                    renderFlags.xrayedSilhouetteOpaque = true;\n                }\n            }\n            if (xrayMaterial.edges) {\n                if (xrayMaterial.edgeAlpha < 1.0) {\n                    renderFlags.xrayedEdgesTransparent = true;\n                } else {\n                    renderFlags.xrayedEdgesOpaque = true;\n                }\n            }\n        }\n        if (this.numEdgesLayerPortions > 0) {\n            const edgeMaterial = this.scene.edgeMaterial._state;\n            if (edgeMaterial.edges) {\n                renderFlags.edgesOpaque = (this.numTransparentLayerPortions < this.numPortions);\n                if (this.numTransparentLayerPortions > 0) {\n                    renderFlags.edgesTransparent = true;\n                }\n            }\n        }\n        if (this.numSelectedLayerPortions > 0) {\n            const selectedMaterial = this.scene.selectedMaterial._state;\n            if (selectedMaterial.fill) {\n                if (selectedMaterial.fillAlpha < 1.0) {\n                    renderFlags.selectedSilhouetteTransparent = true;\n                } else {\n                    renderFlags.selectedSilhouetteOpaque = true;\n                }\n            }\n            if (selectedMaterial.edges) {\n                if (selectedMaterial.edgeAlpha < 1.0) {\n                    renderFlags.selectedEdgesTransparent = true;\n                } else {\n                    renderFlags.selectedEdgesOpaque = true;\n                }\n            }\n        }\n        if (this.numHighlightedLayerPortions > 0) {\n            const highlightMaterial = this.scene.highlightMaterial._state;\n            if (highlightMaterial.fill) {\n                if (highlightMaterial.fillAlpha < 1.0) {\n                    renderFlags.highlightedSilhouetteTransparent = true;\n                } else {\n                    renderFlags.highlightedSilhouetteOpaque = true;\n                }\n            }\n            if (highlightMaterial.edges) {\n                if (highlightMaterial.edgeAlpha < 1.0) {\n                    renderFlags.highlightedEdgesTransparent = true;\n                } else {\n                    renderFlags.highlightedEdgesOpaque = true;\n                }\n            }\n        }\n    }\n\n    // -------------- RENDERING ---------------------------------------------------------------------------------------\n\n\n    /**\n     * @private\n     */\n    _withEachVisibleLayer(frameCtx, testNumVisibleLayerPortions, cb) {\n        if (testNumVisibleLayerPortions && (this.numVisibleLayerPortions === 0)) {\n            return;\n        }\n        const testLayerCull = frameCtx.testAABB;\n        const renderFlags = this.renderFlags;\n        for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {\n            const layer = this.layerList[renderFlags.visibleLayers[i]];\n            if ((! testLayerCull) || testLayerCull(layer.getAABB())) {\n                cb(layer);\n            }\n        }\n    }\n\n    drawColorOpaque          (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawColorOpaque          (this.renderFlags, frameCtx)); }\n    drawColorTransparent     (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawColorTransparent     (this.renderFlags, frameCtx)); }\n    drawDepth                (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawDepth                (this.renderFlags, frameCtx)); } // Dedicated to SAO because it skips transparent objects\n    drawSilhouetteXRayed     (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawSilhouetteXRayed     (this.renderFlags, frameCtx)); }\n    drawSilhouetteHighlighted(frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawSilhouetteHighlighted(this.renderFlags, frameCtx)); }\n    drawSilhouetteSelected   (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawSilhouetteSelected   (this.renderFlags, frameCtx)); }\n    drawEdgesColorOpaque     (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawEdgesColorOpaque     (this.renderFlags, frameCtx)); }\n    drawEdgesColorTransparent(frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawEdgesColorTransparent(this.renderFlags, frameCtx)); }\n    drawEdgesXRayed          (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawEdgesXRayed          (this.renderFlags, frameCtx)); }\n    drawEdgesHighlighted     (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawEdgesHighlighted     (this.renderFlags, frameCtx)); }\n    drawEdgesSelected        (frameCtx) { this._withEachVisibleLayer(frameCtx, false, layer => layer.drawEdgesSelected        (this.renderFlags, frameCtx)); }\n    drawOcclusion            (frameCtx) { this._withEachVisibleLayer(frameCtx, true,  layer => layer.drawOcclusion            (this.renderFlags, frameCtx)); }\n    drawShadow               (frameCtx) { this._withEachVisibleLayer(frameCtx, true,  layer => layer.drawShadow               (this.renderFlags, frameCtx)); }\n    drawPickMesh             (frameCtx) { this._withEachVisibleLayer(frameCtx, true,  layer => layer.drawPickMesh             (this.renderFlags, frameCtx)); }\n    drawPickDepths           (frameCtx) { this._withEachVisibleLayer(frameCtx, true,  layer => layer.drawPickDepths           (this.renderFlags, frameCtx)); }\n    drawPickNormals          (frameCtx) { this._withEachVisibleLayer(frameCtx, true,  layer => layer.drawPickNormals          (this.renderFlags, frameCtx)); }\n    _drawSnap    (frameCtx, isSnapInit) { this._withEachVisibleLayer(frameCtx, true,  layer => layer.drawSnap                 (this.renderFlags, frameCtx, isSnapInit)); }\n\n    drawSnapInit(frameCtx) { this._drawSnap(frameCtx, true ); }\n    drawSnap    (frameCtx) { this._drawSnap(frameCtx, false); }\n\n    /**\n     * Destroys this SceneModel.\n     */\n    destroy() {\n        Object.values(this._vboLayers).forEach(l => l.destroy());\n        this._vboLayers = {};\n        this.scene.camera.off(this._onCameraViewMatrix);\n        this.scene.off(this._onTick);\n        for (let i = 0, len = this.layerList.length; i < len; i++) {\n            this.layerList[i].destroy();\n        }\n        this.layerList = [];\n        for (let i = 0, len = this._entityList.length; i < len; i++) {\n            this._entityList[i]._destroy();\n        }\n        this._layersToFinalize = [];\n        // Object.entries(this._geometries).forEach(([id, geometry]) => {\n        //     geometry.destroy();\n        // });\n        this._geometries = {};\n        this._dtxBuckets = {};\n        this._textures = {};\n        this._textureSets = {};\n        this._meshes = {};\n        this._entities = {};\n        this.scene._aabbDirty = true;\n        if (this._isModel) {\n            this.scene._deregisterModel(this);\n        }\n        super.destroy();\n    }\n}\n\n\n/**\n * This function applies two steps to the provided mesh geometry data:\n *\n * - 1st, it reduces its `.positions` to unique positions, thus removing duplicate vertices. It will adjust the `.indices` and `.edgeIndices` array accordingly to the unique `.positions`.\n *\n * - 2nd, it tries to do an optimization called `index rebucketting`\n *\n *   _Rebucketting minimizes the amount of RAM usage for a given mesh geometry by trying do demote its needed index bitness._\n *\n *   - _for 32 bit indices, will try to demote them to 16 bit indices_\n *   - _for 16 bit indices, will try to demote them to 8 bits indices_\n *   - _8 bits indices are kept as-is_\n *\n *   The fact that 32/16/8 bits are needed for indices, depends on the number of maximumm indexable vertices within the mesh geometry: this is, the number of vertices in the mesh geometry.\n *\n * The function returns the same provided input `geometry`, enrichened with the additional key `.preparedBukets`.\n *\n * @param {object} geometry The mesh information containing `.positions`, `.indices`, `.edgeIndices` arrays.\n *\n * @param enableVertexWelding\n * @param enableIndexBucketing\n * @returns {object} The mesh information enrichened with `.buckets` key.\n */\nfunction createDTXBuckets(geometry, enableVertexWelding, enableIndexBucketing) {\n    let uniquePositionsCompressed, uniqueIndices, uniqueEdgeIndices;\n    if (enableVertexWelding || enableIndexBucketing) { // Expensive - careful!\n        [\n            uniquePositionsCompressed,\n            uniqueIndices,\n            uniqueEdgeIndices,\n        ] = uniquifyPositions({\n            positionsCompressed: geometry.positionsCompressed,\n            indices: geometry.indices,\n            edgeIndices: geometry.edgeIndices\n        });\n    } else {\n        uniquePositionsCompressed = geometry.positionsCompressed;\n        uniqueIndices = geometry.indices;\n        uniqueEdgeIndices = geometry.edgeIndices;\n    }\n    let buckets;\n    if (enableIndexBucketing) {\n        let numUniquePositions = uniquePositionsCompressed.length / 3;\n        buckets = rebucketPositions({\n                positionsCompressed: uniquePositionsCompressed,\n                indices: uniqueIndices,\n                edgeIndices: uniqueEdgeIndices,\n            },\n            (numUniquePositions > (1 << 16)) ? 16 : 8,\n            // true\n        );\n    } else {\n        buckets = [{\n            positionsCompressed: uniquePositionsCompressed,\n            indices: uniqueIndices,\n            edgeIndices: uniqueEdgeIndices,\n        }];\n    }\n    return buckets;\n}\n\n/**\n * A set of 3D line segments.\n *\n * * Creates a set of 3D line segments.\n * * Registered by {@link LineSet#id} in {@link Scene#lineSets}.\n * * Configure color using the {@link LinesMaterial} located at {@link Scene#linesMaterial}.\n * * {@link BCFViewpointsPlugin} will save and load Linesets in BCF viewpoints.\n *\n * ## Usage\n *\n * In the example below, we'll load the Schependomlaan model, then use\n * a ````LineSet```` to show a grid underneath the model.\n *\n * [<img src=\"http://xeokit.github.io/xeokit-sdk/assets/images/LineSet_grid.png\">](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#LineSet_grid)\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/scenegraph/#LineSet_grid)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, LineSet, buildGridGeometry} from \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/xeokit-sdk.es.min.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n *  });\n *\n * const camera = viewer.camera;\n *\n * viewer.camera.eye = [-2.56, 8.38, 8.27];\n * viewer.camera.look = [13.44, 3.31, -14.83];\n * viewer.camera.up = [0.10, 0.98, -0.14];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *      id: \"myModel\",\n *      src: \"../assets/models/xkt/v8/ifc/Schependomlaan.ifc.xkt\",\n *      position: [0,1,0],\n *      edges: true,\n *      saoEnabled: true\n *  });\n *\n * const geometryArrays = buildGridGeometry({\n *      size: 100,\n *      divisions: 30\n *  });\n *\n * new LineSet(viewer.scene, {\n *      positions: geometryArrays.positions,\n *      indices: geometryArrays.indices\n * });\n * ````\n */\nclass LineSet extends Component {\n\n    /**\n     * Creates a new LineSet.\n     *\n     * Registers the LineSet in {@link Scene#lineSets}; causes Scene to fire a \"lineSetCreated\" event.\n     *\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this ````LineSet```` as well.\n     * @param {*} [cfg]  ````LineSet```` configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number[]} cfg.positions World-space 3D vertex positions.\n     * @param {Number[]} [cfg.indices] Indices to connect ````positions```` into line segments. Note that these are separate line segments, not a polyline.\n     * @param {Number[]} [cfg.color=[1,1,1]] The color of this ````LineSet````. This is both emissive and diffuse.\n     * @param {Boolean} [cfg.visible=true] Indicates whether or not this ````LineSet```` is visible.\n     * @param {Number} [cfg.opacity=1.0] ````LineSet````'s initial opacity factor.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._positions = cfg.positions || [];\n\n        if (cfg.indices) {\n            this._indices = cfg.indices;\n        } else {\n            this._indices = [];\n            for (let i = 0, len = (this._positions.length / 3) - 1; i < len; i += 2) {\n                this._indices.push(i);\n                this._indices.push(i + 1);\n            }\n        }\n\n        this._color = cfg.color || [1, 1, 1];\n        this._opacity = cfg.opacity || 1.0;\n\n        this._sceneModel = new SceneModel(this, {\n            isModel: false // Don't register in Scene.models\n        });\n\n        this._sceneModel.createMesh({\n            id: \"linesMesh\",\n            primitive: \"lines\",\n            positions: this._positions,\n            indices: this._indices,\n            color: this._color,\n            opacity: this._opacity,\n        });\n\n        this._sceneModel.createEntity({\n            meshIds: [\"linesMesh\"],\n            visible: cfg.visible,\n            clippable: cfg.clippable,\n               collidable: cfg.collidable\n        });\n\n        this._sceneModel.finalize();\n\n        this.scene._lineSetCreated(this);\n    }\n\n    /**\n     * Sets if this ````LineSet```` is visible.\n     *\n     * Default value is ````true````.\n     *\n     * @param {Boolean} visible Set ````true```` to make this ````LineSet```` visible.\n     */\n    set visible(visible) {\n        this._sceneModel.visible = visible;\n    }\n\n    /**\n     * Gets if this ````LineSet```` is visible.\n     *\n     * Default value is ````true````.\n     *\n     * @returns {Boolean} Returns ````true```` if visible.\n     */\n    get visible() {\n        return this._sceneModel.visible;\n    }\n\n    /**\n     * Gets the 3D World-space vertex positions of the lines in this ````LineSet````.\n     *\n     * @returns {Number[]}\n     */\n    get positions() {\n        return this._positions;\n    }\n\n    /**\n     * Gets the vertex indices of the lines in this ````LineSet````.\n     *\n     * @returns {Number[]}\n     */\n    get indices() {\n        return this._indices;\n    }\n\n    /**\n     * Destroys this ````LineSet````.\n     *\n     * Removes the ```LineSet```` from {@link Scene#lineSets}; causes Scene to fire a \"lineSetDestroyed\" event.\n     */\n    destroy() {\n        super.destroy(); // destroyes _sceneModel\n        this.scene._lineSetDestroyed(this);\n    }\n}\n\n/**\n * @desc A dynamic light source within a {@link Scene}.\n *\n * These are registered by {@link Light#id} in {@link Scene#lights}.\n */\nclass Light extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Light\";\n    }\n\n    /**\n     * @private\n     */\n    get isLight() {\n        return true;\n    }\n\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n    }\n}\n\n/**\n * @desc An ambient light source of fixed color and intensity that illuminates all {@link Mesh}es equally.\n *\n * * {@link AmbientLight#color} multiplies by {@link PhongMaterial#ambient} at each position of each {@link ReadableGeometry} surface.\n * * {@link AmbientLight#color} multiplies by {@link LambertMaterial#color} uniformly across each triangle of each {@link ReadableGeometry} (ie. flat shaded).\n * * {@link AmbientLight}s, {@link DirLight}s and {@link PointLight}s are registered by their {@link Component#id} on {@link Scene#lights}.\n *\n * ## Usage\n *\n * In the example below we'll destroy the {@link Scene}'s default light sources then create an AmbientLight and a couple of {@link @DirLight}s:\n *\n * [[Run this example](/examples/index.html#lights_AmbientLight)]\n *\n * ````javascript\n * import {Viewer, Mesh, buildTorusGeometry,\n * ReadableGeometry, PhongMaterial, Texture, AmbientLight} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer and arrange the camera\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * // Replace the Scene's default lights with a single custom AmbientLight\n *\n * viewer.scene.clearLights();\n *\n * new AmbientLight(viewer.scene, {\n *      color: [0.0, 0.3, 0.7],\n *      intensity: 1.0\n * });\n *\n * new DirLight(viewer.scene, {\n *      id: \"keyLight\",\n *      dir: [0.8, -0.6, -0.8],\n *      color: [1.0, 0.3, 0.3],\n *      intensity: 1.0,\n *      space: \"view\"\n * });\n *\n * new DirLight(viewer.scene, {\n *      id: \"fillLight\",\n *      dir: [-0.8, -0.4, -0.4],\n *      color: [0.3, 1.0, 0.3],\n *      intensity: 1.0,\n *      space: \"view\"\n * });\n *\n * new DirLight(viewer.scene, {\n *      id: \"rimLight\",\n *      dir: [0.2, -0.8, 0.8],\n *      color: [0.6, 0.6, 0.6],\n *      intensity: 1.0,\n *      space: \"view\"\n * });\n *\n * // Create a mesh with torus shape and PhongMaterial\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildSphereGeometry({\n *          center: [0, 0, 0],\n *          radius: 1.5,\n *          tube: 0.5,\n *          radialSegments: 32,\n *          tubeSegments: 24,\n *          arc: Math.PI * 2.0\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *          ambient: [1.0, 1.0, 1.0],\n *          shininess: 30,\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse/uvGrid2.jpg\"\n *          })\n *      })\n * });\n *\n * // Adjust the color of our AmbientLight\n *\n * var ambientLight = viewer.scene.lights[\"myAmbientLight\"];\n * ambientLight.color = [1.0, 0.8, 0.8];\n *````\n */\nclass AmbientLight extends Light {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"AmbientLight\";\n    }\n\n    /**\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this AmbientLight as well.\n     * @param {*} [cfg] AmbientLight configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number[]} [cfg.color=[0.7, 0.7, 0.8]]  The color of this AmbientLight.\n     * @param {Number} [cfg.intensity=[1.0]]  The intensity of this AmbientLight, as a factor in range ````[0..1]````.\n     */\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n        this._state = {\n            type: \"ambient\",\n            color: math.vec3([0.7, 0.7, 0.7]),\n            intensity: 1.0\n        };\n        this.color = cfg.color;\n        this.intensity = cfg.intensity;\n        this.scene._lightCreated(this);\n    }\n\n    /**\n     * Sets the RGB color of this AmbientLight.\n     *\n     * Default value is ````[0.7, 0.7, 0.8]````.\n     *\n     * @param {Number[]} color The AmbientLight's RGB color.\n     */\n    set color(color) {\n        this._state.color.set(color || [0.7, 0.7, 0.8]);\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the RGB color of this AmbientLight.\n     *\n     * Default value is ````[0.7, 0.7, 0.8]````.\n     *\n     * @returns {Number[]} The AmbientLight's RGB color.\n     */\n    get color() {\n        return this._state.color;\n    }\n\n    /**\n     * Sets the intensity of this AmbientLight.\n     *\n     * Default value is ````1.0```` for maximum intensity.\n     *\n     * @param {Number} intensity The AmbientLight's intensity.\n     */\n    set intensity(intensity) {\n        this._state.intensity = intensity !== undefined ? intensity : 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the intensity of this AmbientLight.\n     *\n     * Default value is ````1.0```` for maximum intensity.\n     *\n     * @returns {Number} The AmbientLight's intensity.\n     */\n    get intensity() {\n        return this._state.intensity;\n    }\n\n    /**\n     * Destroys this AmbientLight.\n     */\n    destroy() {\n\n        super.destroy();\n\n        this.scene._lightDestroyed(this);\n    }\n}\n\n/**\n * @desc Represents a WebGL render buffer.\n * @private\n */\nclass RenderBuffer {\n\n    constructor(gl, colorFormats, hasDepthTexture) {\n        /** @type {WebGL2RenderingContext} */\n        this.gl = gl;\n        this.allocated = false;\n        this.buffer = null;\n        this.bound = false;\n        this._colorFormats = colorFormats;\n        this._hasDepthTexture = hasDepthTexture;\n    }\n\n    setSize(size) {\n        this.size = size;\n    }\n\n    bind() {\n        const width  = this.size[0];\n        const height = this.size[1];\n\n        if (this.buffer && ((this.buffer.width !== width) || (this.buffer.height !== height))) {\n            this.buffer.cleanup();\n            this.buffer = null;\n        }\n\n        if (! this.buffer) {\n            this._allocateBuffer(width, height);\n            this.bound = false;\n        }\n\n        if (! this.bound) {\n            const gl = this.gl;\n            gl.bindFramebuffer(gl.FRAMEBUFFER, this.buffer.framebuf);\n            this.bound = true;\n        }\n    }\n\n    _allocateBuffer(width, height) {\n        const internalformats = this._colorFormats || [];\n\n        const gl = this.gl;\n\n        const createTexture = () => {\n            const tex = gl.createTexture();\n            gl.bindTexture(gl.TEXTURE_2D, tex);\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n            return tex;\n        };\n\n        const colorTextures = ((internalformats.length > 0) ? internalformats : [ null ]).map(internalformat => {\n            const tex = createTexture();\n            if (internalformat) {\n                gl.texStorage2D(gl.TEXTURE_2D, 1, internalformat, width, height);\n            } else {\n                gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n            }\n            return tex;\n        });\n\n        const renderbuf = gl.createRenderbuffer();\n        gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuf);\n        gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT32F, width, height);\n\n        const framebuf = gl.createFramebuffer();\n        gl.bindFramebuffer(gl.FRAMEBUFFER, framebuf);\n        for (let i = 0; i < colorTextures.length; i++) {\n            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, colorTextures[i], 0);\n        }\n        if (internalformats.length > 0) {\n            gl.drawBuffers(colorTextures.map((_, i) => gl.COLOR_ATTACHMENT0 + i));\n        }\n\n        const depthTexture = this._hasDepthTexture && createTexture();\n        if (depthTexture) {\n            gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F, width, height, 0, gl.DEPTH_COMPONENT, gl.FLOAT, null);\n            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0);\n        } else {\n            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuf);\n        }\n\n        gl.bindTexture(gl.TEXTURE_2D, null);\n        gl.bindRenderbuffer(gl.RENDERBUFFER, null);\n        gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n        // Verify framebuffer is OK\n\n        gl.bindFramebuffer(gl.FRAMEBUFFER, framebuf);\n        if (!gl.isFramebuffer(framebuf)) {\n            throw \"Invalid framebuffer\";\n        }\n        gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n        const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n\n        switch (status) {\n\n            case gl.FRAMEBUFFER_COMPLETE:\n                break;\n\n            case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:\n                throw \"Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT\";\n\n            case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:\n                throw \"Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\";\n\n            case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:\n                throw \"Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS\";\n\n            case gl.FRAMEBUFFER_UNSUPPORTED:\n                throw \"Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED\";\n\n            default:\n                throw \"Incomplete framebuffer: \" + status;\n        }\n\n        this.buffer = {\n            cleanup: () => {\n                colorTextures.forEach(texture => gl.deleteTexture(texture));\n                depthTexture && gl.deleteTexture(depthTexture);\n                gl.deleteFramebuffer(framebuf);\n                gl.deleteRenderbuffer(renderbuf);\n            },\n            framebuf: framebuf,\n            width: width,\n            height: height\n        };\n\n        this.colorTextures = colorTextures.map(tex => ({\n            bind: function(unit) {\n                gl.activeTexture(gl[\"TEXTURE\" + unit]);\n                gl.bindTexture(gl.TEXTURE_2D, tex);\n                return true;\n            }\n        }));\n\n        this.depthTexture = depthTexture && {\n            bind: function(unit) {\n                gl.activeTexture(gl[\"TEXTURE\" + unit]);\n                gl.bindTexture(gl.TEXTURE_2D, depthTexture);\n                return true;\n            }\n        };\n    }\n\n    read(pickX, pickY, glFormat = null, glType = null, arrayType = Uint8Array, arrayMultiplier = 4, colorBufferIndex = 0) {\n        const pix = new arrayType(arrayMultiplier);\n        const gl = this.gl;\n        gl.readBuffer(gl.COLOR_ATTACHMENT0 + colorBufferIndex);\n        gl.readPixels(pickX, this.buffer.height - pickY - 1, 1, 1, glFormat || gl.RGBA, glType || gl.UNSIGNED_BYTE, pix, 0);\n        return pix;\n    }\n\n    unbind() {\n        const gl = this.gl;\n        gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n        this.bound = false;\n    }\n\n    destroy() {\n        if (this.allocated) {\n            this.buffer.cleanup();\n            this.allocated = false;\n            this.buffer = null;\n            this.bound = false;\n        }\n        this.colorTextures = null;\n        this.depthTexture = null;\n    }\n}\n\n/**\n * @desc A directional light source that illuminates all {@link Mesh}es equally from a given direction.\n *\n * * Has an emission direction vector in {@link DirLight#dir}, but no position.\n * * Defined in either *World* or *View* coordinate space. When in World-space, {@link DirLight#dir} is relative to the\n * World coordinate system, and will appear to move as the {@link Camera} moves. When in View-space, {@link DirLight#dir} is\n * relative to the View coordinate system, and will behave as if fixed to the viewer's head.\n * * {@link AmbientLight}s, {@link DirLight}s and {@link PointLight}s are registered by their {@link Component#id} on {@link Scene#lights}.\n *\n * ## Usage\n *\n * In the example below we'll replace the {@link Scene}'s default light sources with three View-space DirLights.\n *\n * [[Run this example](/examples/index.html#lights_DirLight_view)]\n *\n * ````javascript\n * import {Viewer, Mesh, buildSphereGeometry,\n *      buildPlaneGeometry, ReadableGeometry,\n *      PhongMaterial, Texture, DirLight} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer and arrange the camera\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * // Replace the Scene's default lights with three custom view-space DirLights\n *\n * viewer.scene.clearLights();\n *\n * new DirLight(viewer.scene, {\n *      id: \"keyLight\",\n *      dir: [0.8, -0.6, -0.8],\n *      color: [1.0, 0.3, 0.3],\n *      intensity: 1.0,\n *      space: \"view\"\n * });\n *\n * new DirLight(viewer.scene, {\n *      id: \"fillLight\",\n *      dir: [-0.8, -0.4, -0.4],\n *      color: [0.3, 1.0, 0.3],\n *      intensity: 1.0,\n *      space: \"view\"\n * });\n *\n * new DirLight(viewer.scene, {\n *      id: \"rimLight\",\n *      dir: [0.2, -0.8, 0.8],\n *      color: [0.6, 0.6, 0.6],\n *      intensity: 1.0,\n *      space: \"view\"\n * });\n *\n *\n * // Create a sphere and ground plane\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildSphereGeometry({\n *          radius: 2.0\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *          diffuse: [0.7, 0.7, 0.7],\n *          specular: [1.0, 1.0, 1.0],\n *          emissive: [0, 0, 0],\n *          alpha: 1.0,\n *          ambient: [1, 1, 0],\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse/uvGrid2.jpg\"\n *          })\n *      })\n *  });\n *\n * new Mesh(viewer.scene, {\n *      geometry: buildPlaneGeometry(ReadableGeometry, viewer.scene, {\n *          xSize: 30,\n *          zSize: 30\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse/uvGrid2.jpg\"\n *          }),\n *          backfaces: true\n *      }),\n *      position: [0, -2.1, 0]\n * });\n * ````\n */\nclass DirLight extends Light {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"DirLight\";\n    }\n\n    /**\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this DirLight as well.\n     * @param {*} [cfg] The DirLight configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number[]} [cfg.dir=[1.0, 1.0, 1.0]]  A unit vector indicating the direction that the light is shining,  given in either World or View space, depending on the value of the ````space```` parameter.\n     * @param {Number[]} [cfg.color=[0.7, 0.7, 0.8 ]] The color of this DirLight.\n     * @param {Number} [cfg.intensity=1.0] The intensity of this DirLight, as a factor in range ````[0..1]````.\n     * @param {String} [cfg.space=\"view\"] The coordinate system the DirLight is defined in - ````\"view\"```` or ````\"world\"````.\n     * @param {Boolean} [cfg.castsShadow=false] Flag which indicates if this DirLight casts a castsShadow.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._shadowRenderBuf = null;\n        this._shadowViewMatrix = null;\n        this._shadowProjMatrix = null;\n        this._shadowViewMatrixDirty = true;\n        this._shadowProjMatrixDirty = true;\n\n        const camera = this.scene.camera;\n        const canvas = this.scene.canvas;\n\n        this._onCameraViewMatrix = camera.on(\"viewMatrix\", () => {\n            this._shadowViewMatrixDirty = true;\n        });\n\n        this._onCameraProjMatrix = camera.on(\"projMatrix\", () => {\n            this._shadowProjMatrixDirty = true;\n        });\n\n        this._onCanvasBoundary = canvas.on(\"boundary\", () => {\n            this._shadowProjMatrixDirty = true;\n        });\n\n        this._state = new RenderState({\n\n            type: \"dir\",\n            dir: math.vec3([1.0, 1.0, 1.0]),\n            color: math.vec3([0.7, 0.7, 0.8]),\n            intensity: 1.0,\n            space: cfg.space || \"view\",\n            castsShadow: false,\n\n            getShadowViewMatrix: () => {\n                if (this._shadowViewMatrixDirty) {\n                    if (!this._shadowViewMatrix) {\n                        this._shadowViewMatrix = math.identityMat4();\n                    }\n                    const camera = this.scene.camera;\n                    const dir = this._state.dir;\n                    const look = camera.look;\n                    const eye = [look[0] - dir[0], look[1] - dir[1], look[2] - dir[2]];\n                    const up = [0, 1, 0];\n                    math.lookAtMat4v(eye, look, up, this._shadowViewMatrix);\n                    this._shadowViewMatrixDirty = false;\n                }\n                return this._shadowViewMatrix;\n            },\n\n            getShadowProjMatrix: () => {\n                if (this._shadowProjMatrixDirty) { // TODO: Set when canvas resizes\n                    if (!this._shadowProjMatrix) {\n                        this._shadowProjMatrix = math.identityMat4();\n                    }\n                    math.orthoMat4c(-40, 40, -40, 40, -40.0, 80, this._shadowProjMatrix);  // left, right, bottom, top, near, far, dest\n                    this._shadowProjMatrixDirty = false;\n                }\n                return this._shadowProjMatrix;\n            },\n\n            getShadowRenderBuf: () => {\n                if (!this._shadowRenderBuf) {\n                    this._shadowRenderBuf = new RenderBuffer(this.scene.canvas.gl); // Super old mobile devices have a limit of 1024x1024 textures\n                    this._shadowRenderBuf.setSize([1024, 1024]);\n                }\n                return this._shadowRenderBuf;\n            }\n        });\n\n        this.dir = cfg.dir;\n        this.color = cfg.color;\n        this.intensity = cfg.intensity;\n        this.castsShadow = cfg.castsShadow;\n\n        this.scene._lightCreated(this);\n    }\n\n    /**\n     * Sets the direction in which the DirLight is shining.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @param {Number[]} value The direction vector.\n     */\n    set dir(value) {\n        this._state.dir.set(value || [1.0, 1.0, 1.0]);\n        this._shadowViewMatrixDirty = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the direction in which the DirLight is shining.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @returns {Number[]} The direction vector.\n     */\n    get dir() {\n        return this._state.dir;\n    }\n\n    /**\n     * Sets the RGB color of this DirLight.\n     *\n     * Default value is ````[0.7, 0.7, 0.8]````.\n     *\n     * @param {Number[]} color The DirLight's RGB color.\n     */\n    set color(color) {\n        this._state.color.set(color || [0.7, 0.7, 0.8]);\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the RGB color of this DirLight.\n     *\n     * Default value is ````[0.7, 0.7, 0.8]````.\n     *\n     * @returns {Number[]} The DirLight's RGB color.\n     */\n    get color() {\n        return this._state.color;\n    }\n\n    /**\n     * Sets the intensity of this DirLight.\n     *\n     * Default intensity is ````1.0```` for maximum intensity.\n     *\n     * @param {Number} intensity The DirLight's intensity\n     */\n    set intensity(intensity) {\n        intensity = intensity !== undefined ? intensity : 1.0;\n        this._state.intensity = intensity;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the intensity of this DirLight.\n     *\n     * Default value is ````1.0```` for maximum intensity.\n     *\n     * @returns {Number} The DirLight's intensity.\n     */\n    get intensity() {\n        return this._state.intensity;\n    }\n\n    /**\n     * Sets if this DirLight casts a shadow.\n     *\n     * Default value is ````false````.\n     *\n     * @param {Boolean} castsShadow Set ````true```` to cast shadows.\n     */\n    set castsShadow(castsShadow) {\n        castsShadow = !!castsShadow;\n        if (this._state.castsShadow === castsShadow) {\n            return;\n        }\n        this._state.castsShadow = castsShadow;\n        this._shadowViewMatrixDirty = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this DirLight casts a shadow.\n     *\n     * Default value is ````false````.\n     *\n     * @returns {Boolean} ````true```` if this DirLight casts shadows.\n     */\n    get castsShadow() {\n        return this._state.castsShadow;\n    }\n\n    /**\n     * Destroys this DirLight.\n     */\n    destroy() {\n\n        const camera = this.scene.camera;\n        const canvas = this.scene.canvas;\n        camera.off(this._onCameraViewMatrix);\n        camera.off(this._onCameraProjMatrix);\n        canvas.off(this._onCanvasBoundary);\n\n        super.destroy();\n        this._state.destroy();\n        if (this._shadowRenderBuf) {\n            this._shadowRenderBuf.destroy();\n        }\n        this.scene._lightDestroyed(this);\n        this.glRedraw();\n    }\n}\n\n/**\n * A positional light source that originates from a single point and spreads outward in all directions, with optional attenuation over distance.\n *\n * * Has a position in {@link PointLight#pos}, but no direction.\n * * Defined in either *World* or *View* coordinate space. When in World-space, {@link PointLight#pos} is relative to\n * the World coordinate system, and will appear to move as the {@link Camera} moves. When in View-space,\n * {@link PointLight#pos} is relative to the View coordinate system, and will behave as if fixed to the viewer's head.\n * * Has {@link PointLight#constantAttenuation}, {@link PointLight#linearAttenuation} and {@link PointLight#quadraticAttenuation}\n * factors, which indicate how intensity attenuates over distance.\n * * {@link AmbientLight}s, {@link PointLight}s and {@link PointLight}s are registered by their {@link Component#id} on {@link Scene#lights}.\n *\n * ## Usage\n *\n * In the example below we'll replace the {@link Scene}'s default light sources with three World-space PointLights.\n *\n * [[Run this example](/examples/index.html#lights_PointLight_world)]\n *\n * ````javascript\n * import {Viewer, Mesh, buildSphereGeometry, buildPlaneGeometry,\n *      ReadableGeometry, PhongMaterial, Texture, PointLight} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer and arrange the camera\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * // Replace the Scene's default lights with three custom world-space PointLights\n *\n * viewer.scene.clearLights();\n *\n * new PointLight(viewer.scene,{\n *      id: \"keyLight\",\n *      pos: [-80, 60, 80],\n *      color: [1.0, 0.3, 0.3],\n *      intensity: 1.0,\n *      space: \"world\"\n * });\n *\n * new PointLight(viewer.scene,{\n *      id: \"fillLight\",\n *      pos: [80, 40, 40],\n *      color: [0.3, 1.0, 0.3],\n *      intensity: 1.0,\n *      space: \"world\"\n * });\n *\n * new PointLight(viewer.scene,{\n *      id: \"rimLight\",\n *      pos: [-20, 80, -80],\n *      color: [0.6, 0.6, 0.6],\n *      intensity: 1.0,\n *      space: \"world\"\n * });\n *\n * // Create a sphere and ground plane\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildSphereGeometry({\n *          radius: 1.3\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *          diffuse: [0.7, 0.7, 0.7],\n *          specular: [1.0, 1.0, 1.0],\n *          emissive: [0, 0, 0],\n *          alpha: 1.0,\n *          ambient: [1, 1, 0],\n *          diffuseMap: new Texture(viewer.scene, {\n *              src: \"textures/diffuse/uvGrid2.jpg\"\n *          })\n *      })\n * });\n *\n * new Mesh(viewer.scene, {\n *      geometry: buildPlaneGeometry(ReadableGeometry, viewer.scene, {\n *          xSize: 30,\n *          zSize: 30\n *      }),\n *      material: new PhongMaterial(viewer.scene, {\n *          diffuseMap: new Texture(viewer.scene, {\n *               src: \"textures/diffuse/uvGrid2.jpg\"\n *          }),\n *          backfaces: true\n *      }),\n *      position: [0, -2.1, 0]\n * });\n * ````\n */\nclass PointLight extends Light {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"PointLight\";\n    }\n\n    /**\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this PointLight as well.\n     * @param {*} [cfg] The PointLight configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number[]} [cfg.pos=[ 1.0, 1.0, 1.0 ]] Position, in either World or View space, depending on the value of the **space** parameter.\n     * @param {Number[]} [cfg.color=[0.7, 0.7, 0.8 ]] Color of this PointLight.\n     * @param {Number} [cfg.intensity=1.0] Intensity of this PointLight, as a factor in range ````[0..1]````.\n     * @param {Number} [cfg.constantAttenuation=0] Constant attenuation factor.\n     * @param {Number} [cfg.linearAttenuation=0] Linear attenuation factor.\n     * @param {Number} [cfg.quadraticAttenuation=0]Quadratic attenuation factor.\n     * @param {String} [cfg.space=\"view\"]The coordinate system this PointLight is defined in - \"view\" or \"world\".\n     * @param {Boolean} [cfg.castsShadow=false] Flag which indicates if this PointLight casts a castsShadow.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        const self = this;\n\n        this._shadowRenderBuf = null;\n        this._shadowViewMatrix = null;\n        this._shadowProjMatrix = null;\n        this._shadowViewMatrixDirty = true;\n        this._shadowProjMatrixDirty = true;\n\n        const camera = this.scene.camera;\n        const canvas = this.scene.canvas;\n\n        this._onCameraViewMatrix = camera.on(\"viewMatrix\", () => {\n            this._shadowViewMatrixDirty = true;\n        });\n\n        this._onCameraProjMatrix = camera.on(\"projMatrix\", () => {\n            this._shadowProjMatrixDirty = true;\n        });\n\n        this._onCanvasBoundary = canvas.on(\"boundary\", () => {\n            this._shadowProjMatrixDirty = true;\n        });\n\n        this._state = new RenderState({\n\n            type: \"point\",\n            pos: math.vec3([1.0, 1.0, 1.0]),\n            color: math.vec3([0.7, 0.7, 0.8]),\n            intensity: 1.0, attenuation: [0.0, 0.0, 0.0],\n            space: cfg.space || \"view\",\n            castsShadow: false,\n\n            getShadowViewMatrix: () => {\n                if (self._shadowViewMatrixDirty) {\n                    if (!self._shadowViewMatrix) {\n                        self._shadowViewMatrix = math.identityMat4();\n                    }\n                    const eye = self._state.pos;\n                    const look = camera.look;\n                    const up = camera.up;\n                    math.lookAtMat4v(eye, look, up, self._shadowViewMatrix);\n                    self._shadowViewMatrixDirty = false;\n                }\n                return self._shadowViewMatrix;\n            },\n\n            getShadowProjMatrix: () => {\n                if (self._shadowProjMatrixDirty) { // TODO: Set when canvas resizes\n                    if (!self._shadowProjMatrix) {\n                        self._shadowProjMatrix = math.identityMat4();\n                    }\n                    const canvas = self.scene.canvas.canvas;\n                    math.perspectiveMat4(70 * (Math.PI / 180.0), canvas.clientWidth / canvas.clientHeight, 0.1, 500.0, self._shadowProjMatrix);\n                    self._shadowProjMatrixDirty = false;\n                }\n                return self._shadowProjMatrix;\n            },\n\n            getShadowRenderBuf: () => {\n                if (!self._shadowRenderBuf) {\n                    self._shadowRenderBuf = new RenderBuffer(self.scene.canvas.gl); // Super old mobile devices have a limit of 1024x1024 textures\n                    self._shadowRenderBuf.setSize([1024, 1024]);\n                }\n                return self._shadowRenderBuf;\n            }\n        });\n\n        this.pos = cfg.pos;\n        this.color = cfg.color;\n        this.intensity = cfg.intensity;\n        this.constantAttenuation = cfg.constantAttenuation;\n        this.linearAttenuation = cfg.linearAttenuation;\n        this.quadraticAttenuation = cfg.quadraticAttenuation;\n        this.castsShadow = cfg.castsShadow;\n\n        this.scene._lightCreated(this);\n    }\n\n    /**\n     * Sets the position of this PointLight.\n     *\n     * This will be either World- or View-space, depending on the value of {@link PointLight#space}.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @param {Number[]} pos The position.\n     */\n    set pos(pos) {\n        this._state.pos.set(pos || [1.0, 1.0, 1.0]);\n        this._shadowViewMatrixDirty = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the position of this PointLight.\n     *\n     * This will be either World- or View-space, depending on the value of {@link PointLight#space}.\n     *\n     * Default value is ````[1.0, 1.0, 1.0]````.\n     *\n     * @returns {Number[]} The position.\n     */\n    get pos() {\n        return this._state.pos;\n    }\n\n    /**\n     * Sets the RGB color of this PointLight.\n     *\n     * Default value is ````[0.7, 0.7, 0.8]````.\n     *\n     * @param {Number[]} color The PointLight's RGB color.\n     */\n    set color(color) {\n        this._state.color.set(color || [0.7, 0.7, 0.8]);\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the RGB color of this PointLight.\n     *\n     * Default value is ````[0.7, 0.7, 0.8]````.\n     *\n     * @returns {Number[]} The PointLight's RGB color.\n     */\n    get color() {\n        return this._state.color;\n    }\n\n    /**\n     * Sets the intensity of this PointLight.\n     *\n     * Default intensity is ````1.0```` for maximum intensity.\n     *\n     * @param {Number} intensity The PointLight's intensity\n     */\n    set intensity(intensity) {\n        intensity = intensity !== undefined ? intensity : 1.0;\n        this._state.intensity = intensity;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the intensity of this PointLight.\n     *\n     * Default value is ````1.0```` for maximum intensity.\n     *\n     * @returns {Number} The PointLight's intensity.\n     */\n    get intensity() {\n        return this._state.intensity;\n    }\n\n    /**\n     * Sets the constant attenuation factor for this PointLight.\n     *\n     * Default value is ````0````.\n     *\n     * @param {Number} value The constant attenuation factor.\n     */\n    set constantAttenuation(value) {\n        this._state.attenuation[0] = value || 0.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the constant attenuation factor for this PointLight.\n     *\n     * Default value is ````0````.\n     *\n     * @returns {Number} The constant attenuation factor.\n     */\n    get constantAttenuation() {\n        return this._state.attenuation[0];\n    }\n\n    /**\n     * Sets the linear attenuation factor for this PointLight.\n     *\n     * Default value is ````0````.\n     *\n     * @param {Number} value The linear attenuation factor.\n     */\n    set linearAttenuation(value) {\n        this._state.attenuation[1] = value || 0.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the linear attenuation factor for this PointLight.\n     *\n     * Default value is ````0````.\n     *\n     * @returns {Number} The linear attenuation factor.\n     */\n    get linearAttenuation() {\n        return this._state.attenuation[1];\n    }\n\n    /**\n     * Sets the quadratic attenuation factor for this PointLight.\n     *\n     * Default value is ````0````.\n     *\n     * @param {Number} value The quadratic attenuation factor.\n     */\n    set quadraticAttenuation(value) {\n        this._state.attenuation[2] = value || 0.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the quadratic attenuation factor for this PointLight.\n     *\n     * Default value is ````0````.\n     *\n     * @returns {Number} The quadratic attenuation factor.\n     */\n    get quadraticAttenuation() {\n        return this._state.attenuation[2];\n    }\n\n    /**\n     * Sets if this PointLight casts a shadow.\n     *\n     * Default value is ````false````.\n     *\n     * @param {Boolean} castsShadow Set ````true```` to cast shadows.\n     */\n    set castsShadow(castsShadow) {\n        castsShadow = !!castsShadow;\n        if (this._state.castsShadow === castsShadow) {\n            return;\n        }\n        this._state.castsShadow = castsShadow;\n        this._shadowViewMatrixDirty = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if this PointLight casts a shadow.\n     *\n     * Default value is ````false````.\n     *\n     * @returns {Boolean} ````true```` if this PointLight casts shadows.\n     */\n    get castsShadow() {\n        return this._state.castsShadow;\n    }\n\n    /**\n     * Destroys this PointLight.\n     */\n    destroy() {\n\n        const camera = this.scene.camera;\n        const canvas = this.scene.canvas;\n        camera.off(this._onCameraViewMatrix);\n        camera.off(this._onCameraProjMatrix);\n        canvas.off(this._onCanvasBoundary);\n\n        super.destroy();\n\n        this._state.destroy();\n        if (this._shadowRenderBuf) {\n            this._shadowRenderBuf.destroy();\n        }\n        this.scene._lightDestroyed(this);\n        this.glRedraw();\n    }\n}\n\nfunction ensureImageSizePowerOfTwo(image) {\n    if (!isPowerOfTwo(image.width) || !isPowerOfTwo(image.height)) {\n        const canvas = document.createElement(\"canvas\");\n        canvas.width = nextHighestPowerOfTwo(image.width);\n        canvas.height = nextHighestPowerOfTwo(image.height);\n        const ctx = canvas.getContext(\"2d\");\n        ctx.drawImage(image,\n            0, 0, image.width, image.height,\n            0, 0, canvas.width, canvas.height);\n        image = canvas;\n    }\n    return image;\n}\n\nfunction isPowerOfTwo(x) {\n    return (x & (x - 1)) === 0;\n}\n\nfunction nextHighestPowerOfTwo(x) {\n    --x;\n    for (let i = 1; i < 32; i <<= 1) {\n        x = x | x >> i;\n    }\n    return x + 1;\n}\n\n/**\n * @desc A cube texture map.\n */\nclass CubeTexture extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"CubeTexture\";\n    }\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID for this CubeTexture, unique among all components in the parent scene, generated automatically when omitted.\n     * @param {String[]} [cfg.src=null]  Paths to six image files to load into this CubeTexture.\n     * @param {Boolean} [cfg.flipY=false] Flips this CubeTexture's source data along its vertical axis when true.\n     * @param {Number} [cfg.encoding=LinearEncoding] Encoding format. Supported values are {@link LinearEncoding} and {@link sRGBEncoding}.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        const gl = this.scene.canvas.gl;\n\n        this._state = new RenderState({\n            texture: new Texture2D({gl, target: gl.TEXTURE_CUBE_MAP}),\n            flipY: this._checkFlipY(cfg.minFilter),\n            encoding: this._checkEncoding(cfg.encoding),\n            minFilter: LinearMipmapLinearFilter,\n            magFilter: LinearFilter,\n            wrapS: ClampToEdgeWrapping,\n            wrapT: ClampToEdgeWrapping,\n            mipmaps: true\n        });\n\n        this._src = cfg.src;\n        this._images = [];\n\n        this._loadSrc(cfg.src);\n\n        stats.memory.textures++;\n    }\n\n    _checkFlipY(value) {\n        return !!value;\n    }\n\n    _checkEncoding(value) {\n        value = value || LinearEncoding;\n        if (value !== LinearEncoding && value !== sRGBEncoding) {\n            this.error(\"Unsupported value for 'encoding' - supported values are LinearEncoding and sRGBEncoding. Defaulting to LinearEncoding.\");\n            value = LinearEncoding;\n        }\n        return value;\n    }\n\n    _loadSrc(src) {\n        const self = this;\n        const gl = this.scene.canvas.gl;\n        this._images = [];\n        let loadFailed = false;\n        let numLoaded = 0;\n        for (let i = 0; i < src.length; i++) {\n            const image = new Image();\n            image.onload = (function () {\n                let _image = image;\n                const index = i;\n                return function () {\n                    if (loadFailed) {\n                        return;\n                    }\n                    _image = ensureImageSizePowerOfTwo(_image);\n                    self._images[index] = _image;\n                    numLoaded++;\n                    if (numLoaded === 6) {\n                        let texture = self._state.texture;\n                        if (!texture) {\n                            texture = new Texture2D({gl, target: gl.TEXTURE_CUBE_MAP});\n                            self._state.texture = texture;\n                        }\n                        texture.setImage(self._images, self._state);\n                        self.fire(\"loaded\", self._src, false);\n                        self.glRedraw();\n                    }\n                };\n            })();\n            image.onerror = function () {\n                loadFailed = true;\n            };\n            image.src = src[i];\n        }\n    }\n\n    /**\n     * Destroys this CubeTexture\n     *\n     */\n    destroy() {\n        super.destroy();\n        if (this._state.texture) {\n            this._state.texture.destroy();\n        }\n        stats.memory.textures--;\n        this._state.destroy();\n    }\n}\n\n/**\n * @desc A reflection cube map.\n *\n * ## Usage\n *\n * ````javascript\n * import {Viewer, Mesh, buildSphereGeometry,\n *      ReadableGeometry, MetallicMaterial, ReflectionMap} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer and arrange the camera\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * new ReflectionMap(viewer.scene, {\n *     src: [\n *         \"textures/reflect/Uffizi_Gallery/Uffizi_Gallery_Radiance_PX.png\",\n *         \"textures/reflect/Uffizi_Gallery/Uffizi_Gallery_Radiance_NX.png\",\n *         \"textures/reflect/Uffizi_Gallery/Uffizi_Gallery_Radiance_PY.png\",\n *         \"textures/reflect/Uffizi_Gallery/Uffizi_Gallery_Radiance_NY.png\",\n *         \"textures/reflect/Uffizi_Gallery/Uffizi_Gallery_Radiance_PZ.png\",\n *         \"textures/reflect/Uffizi_Gallery/Uffizi_Gallery_Radiance_NZ.png\"\n *     ]\n * });\n *\n * // Create a sphere and ground plane\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildSphereGeometry({\n *          radius: 2.0\n *      }),\n *      new MetallicMaterial(viewer.scene, {\n *          baseColor: [1, 1, 1],\n *          metallic: 1.0,\n *          roughness: 1.0\n *      })\n * });\n * ````\n */\nclass ReflectionMap extends CubeTexture {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"ReflectionMap\";\n    }\n\n    /**\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID for this ReflectionMap, unique among all components in the parent scene, generated automatically when omitted.\n     * @param {String[]} [cfg.src=null]  Paths to six image files to load into this ReflectionMap.\n     * @param {Boolean} [cfg.flipY=false] Flips this ReflectionMap's source data along its vertical axis when true.\n     * @param {Number} [cfg.encoding=LinearEncoding] Encoding format. Supported values are {@link LinearEncoding} and {@link sRGBEncoding}.\n     */\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n        this.scene._lightsState.addReflectionMap(this._state);\n        this.scene._reflectionMapCreated(this);\n    }\n\n    /**\n     * Destroys this ReflectionMap.\n     */\n    destroy() {\n        super.destroy();\n        this.scene._reflectionMapDestroyed(this);\n    }\n}\n\n/**\n * @desc A **LightMap** specifies a cube texture light map.\n *\n * ## Usage\n *\n * ````javascript\n * import {Viewer, Mesh, buildSphereGeometry,\n *      ReadableGeometry, MetallicMaterial, LightMap} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer and arrange the camera\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * new LightMap(viewer.scene, {\n *     src: [\n *         \"textures/light/Uffizi_Gallery/Uffizi_Gallery_Irradiance_PX.png\",\n *         \"textures/light/Uffizi_Gallery/Uffizi_Gallery_Irradiance_NX.png\",\n *         \"textures/light/Uffizi_Gallery/Uffizi_Gallery_Irradiance_PY.png\",\n *         \"textures/light/Uffizi_Gallery/Uffizi_Gallery_Irradiance_NY.png\",\n *         \"textures/light/Uffizi_Gallery/Uffizi_Gallery_Irradiance_PZ.png\",\n *         \"textures/light/Uffizi_Gallery/Uffizi_Gallery_Irradiance_NZ.png\"\n *     ]\n * });\n *\n * // Create a sphere and ground plane\n *\n * new Mesh(viewer.scene, {\n *      geometry: new ReadableGeometry(viewer.scene, buildSphereGeometry({\n *          radius: 2.0\n *      }),\n *      new MetallicMaterial(viewer.scene, {\n *          baseColor: [1, 1, 1],\n *          metallic: 1.0,\n *          roughness: 1.0\n *      })\n * });\n * ````\n */\nclass LightMap extends CubeTexture {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"LightMap\";\n    }\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID for this LightMap, unique among all components in the parent scene, generated automatically when omitted.\n     * @param {String:Object} [cfg.meta] Optional map of user-defined metadata to attach to this LightMap.\n     * @param {String[]} [cfg.src=null] Paths to six image files to load into this LightMap.\n     * @param {Boolean} [cfg.flipY=false] Flips this LightMap's source data along its vertical axis when true.\n     * @param {Number} [cfg.encoding=LinearEncoding] Encoding format. Supported values are {@link LinearEncoding} and {@link sRGBEncoding}.\n     */\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n        this.scene._lightMapCreated(this);\n    }\n\n    destroy() {\n        super.destroy();\n        this.scene._lightMapDestroyed(this);\n    }\n}\n\nconst tempVec4a$9 = math.vec4();\nconst tempVec4b$8 = math.vec4();\n\n\n/**\n * @desc Tracks the World, View and Canvas coordinates, and visibility, of a position within a {@link Scene}.\n *\n * ## Position\n *\n * A Marker holds its position in the World, View and Canvas coordinate systems in three properties:\n *\n * * {@link Marker#worldPos} holds the Marker's 3D World-space coordinates. This property can be dynamically updated. The Marker will fire a \"worldPos\" event whenever this property changes.\n * * {@link Marker#viewPos} holds the Marker's 3D View-space coordinates. This property is read-only, and is automatically updated from {@link Marker#worldPos} and the current {@link Camera} position. The Marker will fire a \"viewPos\" event whenever this property changes.\n * * {@link Marker#canvasPos} holds the Marker's 2D Canvas-space coordinates. This property is read-only, and is automatically updated from {@link Marker#canvasPos} and the current {@link Camera} position and projection. The Marker will fire a \"canvasPos\" event whenever this property changes.\n *\n * ## Visibility\n *\n * {@link Marker#visible} indicates if the Marker is currently visible. The Marker will fire a \"visible\" event whenever {@link Marker#visible} changes.\n *\n * This property will be ````false```` when:\n *\n * * {@link Marker#entity} is set to an {@link Entity}, and {@link Entity#visible} is ````false````,\n * * {@link Marker#occludable} is ````true```` and the Marker is occluded by some {@link Entity} in the 3D view, or\n * * {@link Marker#canvasPos} is outside the boundary of the {@link Canvas}.\n *\n * ## Usage\n *\n * In the example below, we'll create a Marker that's associated with a {@link Mesh} (which a type of {@link Entity}).\n *\n * We'll configure our Marker to\n * become invisible whenever it's occluded by any Entities in the canvas.\n *\n * We'll also demonstrate how to query the Marker's visibility status and position (in the World, View and\n * Canvas coordinate systems), and how to subscribe to change events on those properties.\n *\n * ````javascript\n * import {Viewer, GLTFLoaderPlugin, Marker} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * // Create the torus Mesh\n * // Recall that a Mesh is an Entity\n * new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildTorusGeometry({\n *         center: [0,0,0],\n *         radius: 1.0,\n *         tube: 0.5,\n *         radialSegments: 32,\n *         tubeSegments: 24,\n *         arc: Math.PI * 2.0\n *     }),\n *     material: new PhongMaterial(viewer.scene, {\n *         diffuseMap: new Texture(viewer.scene, {\n *             src: \"textures/diffuse/uvGrid2.jpg\"\n *         }),\n *         backfaces: true\n *     })\n * });\n *\n * // Create the Marker, associated with our Mesh Entity\n * const myMarker = new Marker(viewer, {\n *      entity: entity,\n *      worldPos: [10,0,0],\n *      occludable: true\n * });\n *\n * // Get the Marker's current World, View and Canvas coordinates\n * const worldPos   = myMarker.worldPos;     // 3D World-space position\n * const viewPos    = myMarker.viewPos;      // 3D View-space position\n * const canvasPos  = myMarker.canvasPos;    // 2D Canvas-space position\n *\n * const visible = myMarker.visible;\n *\n * // Listen for change of the Marker's 3D World-space position\n * myMarker.on(\"worldPos\", function(worldPos) {\n *    //...\n * });\n *\n * // Listen for change of the Marker's 3D View-space position, which happens\n * // when either worldPos was updated or the Camera was moved\n * myMarker.on(\"viewPos\", function(viewPos) {\n *    //...\n * });\n *\n * // Listen for change of the Marker's 2D Canvas-space position, which happens\n * // when worldPos or viewPos was updated, or Camera's projection was updated\n * myMarker.on(\"canvasPos\", function(canvasPos) {\n *    //...\n * });\n *\n * // Listen for change of Marker visibility. The Marker becomes invisible when it falls outside the canvas,\n * // has an Entity that is also invisible, or when an Entity occludes the Marker's position in the 3D view.\n * myMarker.on(\"visible\", function(visible) { // Marker visibility has changed\n *    if (visible) {\n *        this.log(\"Marker is visible\");\n *    } else {\n *        this.log(\"Marker is invisible\");\n *    }\n * });\n *\n * // Listen for destruction of Marker\n * myMarker.on(\"destroyed\", () => {\n *      //...\n * });\n * ````\n */\nclass Marker extends Component {\n\n    /**\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this Marker as well.\n     * @param {*} [cfg]  Marker configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Entity} [cfg.entity] Entity to associate this Marker with. When the Marker has an Entity, then {@link Marker#visible} will always be ````false```` if {@link Entity#visible} is false.\n     * @param {Boolean} [cfg.occludable=false] Indicates whether or not this Marker is hidden (ie. {@link Marker#visible} is ````false```` whenever occluded by {@link Entity}s in the {@link Scene}.\n     * @param {Number[]} [cfg.worldPos=[0,0,0]] World-space 3D Marker position.\n     */\n    constructor(owner, cfg) {\n\n        super(owner, cfg);\n\n        this._entity = null;\n        this._visible = null;\n        this._worldPos = math.vec3();\n        this._origin = math.vec3();\n        this._rtcPos = math.vec3();\n        this._viewPos = math.vec3();\n        this._canvasPos = math.vec2();\n        this._occludable = false;\n\n        this._onCameraViewMatrix = this.scene.camera.on(\"matrix\", () => {\n            this._viewPosDirty = true;\n            this._needUpdate();\n        });\n\n        this._onCameraProjMatrix = this.scene.camera.on(\"projMatrix\", () => {\n            this._canvasPosDirty = true;\n            this._needUpdate();\n        });\n\n        this._onEntityDestroyed = null;\n        this._onEntityModelDestroyed = null;\n\n        this._renderer.addMarker(this);\n\n        this.entity = cfg.entity;\n        this.worldPos = cfg.worldPos;\n        this.occludable = cfg.occludable;\n    }\n\n    _update() { // this._needUpdate() schedules this for next tick\n        if (this._viewPosDirty) {\n            math.transformPoint3(this.scene.camera.viewMatrix, this._worldPos, this._viewPos);\n            this._viewPosDirty = false;\n            this._canvasPosDirty = true;\n            this.fire(\"viewPos\", this._viewPos);\n        }\n        if (this._canvasPosDirty) {\n            tempVec4a$9.set(this._viewPos);\n            tempVec4a$9[3] = 1.0;\n            math.transformPoint4(this.scene.camera.projMatrix, tempVec4a$9, tempVec4b$8);\n            const aabb = this.scene.canvas.boundary;\n            this._canvasPos[0] = Math.floor((1 + tempVec4b$8[0] / tempVec4b$8[3]) * aabb[2] / 2);\n            this._canvasPos[1] = Math.floor((1 - tempVec4b$8[1] / tempVec4b$8[3]) * aabb[3] / 2);\n            this._canvasPosDirty = false;\n            this.fire(\"canvasPos\", this._canvasPos);\n        }\n    }\n\n    _setVisible(visible) { // Called by VisibilityTester and this._entity.on(\"destroyed\"..)\n        if (this._visible === visible) ;\n        this._visible = visible;\n        this.fire(\"visible\", this._visible);\n    }\n\n    /**\n     * Sets the {@link Entity} this Marker is associated with.\n     *\n     * An Entity is optional. When the Marker has an Entity, then {@link Marker#visible} will always be ````false````\n     * if {@link Entity#visible} is false.\n     *\n     * @type {Entity}\n     */\n    set entity(entity) {\n        if (this._entity === entity) {\n            return;\n        }\n        this._cleanupDestroyedHandlers();\n        this._entity = entity;\n        if (this._entity) {\n            if (this._entity.isSceneModelEntity) {\n                this._onEntityModelDestroyed = this._entity.model.on(\"destroyed\", () => { // SceneModelEntity does not fire events, and cannot exist beyond its VBOSceneModel\n                    this._entity = null; // Marker now may become visible, if it was synched to invisible Entity\n                    this._onEntityModelDestroyed = null;\n                });\n            } else {\n                this._onEntityDestroyed = this._entity.on(\"destroyed\", () => {\n                    this._entity = null;\n                    this._onEntityDestroyed = null;\n                });\n            }\n        }\n        this.fire(\"entity\", this._entity, true /* forget */);\n    }\n\n    /**\n     * Gets the {@link Entity} this Marker is associated with.\n     *\n     * @type {Entity}\n     */\n    get entity() {\n        return this._entity;\n    }\n\n    /**\n     * Sets whether occlusion testing is performed for this Marker.\n     *\n     * When this is ````true````, then {@link Marker#visible} will be ````false```` whenever the Marker is occluded by an {@link Entity} in the 3D view.\n     *\n     * The {@link Scene} periodically occlusion-tests all Markers on every 20th \"tick\" (which represents a rendered frame). We\n     * can adjust that frequency via property {@link Scene#ticksPerOcclusionTest}.\n     *\n     * @type {Boolean}\n     */\n    set occludable(occludable) {\n        occludable = !!occludable;\n        if (occludable === this._occludable) {\n            return;\n        }\n        this._occludable = occludable;\n        if (this._occludable) {\n            this._renderer.markerWorldPosUpdated(this);\n        }\n    }\n\n    /**\n     * Gets whether occlusion testing is performed for this Marker.\n     *\n     * When this is ````true````, then {@link Marker#visible} will be ````false```` whenever the Marker is occluded by an {@link Entity} in the 3D view.\n     *\n     * @type {Boolean}\n     */\n    get occludable() {\n        return this._occludable;\n    }\n\n    /**\n     * Sets the World-space 3D position of this Marker.\n     *\n     * Fires a \"worldPos\" event with new World position.\n     *\n     * @type {Number[]}\n     */\n    set worldPos(worldPos) {\n        this._worldPos.set(worldPos || [0, 0, 0]);\n        worldToRTCPos(this._worldPos, this._origin, this._rtcPos);\n        if (this._occludable) {\n            this._renderer.markerWorldPosUpdated(this);\n        }\n        this._viewPosDirty = true;\n        this.fire(\"worldPos\", this._worldPos);\n        this._needUpdate();\n    }\n\n    /**\n     * Gets the World-space 3D position of this Marker.\n     *\n     * @type {Number[]}\n     */\n    get worldPos() {\n        return this._worldPos;\n    }\n\n    /**\n     * Gets the RTC center of this Marker.\n     *\n     * This is automatically calculated from {@link Marker#worldPos}.\n     *\n     * @type {Number[]}\n     */\n    get origin() {\n        return this._origin;\n    }\n\n    /**\n     * Gets the RTC position of this Marker.\n     *\n     * This is automatically calculated from {@link Marker#worldPos}.\n     *\n     * @type {Number[]}\n     */\n    get rtcPos() {\n        return this._rtcPos;\n    }\n\n    /**\n     * View-space 3D coordinates of this Marker.\n     *\n     * This property is read-only and is automatically calculated from {@link Marker#worldPos} and the current {@link Camera} position.\n     *\n     * The Marker fires a \"viewPos\" event whenever this property changes.\n     *\n     * @type {Number[]}\n     * @final\n     */\n    get viewPos() {\n        this._update();\n        return this._viewPos;\n    }\n\n    /**\n     * Canvas-space 2D coordinates of this Marker.\n     *\n     * This property is read-only and is automatically calculated from {@link Marker#worldPos} and the current {@link Camera} position and projection.\n     *\n     * The Marker fires a \"canvasPos\" event whenever this property changes.\n     *\n     * @type {Number[]}\n     * @final\n     */\n    get canvasPos() {\n        this._update();\n        return this._canvasPos;\n    }\n\n    /**\n     * Indicates if this Marker is currently visible.\n     *\n     * This is read-only and is automatically calculated.\n     *\n     * The Marker is **invisible** whenever:\n     *\n     * * {@link Marker#canvasPos} is currently outside the canvas,\n     * * {@link Marker#entity} is set to an {@link Entity} that has {@link Entity#visible} ````false````, or\n     * * or {@link Marker#occludable} is ````true```` and the Marker is currently occluded by an Entity in the 3D view.\n     *\n     * The Marker fires a \"visible\" event whenever this property changes.\n     *\n     * @type {Boolean}\n     * @final\n     */\n    get visible() {\n        return !!this._visible;\n    }\n\n    /**\n     * Destroys this Marker.\n     */\n    destroy() {\n        this.fire(\"destroyed\", true);\n        this.scene.camera.off(this._onCameraViewMatrix);\n        this.scene.camera.off(this._onCameraProjMatrix);\n        this._cleanupDestroyedHandlers();\n        this._renderer.removeMarker(this);\n        super.destroy();\n    }\n\n    _cleanupDestroyedHandlers() {\n        if (this._entity) {\n            if (this._onEntityDestroyed !== null) {\n                if (this._entity.model) {\n                    this._entity.model.off(this._onEntityDestroyed);\n                } else {\n                    this._entity.off(this._onEntityDestroyed);\n                }\n                this._onEntityDestroyed = null;\n            }\n            if (this._onEntityModelDestroyed !== null) {\n                if (this._entity.model) {\n                    this._entity.model.off(this._onEntityModelDestroyed);\n                }\n                this._onEntityModelDestroyed = null;\n            }\n        }\n    }\n}\n\n/**\n * A {@link Marker} with a billboarded and textured quad attached to it.\n *\n * * Extends {@link Marker}\n * * Keeps the quad oriented towards the viewpoint\n * * Auto-fits the quad to the texture\n * * Has a world-space position\n * * Can be configured to hide the quad whenever the position is occluded by some other object\n *\n * ## Usage\n *\n * [[Run this example](/examples/index.html#markers_SpriteMarker)]\n *\n * ```` javascript\n * import {Viewer, SpriteMarker } from \"./https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/xeokit-sdk.es.min.js\";\n *\n * const viewer = new Viewer({\n *        canvasId: \"myCanvas\",\n *      transparent: true\n *  });\n *\n * viewer.scene.camera.eye = [0, 0, 25];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * new SpriteMarker(viewer.scene, {\n *      worldPos: [-10, 0, 0],\n *      src: \"../assets/textures/diffuse/uvGrid2_512x1024.jpg\",\n *      size: 5,\n *      occludable: false\n *  });\n *\n * new SpriteMarker(viewer.scene, {\n *      worldPos: [+10, 0, 0],\n *      src: \"../assets/textures/diffuse/uvGrid2_1024x512.jpg\",\n *      size: 4,\n *      occludable: false\n *  });\n *````\n */\nclass SpriteMarker extends Marker {\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this SpriteMarker as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID for this SpriteMarker, unique among all components in the parent scene, generated automatically when omitted.\n     * @param {Entity} [cfg.entity] Entity to associate this Marker with. When the SpriteMarker has an Entity, then {@link Marker#visible} will always be ````false```` if {@link Entity#visible} is false.\n     * @param {Boolean} [cfg.occludable=false] Indicates whether or not this Marker is hidden (ie. {@link Marker#visible} is ````false```` whenever occluded by {@link Entity}s in the {@link Scene}.\n     * @param {Number[]} [cfg.worldPos=[0,0,0]] World-space 3D Marker position.\n     * @param {String} [cfg.src=null] Path to image file to load into this SpriteMarker. See the {@link SpriteMarker#src} property for more info.\n     * @param {HTMLImageElement} [cfg.image=null] HTML Image object to load into this SpriteMarker. See the {@link SpriteMarker#image} property for more info.\n     * @param {Boolean} [cfg.flipY=false] Flips this SpriteMarker's texture image along its vertical axis when true.\n     * @param  {String} [cfg.encoding=\"linear\"] Texture encoding format.  See the {@link Texture#encoding} property for more info.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, {\n            entity: cfg.entity,\n            occludable: cfg.occludable,\n            worldPos: cfg.worldPos\n        });\n\n        this._occluded = false;\n        this._visible = true;\n        this._src = null;\n        this._image = null;\n        this._pos = math.vec3();\n        this._origin = math.vec3();\n        this._rtcPos = math.vec3();\n        this._dir = math.vec3();\n        this._size = 1.0;\n        this._imageSize = math.vec2();\n\n        this._texture = new Texture(this, {\n            src: cfg.src\n        });\n\n        this._geometry = new ReadableGeometry(this, {\n            primitive: \"triangles\",\n            positions: [3, 3, 0, -3, 3, 0, -3, -3, 0, 3, -3, 0],\n            normals: [-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0],\n            uv: [1, -1, 0, -1, 0, 0, 1, 0],\n            indices: [0, 1, 2, 0, 2, 3] // Ensure these will be front-faces\n        });\n\n        this._mesh = new Mesh(this, {\n            geometry: this._geometry,\n            material: new PhongMaterial(this, {\n                ambient: [0.9, 0.3, 0.9],\n                shininess: 30,\n                diffuseMap: this._texture,\n                backfaces: true\n            }),\n            scale: [1, 1, 1], // Note: by design, scale does not work with billboard\n            position: cfg.worldPos,\n            rotation: [90, 0, 0],\n            billboard: \"spherical\",\n            occluder: false // Don't occlude SpriteMarkers or Annotations\n        });\n\n        this.visible = true;\n        this.collidable = cfg.collidable;\n        this.clippable = cfg.clippable;\n        this.pickable = cfg.pickable;\n        this.opacity = cfg.opacity;\n        this.size = cfg.size;\n\n        if (cfg.image) {\n            this.image = cfg.image;\n        } else {\n            this.src = cfg.src;\n        }\n    }\n\n    _setVisible(visible) { // Called by VisibilityTester and this._entity.on(\"destroyed\"..)\n        this._occluded = (!visible);\n        this._mesh.visible = this._visible && (!this._occluded);\n        super._setVisible(visible);\n    }\n\n    /**\n     * Sets if this ````SpriteMarker```` is visible or not.\n     *\n     * Default value is ````true````.\n     *\n     * @param {Boolean} visible Set ````true```` to make this ````SpriteMarker```` visible.\n     */\n    set visible(visible) {\n        this._visible = (visible === null || visible === undefined) ? true : visible;\n        this._mesh.visible = this._visible && (!this._occluded);\n    }\n\n    /**\n     * Gets if this ````SpriteMarker```` is visible or not.\n     *\n     * Default value is ````true````.\n     *\n     * @returns {Boolean} Returns ````true```` if visible.\n     */\n    get visible() {\n        return this._visible;\n    }\n\n    /**\n     * Sets an ````HTMLImageElement```` to source the image from.\n     *\n     * Sets {@link Texture#src} null.\n     *\n     * @type {HTMLImageElement}\n     */\n    set image(image) {\n        this._image = image;\n        if (this._image) {\n            this._imageSize[0] = this._image.width;\n            this._imageSize[1] = this._image.height;\n            this._updatePlaneSizeFromImage();\n            this._src = null;\n            this._texture.image = this._image;\n        }\n    }\n\n    /**\n     * Gets the ````HTMLImageElement```` the ````SpriteMarker````'s image is sourced from, if set.\n     *\n     * Returns null if not set.\n     *\n     * @type {HTMLImageElement}\n     */\n    get image() {\n        return this._image;\n    }\n\n    /**\n     * Sets an image file path that the ````SpriteMarker````'s image is sourced from.\n     *\n     * Accepted file types are PNG and JPEG.\n     *\n     * Sets {@link Texture#image} null.\n     *\n     * @type {String}\n     */\n    set src(src) {\n        this._src = src;\n        if (this._src) {\n            this._image = null;\n            const image = new Image();\n            image.onload = () => {\n                this._texture.image = image;\n                this._imageSize[0] = image.width;\n                this._imageSize[1] = image.height;\n                this._updatePlaneSizeFromImage();\n            };\n            image.src = this._src;\n        }\n    }\n\n    /**\n     * Gets the image file path that the ````SpriteMarker````'s image is sourced from, if set.\n     *\n     * Returns null if not set.\n     *\n     * @type {String}\n     */\n    get src() {\n        return this._src;\n    }\n\n    /**\n     * Sets the World-space size of the longest edge of the ````SpriteMarker````.\n     *\n     * Note that ````SpriteMarker```` sets its aspect ratio to match its image. If we set a value of ````1000````, and\n     * the image has size ````400x300````, then the ````SpriteMarker```` will then have size ````1000 x 750````.\n     *\n     * Default value is ````1.0````.\n     *\n     * @param {Number} size New World-space size of the ````SpriteMarker````.\n     */\n    set size(size) {\n        this._size = (size === undefined || size === null) ? 1.0 : size;\n        if (this._image) {\n            this._updatePlaneSizeFromImage();\n        }\n    }\n\n    /**\n     * Gets the World-space size of the longest edge of the ````SpriteMarker````.\n     *\n     * Returns {Number} World-space size of the ````SpriteMarker````.\n     */\n    get size() {\n        return this._size;\n    }\n\n    /**\n     * Sets if this ````SpriteMarker```` is included in boundary calculations.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set collidable(value) {\n        this._mesh.collidable = (value !== false);\n    }\n\n    /**\n     * Gets if this ````SpriteMarker```` is included in boundary calculations.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get collidable() {\n        return this._mesh.collidable;\n    }\n\n    /**\n     * Sets if this ````SpriteMarker```` is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set clippable(value) {\n        this._mesh.clippable = (value !== false);\n    }\n\n    /**\n     * Gets if this ````SpriteMarker````  is clippable.\n     *\n     * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get clippable() {\n        return this._mesh.clippable;\n    }\n\n    /**\n     * Sets if this ````SpriteMarker```` is pickable.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set pickable(value) {\n        this._mesh.pickable = (value !== false);\n    }\n\n    /**\n     * Gets if this ````SpriteMarker````  is pickable.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get pickable() {\n        return this._mesh.pickable;\n    }\n\n    /**\n     * Sets the opacity factor for this ````SpriteMarker````.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    set opacity(opacity) {\n        this._mesh.opacity = opacity;\n    }\n\n    /**\n     * Gets this ````SpriteMarker````'s opacity factor.\n     *\n     * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.\n     *\n     * @type {Number}\n     */\n    get opacity() {\n        return this._mesh.opacity;\n    }\n\n    _updatePlaneSizeFromImage() {\n        const halfSize = this._size * 0.5;\n        const width = this._imageSize[0];\n        const height = this._imageSize[1];\n        const aspect = height / width;\n        if (width > height) {\n            this._geometry.positions = [\n                halfSize, halfSize * aspect, 0,\n                -halfSize, halfSize * aspect, 0,\n                -halfSize, -halfSize * aspect, 0,\n                halfSize, -halfSize * aspect, 0\n            ];\n        } else {\n            this._geometry.positions = [\n                halfSize / aspect, halfSize, 0,\n                -halfSize / aspect, halfSize, 0,\n                -halfSize / aspect, -halfSize, 0,\n                halfSize / aspect, -halfSize, 0\n            ];\n        }\n    }\n}\n\n/**\n * @desc Saves and restores the state of a {@link Scene}'s {@link Camera}.\n *\n * ## See Also\n *\n * * {@link ModelMemento} - Saves and restores a snapshot of the visual state of the {@link Entity}'s of a model within a {@link Scene}.\n * * {@link ObjectsMemento} - Saves and restores a snapshot of the visual state of the {@link Entity}'s that represent objects within a {@link Scene}.\n *\n * ## Usage\n *\n * In the example below, we'll create a {@link Viewer} and use an {@link XKTLoaderPlugin} to load an ````.xkt```` model. When the model has loaded, we'll save a snapshot of the {@link Camera} state in an CameraMemento. Then we'll move the Camera, and then we'll restore its original state again from the CameraMemento.\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, CameraMemento} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * // Load a model\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/xkt/schependomlaan/schependomlaan.xkt\"\n * });\n *\n * // Set camera\n * viewer.camera.eye = [-2.56, 8.38, 8.27];\n * viewer.camera.look = [13.44, 3.31, -14.83];\n * viewer.camera.up = [0.10, 0.98, -0.14];\n *\n * model.on(\"loaded\", () => {\n *\n *      // Model has loaded\n *\n *      // Save memento of camera state\n *      const cameraMemento = new CameraMemento();\n *\n *      cameraMemento.saveCamera(viewer.scene);\n *\n *      // Move the camera\n *      viewer.camera.eye = [45.3, 2.00, 5.13];\n *      viewer.camera.look = [0.0, 5.5, 10.0];\n *      viewer.camera.up = [0.10, 0.98, -0.14];\n *\n *      // Restore the camera state again\n *      objectsMemento.restoreCamera(viewer.scene);\n * });\n * ````\n */\nclass CameraMemento {\n\n    /**\n     * Creates a CameraState.\n     *\n     * @param {Scene} [scene] When given, immediately saves the state of the given {@link Scene}'s {@link Camera}.\n     */\n    constructor(scene) {\n\n        /** @private */\n        this._eye = math.vec3();\n\n        /** @private */\n        this._look = math.vec3();\n\n        /** @private */\n        this._up = math.vec3();\n\n        /** @private */\n        this._projection = {};\n\n        if (scene) {\n            this.saveCamera(scene);\n        }\n    }\n\n    /**\n     * Saves the state of the given {@link Scene}'s {@link Camera}.\n     *\n     * @param {Scene} scene The scene that contains the {@link Camera}.\n     */\n    saveCamera(scene) {\n\n        const camera = scene.camera;\n        const project = camera.project;\n\n        this._eye.set(camera.eye);\n        this._look.set(camera.look);\n        this._up.set(camera.up);\n\n        switch (camera.projection) {\n\n            case \"perspective\":\n                this._projection = {\n                    projection: \"perspective\",\n                    fov: project.fov,\n                    fovAxis: project.fovAxis,\n                    near: project.near,\n                    far: project.far\n                };\n                break;\n\n            case \"ortho\":\n                this._projection = {\n                    projection: \"ortho\",\n                    scale: project.scale,\n                    near: project.near,\n                    far: project.far\n                };\n                break;\n\n            case \"frustum\":\n                this._projection = {\n                    projection: \"frustum\",\n                    left: project.left,\n                    right: project.right,\n                    top: project.top,\n                    bottom: project.bottom,\n                    near: project.near,\n                    far: project.far\n                };\n                break;\n\n            case \"custom\":\n                this._projection = {\n                    projection: \"custom\",\n                    matrix: project.matrix.slice()\n                };\n                break;\n        }\n    }\n\n    /**\n     * Restores a {@link Scene}'s {@link Camera} to the state previously captured with {@link CameraMemento#saveCamera}.\n     *\n     * @param {Scene} scene The scene.\n     * @param {Function} [done] When this callback is given, will fly the {@link Camera} to the saved state then fire the callback. Otherwise will just jump the Camera to the saved state.\n     */\n    restoreCamera(scene, done) {\n\n        const camera = scene.camera;\n        const savedProjection = this._projection;\n\n        function restoreProjection() {\n\n            switch (savedProjection.type) {\n\n                case \"perspective\":\n                    camera.perspective.fov = savedProjection.fov;\n                    camera.perspective.fovAxis = savedProjection.fovAxis;\n                    camera.perspective.near = savedProjection.near;\n                    camera.perspective.far = savedProjection.far;\n                    break;\n\n                case \"ortho\":\n                    camera.ortho.scale = savedProjection.scale;\n                    camera.ortho.near = savedProjection.near;\n                    camera.ortho.far = savedProjection.far;\n                    break;\n\n                case \"frustum\":\n                    camera.frustum.left = savedProjection.left;\n                    camera.frustum.right = savedProjection.right;\n                    camera.frustum.top = savedProjection.top;\n                    camera.frustum.bottom = savedProjection.bottom;\n                    camera.frustum.near = savedProjection.near;\n                    camera.frustum.far = savedProjection.far;\n                    break;\n\n                case \"custom\":\n                    camera.customProjection.matrix = savedProjection.matrix;\n                    break;\n            }\n        }\n\n        if (done) {\n            scene.viewer.cameraFlight.flyTo({\n                eye: this._eye,\n                look: this._look,\n                up: this._up,\n                orthoScale: savedProjection.scale,\n                projection: savedProjection.projection\n            }, () => {\n                restoreProjection();\n                done();\n            });\n        } else {\n            camera.eye = this._eye;\n            camera.look = this._look;\n            camera.up = this._up;\n            restoreProjection();\n            camera.projection = savedProjection.projection;\n        }\n    }\n}\n\nconst color$3 = math.vec3();\n\n/**\n * @desc Saves and restores a snapshot of the visual state of the {@link Entity}'s of a model within a {@link Scene}.\n *\n * ## Usage\n *\n * In the example below, we'll create a {@link Viewer} and use an {@link XKTLoaderPlugin} to load an ````.xkt```` model. When the model has loaded, we'll hide a couple of {@link Entity}s and save a snapshot of the visual states of all its Entitys in an ModelMemento. Then we'll show all the Entitys\n * again, and then we'll restore the visual states of all the Entitys again from the ModelMemento, which will hide those two Entitys again.\n *\n * ## See Also\n *\n * * {@link CameraMemento} - Saves and restores the state of a {@link Scene}'s {@link Camera}.\n * * {@link ObjectsMemento} - Saves and restores a snapshot of the visual state of the {@link Entity}'s that represent objects within a {@link Scene}.\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin,  ModelMemento} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * // Load a model\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/xkt/schependomlaan/schependomlaan.xkt\"\n * });\n *\n * model.on(\"loaded\", () => {\n *\n *      // Model has loaded\n *\n *      // Hide a couple of objects\n *      viewer.scene.objects[\"0u4wgLe6n0ABVaiXyikbkA\"].visible = false;\n *      viewer.scene.objects[\"3u4wgLe3n0AXVaiXyikbYO\"].visible = false;\n *\n *      // Save memento of all object states, which includes those two hidden objects\n *      const ModelMemento = new ModelMemento();\n *\n * const metaModel = viewer.metaScene.metaModels\n *      ModelMemento.saveObjects(viewer.scene);\n *\n *      // Show all objects\n *      viewer.scene.setObjectsVisible(viewer.scene.objectIds, true);\n *\n *      // Restore the objects states again, which involves hiding those two objects again\n *      ModelMemento.restoreObjects(viewer.scene);\n * });\n * `````\n *\n * ## Masking Saved State\n *\n * We can optionally supply a mask to focus what state we save and restore.\n *\n * For example, to save and restore only the {@link Entity#visible} and {@link Entity#clippable} states:\n *\n * ````javascript\n * ModelMemento.saveObjects(viewer.scene, {\n *     visible: true,\n *     clippable: true\n * });\n *\n * //...\n *\n * // Restore the objects states again\n * ModelMemento.restoreObjects(viewer.scene);\n * ````\n */\nclass ModelMemento {\n\n    /**\n     * Creates a ModelMemento.\n     *\n     * @param {MetaModel} [metaModel] When given, immediately saves the model's {@link Entity} states to this ModelMemento.\n     */\n    constructor(metaModel) {\n\n        /** @private */\n        this.objectsVisible = [];\n\n        /** @private */\n        this.objectsEdges = [];\n\n        /** @private */\n        this.objectsXrayed = [];\n\n        /** @private */\n        this.objectsHighlighted = [];\n\n        /** @private */\n        this.objectsSelected = [];\n\n        /** @private */\n        this.objectsClippable = [];\n\n        /** @private */\n        this.objectsPickable = [];\n\n        /** @private */\n        this.objectsColorize = [];\n\n        /** @private */\n        this.objectsOpacity = [];\n\n        /** @private */\n        this.numObjects = 0;\n\n        if (metaModel) {\n            const metaScene = metaModel.metaScene;\n            const scene = metaScene.scene;\n            this.saveObjects(scene, metaModel);\n        }\n    }\n\n    /**\n     * Saves a snapshot of the visual state of the {@link Entity}'s that represent objects within a model.\n     *\n     * @param {Scene} scene The scene.\n     * @param {MetaModel} metaModel Represents the model. Corresponds with an {@link Entity} that represents the model in the scene.\n     * @param {Object} [mask] Masks what state gets saved. Saves all state when not supplied.\n     * @param {boolean} [mask.visible] Saves {@link Entity#visible} values when ````true````.\n     * @param {boolean} [mask.visible] Saves {@link Entity#visible} values when ````true````.\n     * @param {boolean} [mask.edges] Saves {@link Entity#edges} values when ````true````.\n     * @param {boolean} [mask.xrayed] Saves {@link Entity#xrayed} values when ````true````.\n     * @param {boolean} [mask.highlighted] Saves {@link Entity#highlighted} values when ````true````.\n     * @param {boolean} [mask.selected] Saves {@link Entity#selected} values when ````true````.\n     * @param {boolean} [mask.clippable] Saves {@link Entity#clippable} values when ````true````.\n     * @param {boolean} [mask.pickable] Saves {@link Entity#pickable} values when ````true````.\n     * @param {boolean} [mask.colorize] Saves {@link Entity#colorize} values when ````true````.\n     * @param {boolean} [mask.opacity] Saves {@link Entity#opacity} values when ````true````.\n     */\n    saveObjects(scene, metaModel, mask) {\n\n        this.numObjects = 0;\n\n        this._mask = mask ? utils.apply(mask, {}) : null;\n\n        const visible = (!mask || mask.visible);\n        const edges = (!mask || mask.edges);\n        const xrayed = (!mask || mask.xrayed);\n        const highlighted = (!mask || mask.highlighted);\n        const selected = (!mask || mask.selected);\n        const clippable = (!mask || mask.clippable);\n        const pickable = (!mask || mask.pickable);\n        const colorize = (!mask || mask.colorize);\n        const opacity = (!mask || mask.opacity);\n\n        const metaObjects = metaModel.metaObjects;\n        const objects = scene.objects;\n\n        for (let i = 0, len = metaObjects.length; i < len; i++) {\n            const metaObject = metaObjects[i];\n            const objectId = metaObject.id;\n            const object = objects[objectId];\n            if (!object) {\n                continue;\n            }\n            if (visible) {\n                this.objectsVisible[i] = object.visible;\n            }\n            if (edges) {\n                this.objectsEdges[i] = object.edges;\n            }\n            if (xrayed) {\n                this.objectsXrayed[i] = object.xrayed;\n            }\n            if (highlighted) {\n                this.objectsHighlighted[i] = object.highlighted;\n            }\n            if (selected) {\n                this.objectsSelected[i] = object.selected;\n            }\n            if (clippable) {\n                this.objectsClippable[i] = object.clippable;\n            }\n            if (pickable) {\n                this.objectsPickable[i] = object.pickable;\n            }\n            if (colorize) {\n                const objectColor = object.colorize;\n                this.objectsColorize[i * 3 + 0] = objectColor[0];\n                this.objectsColorize[i * 3 + 1] = objectColor[1];\n                this.objectsColorize[i * 3 + 2] = objectColor[2];\n            }\n            if (opacity) {\n                this.objectsOpacity[i] = object.opacity;\n            }\n            this.numObjects++;\n        }\n    }\n\n    /**\n     * Restores a {@link Scene}'s {@link Entity}'s to their state previously captured with {@link ModelMemento#saveObjects}.\n     *\n     * Assumes that the model has not been destroyed or modified since saving.\n     *\n     * @param {Scene} scene The scene that was given to {@link ModelMemento#saveObjects}.\n     * @param {MetaModel} metaModel The metamodel that was given to {@link ModelMemento#saveObjects}.\n     */\n    restoreObjects(scene, metaModel) {\n\n        const mask = this._mask;\n\n        const visible = (!mask || mask.visible);\n        const edges = (!mask || mask.edges);\n        const xrayed = (!mask || mask.xrayed);\n        const highlighted = (!mask || mask.highlighted);\n        const selected = (!mask || mask.selected);\n        const clippable = (!mask || mask.clippable);\n        const pickable = (!mask || mask.pickable);\n        const colorize = (!mask || mask.colorize);\n        const opacity = (!mask || mask.opacity);\n\n        const metaObjects = metaModel.metaObjects;\n        const objects = scene.objects;\n\n        for (let i = 0, len = metaObjects.length; i < len; i++) {\n            const metaObject = metaObjects[i];\n            const objectId = metaObject.id;\n            const object = objects[objectId];\n            if (!object) {\n                continue;\n            }\n            if (visible) {\n                object.visible = this.objectsVisible[i];\n            }\n            if (edges) {\n                object.edges = this.objectsEdges[i];\n            }\n            if (xrayed) {\n                object.xrayed = this.objectsXrayed[i];\n            }\n            if (highlighted) {\n                object.highlighted = this.objectsHighlighted[i];\n            }\n            if (selected) {\n                object.selected = this.objectsSelected[i];\n            }\n            if (clippable) {\n                object.clippable = this.objectsClippable[i];\n            }\n            if (pickable) {\n                object.pickable = this.objectsPickable[i];\n            }\n            if (colorize) {\n                color$3[0] = this.objectsColorize[i * 3 + 0];\n                color$3[1] = this.objectsColorize[i * 3 + 1];\n                color$3[2] = this.objectsColorize[i * 3 + 2];\n                object.colorize = color$3;\n            }\n            if (opacity) {\n                object.opacity = this.objectsOpacity[i];\n            }\n        }\n    }\n}\n\nconst color$2 = math.vec3();\n\n/**\n * @desc Saves and restores a snapshot of the visual state of the {@link Entity}'s that represent objects within a {@link Scene}.\n *\n * * An Entity represents an object when {@link Entity#isObject} is ````true````.\n * * Each object-Entity is registered by {@link Entity#id} in {@link Scene#objects}.\n *\n * ## See Also\n *\n * * {@link CameraMemento} - Saves and restores the state of a {@link Scene}'s {@link Camera}.\n * * {@link ModelMemento} - Saves and restores a snapshot of the visual state of the {@link Entity}'s of a model within a {@link Scene}.\n *\n * ## Usage\n *\n * In the example below, we'll create a {@link Viewer} and use an {@link XKTLoaderPlugin} to load an ````.xkt```` model. When the model has loaded, we'll hide a couple of {@link Entity}s and save a snapshot of the visual states of all the Entitys in an ObjectsMemento. Then we'll show all the Entitys\n * again, and then we'll restore the visual states of all the Entitys again from the ObjectsMemento, which will hide those two Entitys again.\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, ObjectsMemento} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * // Load a model\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/xkt/schependomlaan/schependomlaan.xkt\"\n * });\n *\n * model.on(\"loaded\", () => {\n *\n *      // Model has loaded\n *\n *      // Hide a couple of objects\n *      viewer.scene.objects[\"0u4wgLe6n0ABVaiXyikbkA\"].visible = false;\n *      viewer.scene.objects[\"3u4wgLe3n0AXVaiXyikbYO\"].visible = false;\n *\n *      // Save memento of all object states, which includes those two hidden objects\n *      const objectsMemento = new ObjectsMemento();\n *\n *      objectsMemento.saveObjects(viewer.scene);\n *\n *      // Show all objects\n *      viewer.scene.setObjectsVisible(viewer.scene.objectIds, true);\n *\n *      // Restore the objects states again, which involves hiding those two objects again\n *      objectsMemento.restoreObjects(viewer.scene);\n * });\n * `````\n *\n * ## Masking Saved State\n *\n * We can optionally supply a mask to focus what state we save and restore.\n *\n * For example, to save and restore only the {@link Entity#visible} and {@link Entity#clippable} states:\n *\n * ````javascript\n * objectsMemento.saveObjects(viewer.scene, {\n *     visible: true,\n *     clippable: true\n * });\n *\n * //...\n *\n * // Restore the objects states again\n * objectsMemento.restoreObjects(viewer.scene);\n * ````\n */\nclass ObjectsMemento {\n\n    /**\n     * Creates an ObjectsMemento.\n     */\n    constructor() {\n\n        /** @private */\n        this.objectsVisible = [];\n\n        /** @private */\n        this.objectsEdges = [];\n\n        /** @private */\n        this.objectsXrayed = [];\n\n        /** @private */\n        this.objectsHighlighted = [];\n\n        /** @private */\n        this.objectsSelected = [];\n\n        /** @private */\n        this.objectsClippable = [];\n\n        /** @private */\n        this.objectsPickable = [];\n\n        /** @private */\n        this.objectsColorize = [];\n\n        /** @private */\n        this.objectsHasColorize = [];\n\n        /** @private */\n        this.objectsOpacity = [];\n\n        /** @private */\n        this.numObjects = 0;\n    }\n\n    /**\n     * Saves a snapshot of the visual state of the {@link Entity}'s that represent objects within a {@link Scene}.\n     *\n     * @param {Scene} scene The scene.\n     * @param {Object} [mask] Masks what state gets saved. Saves all state when not supplied.\n     * @param {boolean} [mask.visible] Saves {@link Entity#visible} values when ````true````.\n     * @param {boolean} [mask.visible] Saves {@link Entity#visible} values when ````true````.\n     * @param {boolean} [mask.edges] Saves {@link Entity#edges} values when ````true````.\n     * @param {boolean} [mask.xrayed] Saves {@link Entity#xrayed} values when ````true````.\n     * @param {boolean} [mask.highlighted] Saves {@link Entity#highlighted} values when ````true````.\n     * @param {boolean} [mask.selected] Saves {@link Entity#selected} values when ````true````.\n     * @param {boolean} [mask.clippable] Saves {@link Entity#clippable} values when ````true````.\n     * @param {boolean} [mask.pickable] Saves {@link Entity#pickable} values when ````true````.\n     * @param {boolean} [mask.colorize] Saves {@link Entity#colorize} values when ````true````.\n     * @param {boolean} [mask.opacity] Saves {@link Entity#opacity} values when ````true````.\n     */\n    saveObjects(scene, mask) {\n\n        this.numObjects = 0;\n\n        this._mask = mask ? utils.apply(mask, {}) : null;\n\n        const objects = scene.objects;\n        const visible = (!mask || mask.visible);\n        const edges = (!mask || mask.edges);\n        const xrayed = (!mask || mask.xrayed);\n        const highlighted = (!mask || mask.highlighted);\n        const selected = (!mask || mask.selected);\n        const clippable = (!mask || mask.clippable);\n        const pickable = (!mask || mask.pickable);\n        const colorize = (!mask || mask.colorize);\n        const opacity = (!mask || mask.opacity);\n\n        for (let objectId in objects) {\n            if (objects.hasOwnProperty(objectId)) {\n                const object = objects[objectId];\n                const i = this.numObjects;\n                if (visible) {\n                    this.objectsVisible[i] = object.visible;\n                }\n                if (edges) {\n                    this.objectsEdges[i] = object.edges;\n                }\n                if (xrayed) {\n                    this.objectsXrayed[i] = object.xrayed;\n                }\n                if (highlighted) {\n                    this.objectsHighlighted[i] = object.highlighted;\n                }\n                if (selected) {\n                    this.objectsSelected[i] = object.selected;\n                }\n                if (clippable) {\n                    this.objectsClippable[i] = object.clippable;\n                }\n                if (pickable) {\n                    this.objectsPickable[i] = object.pickable;\n                }\n                if (colorize) {\n                    const objectColor = object.colorize;\n                    if (objectColor) {\n                        this.objectsColorize[i * 3 + 0] = objectColor[0];\n                        this.objectsColorize[i * 3 + 1] = objectColor[1];\n                        this.objectsColorize[i * 3 + 2] = objectColor[2];\n                        this.objectsHasColorize[i] = true;\n                    } else {\n                        this.objectsHasColorize[i] = false;\n                    }\n                }\n                if (opacity) {\n                    this.objectsOpacity[i] = object.opacity;\n                }\n                this.numObjects++;\n            }\n        }\n    }\n\n    /**\n     * Restores a {@link Scene}'s {@link Entity}'s to their state previously captured with {@link ObjectsMemento#saveObjects}.\n     * @param {Scene} scene The scene.\n     */\n    restoreObjects(scene) {\n\n        const mask = this._mask;\n\n        const visible = (!mask || mask.visible);\n        const edges = (!mask || mask.edges);\n        const xrayed = (!mask || mask.xrayed);\n        const highlighted = (!mask || mask.highlighted);\n        const selected = (!mask || mask.selected);\n        const clippable = (!mask || mask.clippable);\n        const pickable = (!mask || mask.pickable);\n        const colorize = (!mask || mask.colorize);\n        const opacity = (!mask || mask.opacity);\n\n        var i = 0;\n\n        const objects = scene.objects;\n\n        for (let objectId in objects) {\n            if (objects.hasOwnProperty(objectId)) {\n                const object = objects[objectId];\n                if (visible) {\n                    object.visible = this.objectsVisible[i];\n                }\n                if (edges) {\n                    object.edges = this.objectsEdges[i];\n                }\n                if (xrayed) {\n                    object.xrayed = this.objectsXrayed[i];\n                }\n                if (highlighted) {\n                    object.highlighted = this.objectsHighlighted[i];\n                }\n                if (selected) {\n                    object.selected = this.objectsSelected[i];\n                }\n                if (clippable) {\n                    object.clippable = this.objectsClippable[i];\n                }\n                if (pickable) {\n                    object.pickable = this.objectsPickable[i];\n                }\n                if (colorize ) {\n                    if (this.objectsHasColorize[i]) {\n                        color$2[0] = this.objectsColorize[i * 3 + 0];\n                        color$2[1] = this.objectsColorize[i * 3 + 1];\n                        color$2[2] = this.objectsColorize[i * 3 + 2];\n                        object.colorize = color$2;\n                    } else {\n                        object.colorize = null;\n                    }\n                }\n                if (opacity) {\n                    object.opacity = this.objectsOpacity[i];\n                }\n                i++;\n            }\n        }\n    }\n}\n\n/**\n * @desc A {@link Curve} along which a 3D position can be animated.\n *\n * * As shown in the diagram below, a CubicBezierCurve is defined by four control points.\n * * You can sample a {@link CubicBezierCurve#point} and a {@link CubicBezierCurve#tangent} vector on a CubicBezierCurve for any given value of {@link CubicBezierCurve#t} in the range [0..1].\n * * When you set {@link CubicBezierCurve#t} on a CubicBezierCurve, its {@link CubicBezierCurve#point} and {@link CubicBezierCurve#tangent} properties will update accordingly.\n * * To build a complex path, you can combine an unlimited combination of CubicBezierCurves, {@link QuadraticBezierCurve}s and {@link SplineCurve}s into a {@link Path}.\n *\n * <br>\n * <img style=\"border:1px solid;\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/B%C3%A9zier_3_big.gif/240px-B%C3%A9zier_3_big.gif\"/>\n * <br>\n * [Cubic Bezier Curve from WikiPedia](https://en.wikipedia.org/wiki/B%C3%A9zier_curve)\n */\nclass CubicBezierCurve extends Curve {\n\n    /**\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this CubicBezierCurve as well.\n     * @param {*} [cfg] Configs\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number[]} [cfg.v0=[0,0,0]] The starting point.\n     * @param {Number[]} [cfg.v1=[0,0,0]] The first control point.\n     * @param {Number[]} [cfg.v2=[0,0,0]] The middle control point.\n     * @param {Number[]} [cfg.v3=[0,0,0]] The ending point.\n     * @param {Number} [cfg.t=0] Current position on this CubicBezierCurve, in range between 0..1.\n     */\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n        this.v0 = cfg.v0;\n        this.v1 = cfg.v1;\n        this.v2 = cfg.v2;\n        this.v3 = cfg.v3;\n        this.t = cfg.t;\n    }\n\n    /**\n     * Sets the starting point on this CubicBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````\n     *\n     * @param {Number[]} value The starting point.\n     */\n    set v0(value) {\n        this._v0 = value || math.vec3([0, 0, 0]);\n    }\n\n    /**\n     * Gets the starting point on this CubicBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````\n     *\n     * @returns {Number[]} The starting point.\n     */\n    get v0() {\n        return this._v0;\n    }\n\n    /**\n     * Sets the first control point on this CubicBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````\n     *\n     * @param {Number[]} value The first control point.\n     */\n    set v1(value) {\n        this._v1 = value || math.vec3([0, 0, 0]);\n    }\n\n    /**\n     * Gets the first control point on this CubicBezierCurve.\n     *\n     * Fires a {@link CubicBezierCurve#v1:event} event on change.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````\n     *\n     * @returns {Number[]} The first control point.\n     */\n    get v1() {\n        return this._v1;\n    }\n\n    /**\n     * Sets the second control point on this CubicBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````\n     *\n     * @param {Number[]} value The second control point.\n     */\n    set v2(value) {\n        this._v2 = value || math.vec3([0, 0, 0]);\n    }\n\n    /**\n     * Gets the second control point on this CubicBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````\n     *\n     * @returns {Number[]} The second control point.\n     */\n    get v2() {\n        return this._v2;\n    }\n\n    /**\n     * Sets the end point on this CubicBezierCurve.\n     *\n     * Fires a {@link CubicBezierCurve#v3:event} event on change.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````\n     *\n     * @param {Number[]} value The end point.\n     */\n    set v3(value) {\n        this.fire(\"v3\", this._v3 = value || math.vec3([0, 0, 0]));\n    }\n\n    /**\n     * Gets the end point on this CubicBezierCurve.\n     *\n     * Fires a {@link CubicBezierCurve#v3:event} event on change.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````\n     *\n     * @returns {Number[]} The end point.\n     */\n    get v3() {\n        return this._v3;\n    }\n\n    /**\n     * Sets the current position of progress along this CubicBezierCurve.\n     *\n     * Automatically clamps to range ````[0..1]````.\n     *\n     * @param {Number} value New progress time value.\n     */\n    set t(value) {\n        value = value || 0;\n        this._t = value < 0.0 ? 0.0 : (value > 1.0 ? 1.0 : value);\n    }\n\n    /**\n     * Gets the current position of progress along this CubicBezierCurve.\n     *\n     * @returns {Number} Current progress time value.\n     */\n    get t() {\n        return this._t;\n    }\n\n    /**\n     * Returns point on this CubicBezierCurve at the given position.\n     *\n     * @param {Number} t Position to get point at.\n     *\n     * @returns {Number[]} The point at the given position.\n     */\n    get point() {\n        return this.getPoint(this._t);\n    }\n\n    /**\n     * Returns point on this CubicBezierCurve at the given position.\n     *\n     * @param {Number} t Position to get point at.\n     *\n     * @returns {Number[]} The point at the given position.\n     */\n    getPoint(t) {\n\n        var vector = math.vec3();\n\n        vector[0] = math.b3(t, this._v0[0], this._v1[0], this._v2[0], this._v3[0]);\n        vector[1] = math.b3(t, this._v0[1], this._v1[1], this._v2[1], this._v3[1]);\n        vector[2] = math.b3(t, this._v0[2], this._v1[2], this._v2[2], this._v3[2]);\n\n        return vector;\n    }\n\n    getJSON() {\n        return {\n            v0: this._v0,\n            v1: this._v1,\n            v2: this._v2,\n            v3: this._v3,\n            t: this._t\n        };\n    }\n}\n\n/**\n * @desc A complex curved path constructed from various {@link Curve} subtypes.\n *\n * * A Path can be constructed from these {@link Curve} subtypes: {@link SplineCurve}, {@link CubicBezierCurve} and {@link QuadraticBezierCurve}.\n * * You can sample a {@link Path#point} and a {@link Curve#tangent} vector on a Path for any given value of {@link Path#t} in the range ````[0..1]````.\n * * When you set {@link Path#t} on a Path, its {@link Path#point} and {@link Curve#tangent} properties will update accordingly.\n */\nclass Path extends Curve {\n\n    /**\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this SectionPlane as well.\n     * @param {*} [cfg]  Path configuration\n     * @param {String} [cfg.id]  Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {String []} [cfg.paths=[]] IDs or instances of {{#crossLink \"path\"}}{{/crossLink}} subtypes to add to this Path.\n     * @param {Number} [cfg.t=0] Current position on this Path, in range between 0..1.\n     */\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n        this._cachedLengths = [];\n        this._dirty = true;\n        this._curves = []; // Array of child Curve components\n        this._t = 0;\n        this._dirtySubs = []; // Subscriptions to \"dirty\" events from child Curve components\n        this._destroyedSubs = []; // Subscriptions to \"destroyed\" events from child Curve components\n        this.curves = cfg.curves || [];    // Add initial curves\n        this.t = cfg.t; // Set initial progress\n    }\n\n    /**\n     * Adds a {@link Curve} to this Path.\n     *\n     * @param {Curve} curve The {@link Curve} to add.\n     */\n    addCurve(curve) {\n        this._curves.push(curve);\n        this._dirty = true;\n    }\n\n    /**\n     * Sets the {@link Curve}s in this Path.\n     *\n     * Default value is ````[]````.\n     *\n     * @param {{Array of Spline, Path, QuadraticBezierCurve or CubicBezierCurve}} value.\n     */\n    set curves(value) {\n\n        value = value || [];\n\n        var curve;\n        // Unsubscribe from events on old curves\n        var i;\n        var len;\n        for (i = 0, len = this._curves.length; i < len; i++) {\n            curve = this._curves[i];\n            curve.off(this._dirtySubs[i]);\n            curve.off(this._destroyedSubs[i]);\n        }\n\n        this._curves = [];\n        this._dirtySubs = [];\n        this._destroyedSubs = [];\n\n        var self = this;\n\n        function curveDirty() {\n            self._dirty = true;\n        }\n\n        function curveDestroyed() {\n            var id = this.id;\n            for (i = 0, len = self._curves.length; i < len; i++) {\n                if (self._curves[i].id === id) {\n                    self._curves = self._curves.slice(i, i + 1);\n                    self._dirtySubs = self._dirtySubs.slice(i, i + 1);\n                    self._destroyedSubs = self._destroyedSubs.slice(i, i + 1);\n                    self._dirty = true;\n                    return;\n                }\n            }\n        }\n\n        for (i = 0, len = value.length; i < len; i++) {\n            curve = value[i];\n            if (utils.isNumeric(curve) || utils.isString(curve)) {\n                // ID given for curve - find the curve component\n                var id = curve;\n                curve = this.scene.components[id];\n                if (!curve) {\n                    this.error(\"Component not found: \" + _inQuotes(id));\n                    continue;\n                }\n            }\n\n            var type = curve.type;\n\n            if (type !== \"xeokit.SplineCurve\" &&\n                type !== \"xeokit.Path\" &&\n                type !== \"xeokit.CubicBezierCurve\" &&\n                type !== \"xeokit.QuadraticBezierCurve\") {\n\n                this.error(\"Component \" + _inQuotes(curve.id)\n                    + \" is not a xeokit.SplineCurve, xeokit.Path or xeokit.QuadraticBezierCurve\");\n\n                continue;\n            }\n\n            this._curves.push(curve);\n            this._dirtySubs.push(curve.on(\"dirty\", curveDirty));\n            this._destroyedSubs.push(curve.once(\"destroyed\", curveDestroyed));\n        }\n\n        this._dirty = true;\n    }\n\n    /**\n     * Gets the {@link Curve}s in this Path.\n     *\n     * @returns {{Array of Spline, Path, QuadraticBezierCurve or CubicBezierCurve}} the {@link Curve}s in this path.\n     */\n    get curves() {\n        return this._curves;\n    }\n\n    /**\n     * Sets the current point of progress along this Path.\n     *\n     * Automatically clamps to range ````[0..1]````.\n     *\n     * Default value is ````0````.\n     *\n     * @param {Number} value The current point of progress.\n     */\n    set t(value) {\n        value = value || 0;\n        this._t = value < 0.0 ? 0.0 : (value > 1.0 ? 1.0 : value);\n    }\n\n    /**\n     * Gets the current point of progress along this Path.\n     *\n     * Default value is ````0````.\n     *\n     * @returns {Number} The current point of progress.\n     */\n    get t() {\n        return this._t;\n    }\n\n    /**\n     * Gets point on this Path corresponding to the current value of {@link Path#t}.\n     *\n     * @returns {Number[]} The point.\n     */\n    get point() {\n        return this.getPoint(this._t);\n    }\n\n    /**\n     * Length of this Path, which is the cumulative length of all {@link Curve}s currently in {@link Path#curves}.\n     *\n     * @return {Number} Length of this path.\n     */\n    get length() {\n        var lens = this._getCurveLengths();\n        return lens[lens.length - 1];\n    }\n\n    /**\n     * Gets a point on this Path corresponding to the given progress position.\n     *\n     * @param {Number} t Indicates point of progress along this curve, in the range [0..1].\n     * @returns {Number[]}\n     */\n    getPoint(t) {\n        var d = t * this.length;\n        var curveLengths = this._getCurveLengths();\n        var i = 0, diff, curve;\n        while (i < curveLengths.length) {\n            if (curveLengths[i] >= d) {\n                diff = curveLengths[i] - d;\n                curve = this._curves[i];\n                var u = 1 - diff / curve.length;\n                return curve.getPointAt(u);\n            }\n            i++;\n        }\n        return null;\n    }\n\n    _getCurveLengths() {\n        if (!this._dirty) {\n            return this._cachedLengths;\n        }\n        var lengths = [];\n        var sums = 0;\n        var i, il = this._curves.length;\n        for (i = 0; i < il; i++) {\n            sums += this._curves[i].length;\n            lengths.push(sums);\n\n        }\n        this._cachedLengths = lengths;\n        this._dirty = false;\n        return lengths;\n    }\n\n    _getJSON() {\n        var curveIds = [];\n        for (var i = 0, len = this._curves.length; i < len; i++) {\n            curveIds.push(this._curves[i].id);\n        }\n        return {\n            curves: curveIds,\n            t: this._t\n        };\n    }\n\n    /**\n     * Destroys this Path.\n     */\n    destroy() {\n        super.destroy();\n        var i;\n        var len;\n        var curve;\n        for (i = 0, len = this._curves.length; i < len; i++) {\n            curve = this._curves[i];\n            curve.off(this._dirtySubs[i]);\n            curve.off(this._destroyedSubs[i]);\n        }\n    }\n}\n\n/**\n * A **QuadraticBezierCurve** is a {@link Curve} along which a 3D position can be animated.\n *\n * * As shown in the diagram below, a QuadraticBezierCurve is defined by three control points\n * * You can sample a {@link QuadraticBezierCurve#point} and a {@link Curve#tangent} vector on a QuadraticBezierCurve for any given value of {@link QuadraticBezierCurve#t} in the range ````[0..1]````\n * * When you set {@link QuadraticBezierCurve#t} on a QuadraticBezierCurve, its {@link QuadraticBezierCurve#point} and {@link Curve#tangent} will update accordingly.\n * * To build a complex path, you can combine an unlimited combination of QuadraticBezierCurves, {@link CubicBezierCurve}s and {@link SplineCurve}s into a {@link Path}.</li>\n * <br>\n * <img style=\"border:1px solid;\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/B%C3%A9zier_2_big.gif/240px-B%C3%A9zier_2_big.gif\"/>\n * <br>\n * *[Quadratic Bezier Curve from WikiPedia](https://en.wikipedia.org/wiki/B%C3%A9zier_curve)*\n */\nclass QuadraticBezierCurve extends Curve {\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this MetallicMaterial as well.\n     * @param {*} [cfg] Configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {{#crossLink \"Scene\"}}Scene{{/crossLink}}, generated automatically when omitted.\n     * @param {Number[]} [cfg.v0=[0,0,0]] The starting point.\n     * @param {Number[]} [cfg.v1=[0,0,0]] The middle control point.\n     * @param {Number[]} [cfg.v2=[0,0,0]] The end point.\n     * @param {Number[]} [cfg.t=0] Current position on this QuadraticBezierCurve, in range between ````0..1````.\n     */\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n        this.v0 = cfg.v0;\n        this.v1 = cfg.v1;\n        this.v2 = cfg.v2;\n        this.t = cfg.t;\n    }\n\n    /**\n     * Sets the starting point on this QuadraticBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @param {Number[]} value New starting point.\n     */\n    set v0(value) {\n        this._v0 = value || math.vec3([0, 0, 0]);\n    }\n\n    /**\n     * Gets the starting point on this QuadraticBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @returns {Number[]} The starting point.\n     */\n    get v0() {\n        return this._v0;\n    }\n\n    /**\n     * Sets the middle control point on this QuadraticBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @param {Number[]} value New middle control point.\n     */\n    set v1(value) {\n        this._v1 = value || math.vec3([0, 0, 0]);\n    }\n\n    /**\n     * Gets the middle control point on this QuadraticBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @returns {Number[]} The middle control point.\n     */\n    get v1() {\n        return this._v1;\n    }\n\n    /**\n     * Sets the end point on this QuadraticBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @param {Number[]} value The new end point.\n     */\n    set v2(value) {\n        this._v2 = value || math.vec3([0, 0, 0]);\n    }\n\n    /**\n     * Gets the end point on this QuadraticBezierCurve.\n     *\n     * Default value is ````[0.0, 0.0, 0.0]````.\n     *\n     * @returns {Number[]} The end point.\n     */\n    get v2() {\n        return this._v2;\n    }\n\n    /**\n     * Sets the progress along this QuadraticBezierCurve.\n     *\n     * Automatically clamps to range [0..1].\n     *\n     * Default value is ````0````.\n     *\n     * @param {Number} value The new progress location.\n     */\n    set t(value) {\n        value = value || 0;\n        this._t = value < 0.0 ? 0.0 : (value > 1.0 ? 1.0 : value);\n    }\n\n    /**\n     * Gets the progress along this QuadraticBezierCurve.\n     *\n     * Default value is ````0````.\n     *\n     * @returns {Number} The current progress location.\n     */\n    get t() {\n        return this._t;\n    }\n\n    /**\n     Point on this QuadraticBezierCurve at position {@link QuadraticBezierCurve/t}.\n\n     @property point\n     @type {Number[]}\n     */\n    get point() {\n        return this.getPoint(this._t);\n    }\n\n    /**\n     * Returns the point on this QuadraticBezierCurve at the given position.\n     *\n     * @param {Number} t Position to get point at.\n     * @returns {Number[]} The point.\n     */\n    getPoint(t) {\n        var vector = math.vec3();\n        vector[0] = math.b2(t, this._v0[0], this._v1[0], this._v2[0]);\n        vector[1] = math.b2(t, this._v0[1], this._v1[1], this._v2[1]);\n        vector[2] = math.b2(t, this._v0[2], this._v1[2], this._v2[2]);\n        return vector;\n    }\n\n    getJSON() {\n        return {\n            v0: this._v0,\n            v1: this._v1,\n            v2: this._v2,\n            t: this._t\n        };\n    }\n}\n\n/**\n * @desc A high-performance model representation for efficient rendering and low memory usage.\n *\n * * PerformanceModel was replaced with {@link SceneModel} in ````xeokit-sdk v2.4````.\n * * PerformanceModel currently extends {@link SceneModel}, in order to maintain backward-compatibility until we remove PerformanceModel.\n * * See {@link SceneModel} for API details.\n *\n * @deprecated\n * @implements {Drawable}\n * @implements {Entity}\n * @extends {SceneModel}\n */\nclass PerformanceModel extends SceneModel {\n\n    /**\n     * See {@link VBOSceneModel} for details.\n     *\n     * @param owner\n     * @param cfg\n     */\n    constructor(owner, cfg = {}) {\n        super(owner, cfg);\n    }\n}\n\nconst tempVec3a$b = math.vec3();\nconst tempVec3b$8 = math.vec3();\nconst tempVec4a$8 = math.vec4();\nconst front = math.vec3([0,  0, -1]);\nconst back  = math.vec3([0,  0,  1]);\nconst up    = math.vec3([0,  1,  0]);\n\n/**\n *  @desc An arbitrarily-aligned World-space clipping plane.\n *\n * * Slices portions off objects to create cross-section views or reveal interiors.\n * * Registered by {@link SectionPlane#id} in {@link Scene#sectionPlanes}.\n * * Indicates World-space position in {@link SectionPlane#pos} and orientation in {@link SectionPlane#dir}.\n * * Discards elements from the half-space in the direction of {@link SectionPlane#dir}.\n * * Can be be enabled or disabled via {@link SectionPlane#active}.\n *\n * ## Usage\n *\n * In the example below, we'll create two SectionPlanes to slice a model loaded from glTF. Note that we could also create them\n * using a {@link SectionPlanesPlugin}.\n *\n * ````javascript\n * import {Viewer, GLTFLoaderPlugin, SectionPlane} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * const gltfLoaderPlugin = new GLTFModelsPlugin(viewer, {\n *      id: \"GLTFModels\"\n * });\n *\n * const model = gltfLoaderPlugin.load({\n *      id: \"myModel\",\n *      src: \"./models/gltf/mygltfmodel.gltf\"\n * });\n *\n * // Create a SectionPlane on negative diagonal\n * const sectionPlane1 = new SectionPlane(viewer.scene, {\n *     pos: [1.0, 1.0, 1.0],\n *     dir: [-1.0, -1.0, -1.0],\n *     active: true\n * }),\n *\n * // Create a SectionPlane on positive diagonal\n * const sectionPlane2 = new SectionPlane(viewer.scene, {\n *     pos: [-1.0, -1.0, -1.0],\n *     dir: [1.0, 1.0, 1.0],\n *     active: true\n * });\n * ````\n */\nclass SectionPlane extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"SectionPlane\";\n    }\n\n    /**\n     * @constructor\n     * @param {Component} [owner]  Owner component. When destroyed, the owner will destroy this SectionPlane as well.\n     * @param {*} [cfg]  SectionPlane configuration\n     * @param  {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Boolean} [cfg.active=true] Indicates whether or not this SectionPlane is active.\n     * @param {Number[]} [cfg.pos=[0,0,0]] World-space position of the SectionPlane.\n     * @param {Number[]} [cfg.dir=[0,0,-1]] Vector perpendicular to the plane surface, indicating the SectionPlane plane orientation.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            active: true,\n            pos: math.vec3(),\n            quaternion: math.vec4(),\n            roll: 0,\n            dir: math.vec3(),\n            dist: 0\n        });\n\n        this.active = cfg.active;\n        this.pos = cfg.pos;\n        this.dir = cfg.dir;\n\n        this.scene._sectionPlaneCreated(this);\n    }\n\n    /**\n     * Sets if this SectionPlane is active or not.\n     *\n     * Default value is ````true````.\n     *\n     * @param {Boolean} value Set ````true```` to activate else ````false```` to deactivate.\n     */\n    set active(value) {\n        this._state.active = value !== false;\n        this.glRedraw();\n        this.fire(\"active\", this._state.active);\n        this.scene.fire(\"sectionPlaneUpdated\", this);\n    }\n\n    /**\n     * Gets if this SectionPlane is active or not.\n     *\n     * Default value is ````true````.\n     *\n     * @returns {Boolean} Returns ````true```` if active.\n     */\n    get active() {\n        return this._state.active;\n    }\n\n    /**\n     * Sets the World-space position of this SectionPlane's plane.\n     *\n     * Default value is ````[0, 0, 0]````.\n     *\n     * @param {Number[]} value New position.\n     */\n    set pos(value) {\n        this._state.pos.set(value || [0, 0, 0]);\n        this._state.dist = (-math.dotVec3(this._state.pos, this._state.dir));\n        this.fire(\"pos\", this._state.pos);\n        this.scene.fire(\"sectionPlaneUpdated\", this);\n    }\n\n    /**\n     * Gets the World-space position of this SectionPlane's plane.\n     *\n     * Default value is ````[0, 0, 0]````.\n     *\n     * @returns {Number[]} Current position.\n     */\n    get pos() {\n        return this._state.pos;\n    }\n\n    /**\n     * Sets the quaternion of this SectionPlane's plane.\n     *\n     * Default value is ````[0, -1, 0, 0]````.\n     *\n     * @param {Number[]} value New quaternion.\n     */\n    set quaternion(value) {\n        this._state.quaternion.set(value || [0, 0, 0, -1]);\n        math.vec3ApplyQuaternion(this._state.quaternion, back, this._state.dir);\n        const quatUp = math.vec3ApplyQuaternion(this._state.quaternion, up, tempVec3a$b);\n        const dirOnlyQ = math.vec3PairToQuaternion(back, this._state.dir, tempVec4a$8);\n        const dirOnlyUp = math.vec3ApplyQuaternion(dirOnlyQ, up, tempVec3b$8);\n        const angle = Math.acos(Math.min(1, math.dotVec3(quatUp, dirOnlyUp)));\n        const sign = Math.sign(math.dotVec3(this._state.dir, math.cross3Vec3(quatUp, dirOnlyUp, tempVec3b$8)));\n        this._state.roll = sign * angle;\n        this._onDirUpdated();\n    }\n\n    /**\n     * Gets the quaternion of this SectionPlane's plane.\n     *\n     * Default value is ````[0, -1, 0, 0]````.\n     *\n     * @returns {Number[]} value Current quaternion.\n     */\n    get quaternion() {\n        return this._state.quaternion;\n    }\n\n    /**\n     * Sets the roll of this SectionPlane's plane.\n     *\n     * Default value is ````0````.\n     *\n     * @param {Number[]} value New roll.\n     */\n    set roll(value) {\n        this._state.roll = value || 0;\n        this._onDirRollUpdated();\n    }\n\n    /**\n     * Gets the roll of this SectionPlane's plane.\n     *\n     * Default value is ````0````.\n     *\n     * @returns {Number[]} value Current roll.\n     */\n    get roll() {\n        return this._state.roll;\n    }\n\n    /**\n     * Sets the direction of this SectionPlane's plane.\n     *\n     * Default value is ````[0, 0, -1]````.\n     *\n     * @param {Number[]} value New direction.\n     */\n    set dir(value) {\n        this._state.dir.set(value || front);\n        this._onDirRollUpdated();\n    }\n\n    _onDirRollUpdated() {\n        math.vec3PairToQuaternion(back, this._state.dir, this._state.quaternion);\n\n        tempVec4a$8[0] = 0;\n        tempVec4a$8[1] = 0;\n        tempVec4a$8[2] = -1;\n        tempVec4a$8[3] = this._state.roll;\n        math.angleAxisToQuaternion(tempVec4a$8, tempVec4a$8);\n\n        math.mulQuaternions(this._state.quaternion, tempVec4a$8, this._state.quaternion);\n\n        this._onDirUpdated();\n    }\n\n    _onDirUpdated() {\n        this._state.dist = (-math.dotVec3(this._state.pos, this._state.dir));\n        this.glRedraw();\n        this.fire(\"dir\", this._state.dir);\n        this.scene.fire(\"sectionPlaneUpdated\", this);\n    }\n\n    /**\n     * Gets the direction of this SectionPlane's plane.\n     *\n     * Default value is ````[0, 0, -1]````.\n     *\n     * @returns {Number[]} value Current direction.\n     */\n    get dir() {\n        return this._state.dir;\n    }\n\n    /**\n     * Gets this SectionPlane's distance to the origin of the World-space coordinate system.\n     *\n     * This is the dot product of {@link SectionPlane#pos} and {@link SectionPlane#dir} and is automatically re-calculated\n     * each time either of two properties are updated.\n     *\n     * @returns {Number}\n     */\n    get dist() {\n        return this._state.dist;\n    }\n\n    /**\n     * Inverts the direction of {@link SectionPlane#dir}.\n     */\n    flipDir() {\n        math.mulVec3Scalar(this._state.dir, -1.0, this._state.dir);\n        this.dir = this._state.dir;\n    }\n\n    /**\n     * @destroy\n     */\n    destroy() {\n        this._state.destroy();\n        this.scene._sectionPlaneDestroyed(this);\n        super.destroy();\n    }\n}\n\n/**\n * Transcodes texture data.\n *\n * A {@link SceneModel} configured with an appropriate TextureTranscoder will allow us to add textures from\n * transcoded buffers or files. For a concrete example, see {@link VBOSceneModel}, which can be configured with\n * a {@link KTX2TextureTranscoder}, which allows us to add textures from KTX2 buffers and files.\n *\n * @interface\n */\nclass TextureTranscoder {\n\n    /**\n     * Transcodes texture data from transcoded buffers into a {@link Texture2D}.\n     *\n     * @param {ArrayBuffer[]} buffers Transcoded texture data. Given as an array of buffers so that we can support\n     * multi-image textures, such as cube maps.\n     * @param {*} config Transcoding options.\n     * @param {Texture2D} texture The texture to load.\n     * @returns {Promise} Resolves when the texture has loaded.\n     */\n    transcode(buffers, texture, config = {}) {\n    }\n\n    /**\n     * Destroys this transcoder.\n     */\n    destroy() {\n    }\n}\n\n/**\n * @desc Pick result returned by {@link Scene#pick}.\n *\n */\nclass PickResult {\n\n    /**\n     * @private\n     */\n    constructor() {\n\n        /**\n         * Picked entity.\n         * Null when no entity was picked.\n         * @property entity\n         * @type {Entity|*}\n         */\n        this.entity = null;\n\n        /**\n         * Type of primitive that was picked - usually \"triangle\".\n         * Null when no primitive was picked.\n         * @property primitive\n         * @type {String}\n         */\n        this.primitive = null;\n\n        /**\n         * Index of primitive that was picked.\n         * -1 when no entity was picked.\n         * @property primIndex\n         * @type {number}\n         */\n        this.primIndex = -1;\n\n        /**\n         * True when the picked surface position is full precision.\n         * When false, the picked surface position should be regarded as approximate.\n         * Full-precision surface picking is performed with the {@link Scene#pick} method's ````pickSurfacePrecision```` option.\n         * @property pickSurfacePrecision\n         * @type {Boolean}\n         */\n        this.pickSurfacePrecision = false;\n\n        /**\n         * True when picked from touch input, else false when from mouse input.\n         * @type {boolean}\n         */\n        this.touchInput = false;\n\n        /**\n         * True when snapped to nearest edge.\n         * @type {boolean}\n         */\n        this.snappedToEdge = false;\n\n        /**\n         * True when snapped to nearest vertex.\n         * @type {boolean}\n         */\n        this.snappedToVertex = false;\n\n        this._origin = new Float64Array([0, 0, 0]);\n        this._direction = new Float64Array([0, 0, 0]);\n        this._indices = new Int32Array(3);\n        this._localPos = new Float64Array([0, 0, 0]);\n        this._worldPos = new Float64Array([0, 0, 0]);\n        this._viewPos = new Float64Array([0, 0, 0]);\n        this._canvasPos = new Int16Array([0, 0]);\n        this._snappedCanvasPos = new Int16Array([0, 0]);\n        this._bary = new Float64Array([0, 0, 0]);\n        this._worldNormal = new Float64Array([0, 0, 0]);\n        this._uv = new Float64Array([0, 0]);\n\n        this.reset();\n    }\n\n    /**\n     * Canvas pick coordinates.\n     * @property canvasPos\n     * @type {Number[]}\n     */\n    get canvasPos() {\n        return this._gotCanvasPos ? this._canvasPos : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set canvasPos(value) {\n        if (value) {\n            this._canvasPos[0] = value[0];\n            this._canvasPos[1] = value[1];\n            this._gotCanvasPos = true;\n        } else {\n            this._gotCanvasPos = false;\n        }\n    }\n\n    /**\n     * World-space 3D ray origin when raypicked.\n     * @property origin\n     * @type {Number[]}\n     */\n    get origin() {\n        return this._gotOrigin ? this._origin : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set origin(value) {\n        if (value) {\n            this._origin[0] = value[0];\n            this._origin[1] = value[1];\n            this._origin[2] = value[2];\n            this._gotOrigin = true;\n        } else {\n            this._gotOrigin = false;\n        }\n    }\n\n    /**\n     * World-space 3D ray direction when raypicked.\n     * @property direction\n     * @type {Number[]}\n     */\n    get direction() {\n        return this._gotDirection ? this._direction : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set direction(value) {\n        if (value) {\n            this._direction[0] = value[0];\n            this._direction[1] = value[1];\n            this._direction[2] = value[2];\n            this._gotDirection = true;\n        } else {\n            this._gotDirection = false;\n        }\n    }\n    \n    /**\n     * Picked triangle's vertex indices.\n     * @property indices\n     * @type {Int32Array}\n     */\n    get indices() {\n        return this.entity && this._gotIndices ? this._indices : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set indices(value) {\n        if (value) {\n            this._indices[0] = value[0];\n            this._indices[1] = value[1];\n            this._indices[2] = value[2];\n            this._gotIndices = true;\n        } else {\n            this._gotIndices = false;\n        }\n    }\n\n    /**\n     * Picked Local-space point.\n     * @property localPos\n     * @type {Number[]}\n     */\n    get localPos() {\n        return this.entity && this._gotLocalPos ? this._localPos : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set localPos(value) {\n        if (value) {\n            this._localPos[0] = value[0];\n            this._localPos[1] = value[1];\n            this._localPos[2] = value[2];\n            this._gotLocalPos = true;\n        } else {\n            this._gotLocalPos = false;\n        }\n    }\n\n    /**\n     * Canvas cursor coordinates, snapped when snap picking, otherwise same as {@link PickResult#pointerPos}.\n     * @property snappedCanvasPos\n     * @type {Number[]}\n     */\n    get snappedCanvasPos() {\n        return this._gotSnappedCanvasPos ? this._snappedCanvasPos : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set snappedCanvasPos(value) {\n        if (value) {\n            this._snappedCanvasPos[0] = value[0];\n            this._snappedCanvasPos[1] = value[1];\n            this._gotSnappedCanvasPos = true;\n        } else {\n            this._gotSnappedCanvasPos = false;\n        }\n    }\n\n    /**\n     * Picked World-space point.\n     * @property worldPos\n     * @type {Number[]}\n     */\n    get worldPos() {\n        return this._gotWorldPos ? this._worldPos : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set worldPos(value) {\n        if (value) {\n            this._worldPos[0] = value[0];\n            this._worldPos[1] = value[1];\n            this._worldPos[2] = value[2];\n            this._gotWorldPos = true;\n        } else {\n            this._gotWorldPos = false;\n        }\n    }\n\n    /**\n     * Picked View-space point.\n     * @property viewPos\n     * @type {Number[]}\n     */\n    get viewPos() {\n        return this.entity && this._gotViewPos ? this._viewPos : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set viewPos(value) {\n        if (value) {\n            this._viewPos[0] = value[0];\n            this._viewPos[1] = value[1];\n            this._viewPos[2] = value[2];\n            this._gotViewPos = true;\n        } else {\n            this._gotViewPos = false;\n        }\n    }\n\n    /**\n     * Barycentric coordinate within picked triangle.\n     * @property bary\n     * @type {Number[]}\n     */\n    get bary() {\n        return this.entity && this._gotBary ? this._bary : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set bary(value) {\n        if (value) {\n            this._bary[0] = value[0];\n            this._bary[1] = value[1];\n            this._bary[2] = value[2];\n            this._gotBary = true;\n        } else {\n            this._gotBary = false;\n        }\n    }\n\n    /**\n     * Normal vector at picked position on surface.\n     * @property worldNormal\n     * @type {Number[]}\n     */\n    get worldNormal() {\n        return this.entity && this._gotWorldNormal ? this._worldNormal : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set worldNormal(value) {\n        if (value) {\n            this._worldNormal[0] = value[0];\n            this._worldNormal[1] = value[1];\n            this._worldNormal[2] = value[2];\n            this._gotWorldNormal = true;\n        } else {\n            this._gotWorldNormal = false;\n        }\n    }\n\n    /**\n     * UV coordinates at picked position on surface.\n     * @property uv\n     * @type {Number[]}\n     */\n    get uv() {\n        return this.entity && this._gotUV ? this._uv : null;\n    }\n\n    /**\n     * @private\n     * @param value\n     */\n    set uv(value) {\n        if (value) {\n            this._uv[0] = value[0];\n            this._uv[1] = value[1];\n            this._gotUV = true;\n        } else {\n            this._gotUV = false;\n        }\n    }\n\n    /**\n     * True if snapped to edge or vertex.\n     * @returns {boolean}\n     */\n    get snapped() {\n        return this.snappedToEdge || this.snappedToVertex;\n    }\n\n    /**\n     * @private\n     */\n    reset() {\n        this.entity = null;\n        this.primIndex = -1;\n        this.primitive = null;\n        this.pickSurfacePrecision = false;\n        this._gotCanvasPos = false;\n        this._gotSnappedCanvasPos = false;\n        this._gotOrigin = false;\n        this._gotDirection = false;\n        this._gotIndices = false;\n        this._gotLocalPos = false;\n        this._gotWorldPos = false;\n        this._gotViewPos = false;\n        this._gotBary = false;\n        this._gotWorldNormal = false;\n        this._gotUV = false;\n        this.touchInput = false;\n        this.snappedToEdge = false;\n        this.snappedToVertex = false;\n    }\n}\n\nconst os = {\n    isIphoneSafari() {\n        const userAgent = window.navigator.userAgent;\n        const isIphone = /iPhone/i.test(userAgent);\n        const isSafari = /Safari/i.test(userAgent) && !/Chrome/i.test(userAgent);\n\n        return isIphone && isSafari;\n    },\n    isIphoneOrIpadSafari() {\n        const userAgent = window.navigator.userAgent;\n        const isIphoneOrIpad = /iPhone|iPad/i.test(userAgent) || (\n            // iPad detection: Check for touch support and macOS-like user agent\n            /Macintosh/i.test(userAgent) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2\n        );\n        const isSafari = /Safari/i.test(userAgent) && !/Chrome/i.test(userAgent);\n        return isIphoneOrIpad && isSafari;\n    },\n    isTouchDevice() {\n        return (\n            'ontouchstart' in window || //works for most devices\n            navigator.maxTouchPoints > 0 || //works for modern touch devices\n            navigator.mxMaxTouchPoints > 0 //works for older microsoft touch devices\n        )\n    }\n};\n\n/**\n @desc Base class for {@link Viewer} plugin classes.\n */\nclass Plugin {\n\n    /**\n     * Creates this Plugin and installs it into the given {@link Viewer}.\n     *\n     * @param {string} id ID for this plugin, unique among all plugins in the viewer.\n     * @param {Viewer} viewer The viewer.\n     * @param {Object} [cfg] Options\n     */\n    constructor(id, viewer, cfg) {\n\n        /**\n         * ID for this Plugin, unique within its {@link Viewer}.\n         *\n         * @type {string}\n         */\n        this.id = (cfg && cfg.id) ? cfg.id : id;\n\n        /**\n         * The Viewer that contains this Plugin.\n         *\n         * @type {Viewer}\n         */\n        this.viewer = viewer;\n\n        this._subIdMap = null; // Subscription subId pool\n        this._subIdEvents = null; // Subscription subIds mapped to event names\n        this._eventSubs = null; // Event names mapped to subscribers\n        this._eventSubsNum = null;\n        this._events = null; // Maps names to events\n        this._eventCallDepth = 0; // Helps us catch stack overflows from recursive events\n\n        viewer.addPlugin(this);\n    }\n\n    /**\n     * Schedule a task to perform on the next browser interval\n     * @param task\n     */\n    scheduleTask(task) {\n        core.scheduleTask(task, null);\n    }\n\n    /**\n     * Fires an event on this Plugin.\n     *\n     * Notifies existing subscribers to the event, optionally retains the event to give to\n     * any subsequent notifications on the event as they are made.\n     *\n     * @param {String} event The event type name\n     * @param {Object} value The event parameters\n     * @param {Boolean} [forget=false] When true, does not retain for subsequent subscribers\n     */\n    fire(event, value, forget) {\n        if (!this._events) {\n            this._events = {};\n        }\n        if (!this._eventSubs) {\n            this._eventSubs = {};\n            this._eventSubsNum = {};\n        }\n        if (forget !== true) {\n            this._events[event] = value || true; // Save notification\n        }\n        const subs = this._eventSubs[event];\n        let sub;\n        if (subs) { // Notify subscriptions\n            for (const subId in subs) {\n                if (subs.hasOwnProperty(subId)) {\n                    sub = subs[subId];\n                    this._eventCallDepth++;\n                    if (this._eventCallDepth < 300) {\n                        sub.callback.call(sub.scope, value);\n                    } else {\n                        this.error(\"fire: potential stack overflow from recursive event '\" + event + \"' - dropping this event\");\n                    }\n                    this._eventCallDepth--;\n                }\n            }\n        }\n    }\n\n    /**\n     * Subscribes to an event on this Plugin.\n     *\n     * The callback is be called with this Plugin as scope.\n     *\n     * @param {String} event The event\n     * @param {Function} callback Called fired on the event\n     * @param {Object} [scope=this] Scope for the callback\n     * @return {String} Handle to the subscription, which may be used to unsubscribe with {@link #off}.\n     */\n    on(event, callback, scope) {\n        if (!this._events) {\n            this._events = {};\n        }\n        if (!this._subIdMap) {\n            this._subIdMap = new Map$1(); // Subscription subId pool\n        }\n        if (!this._subIdEvents) {\n            this._subIdEvents = {};\n        }\n        if (!this._eventSubs) {\n            this._eventSubs = {};\n        }\n        if (!this._eventSubsNum) {\n            this._eventSubsNum = {};\n        }\n        let subs = this._eventSubs[event];\n        if (!subs) {\n            subs = {};\n            this._eventSubs[event] = subs;\n            this._eventSubsNum[event] = 1;\n        } else {\n            this._eventSubsNum[event]++;\n        }\n        const subId = this._subIdMap.addItem(); // Create unique subId\n        subs[subId] = {\n            callback: callback,\n            scope: scope || this\n        };\n        this._subIdEvents[subId] = event;\n        const value = this._events[event];\n        if (value !== undefined) { // A publication exists, notify callback immediately\n            callback.call(scope || this, value);\n        }\n        return subId;\n    }\n\n    /**\n     * Cancels an event subscription that was previously made with {@link Plugin#on} or {@link Plugin#once}.\n     *\n     * @param {String} subId Subscription ID\n     */\n    off(subId) {\n        if (subId === undefined || subId === null) {\n            return;\n        }\n        if (!this._subIdEvents) {\n            return;\n        }\n        const event = this._subIdEvents[subId];\n        if (event) {\n            delete this._subIdEvents[subId];\n            const subs = this._eventSubs[event];\n            if (subs) {\n                delete subs[subId];\n                this._eventSubsNum[event]--;\n            }\n            this._subIdMap.removeItem(subId); // Release subId\n        }\n    }\n\n    /**\n     * Subscribes to the next occurrence of the given event, then un-subscribes as soon as the event is subIdd.\n     *\n     * This is equivalent to calling {@link Plugin#on}, and then calling {@link Plugin#off} inside the callback function.\n     *\n     * @param {String} event Data event to listen to\n     * @param {Function} callback Called when fresh data is available at the event\n     * @param {Object} [scope=this] Scope for the callback\n     */\n    once(event, callback, scope) {\n        const self = this;\n        const subId = this.on(event,\n            function (value) {\n                self.off(subId);\n                callback.call(scope || this, value);\n            },\n            scope);\n    }\n\n    /**\n     * Returns true if there are any subscribers to the given event on this Plugin.\n     *\n     * @param {String} event The event\n     * @return {Boolean} True if there are any subscribers to the given event on this Plugin.\n     */\n    hasSubs(event) {\n        return (this._eventSubsNum && (this._eventSubsNum[event] > 0));\n    }\n\n    /**\n     * Logs a message to the JavaScript developer console, prefixed with the ID of this Plugin.\n     *\n     * @param {String} msg The error message\n     */\n    log(msg) {\n        console.log(`[xeokit plugin ${this.id}]: ${msg}`);\n    }\n\n    /**\n     * Logs a warning message to the JavaScript developer console, prefixed with the ID of this Plugin.\n     *\n     * @param {String} msg The error message\n     */\n    warn(msg) {\n        console.warn(`[xeokit plugin ${this.id}]: ${msg}`);\n    }\n\n    /**\n     * Logs an error message to the JavaScript developer console, prefixed with the ID of this Plugin.\n     *\n     * @param {String} msg The error message\n     */\n    error(msg) {\n        console.error(`[xeokit plugin ${this.id}]: ${msg}`);\n    }\n\n    /**\n     * Sends a message to this Plugin.\n     *\n     * @private\n     */\n    send(name, value) {\n        //...\n    }\n\n    /**\n     * Destroys this Plugin and removes it from its {@link Viewer}.\n     */\n    destroy() {\n        this.viewer.removePlugin(this);\n    }\n}\n\nconst defaultCSS = \".sk-fading-circle {\\\n        background: transparent;\\\n        margin: 20px auto;\\\n        width: 50px;\\\n        height:50px;\\\n        position: relative;\\\n        }\\\n        .sk-fading-circle .sk-circle {\\\n        width: 120%;\\\n        height: 120%;\\\n        position: absolute;\\\n        left: 0;\\\n        top: 0;\\\n        }\\\n        .sk-fading-circle .sk-circle:before {\\\n        content: '';\\\n        display: block;\\\n        margin: 0 auto;\\\n        width: 15%;\\\n        height: 15%;\\\n        background-color: #ff8800;\\\n        border-radius: 100%;\\\n        -webkit-animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;\\\n        animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;\\\n        }\\\n        .sk-fading-circle .sk-circle2 {\\\n        -webkit-transform: rotate(30deg);\\\n        -ms-transform: rotate(30deg);\\\n        transform: rotate(30deg);\\\n    }\\\n    .sk-fading-circle .sk-circle3 {\\\n        -webkit-transform: rotate(60deg);\\\n        -ms-transform: rotate(60deg);\\\n        transform: rotate(60deg);\\\n    }\\\n    .sk-fading-circle .sk-circle4 {\\\n        -webkit-transform: rotate(90deg);\\\n        -ms-transform: rotate(90deg);\\\n        transform: rotate(90deg);\\\n    }\\\n    .sk-fading-circle .sk-circle5 {\\\n        -webkit-transform: rotate(120deg);\\\n        -ms-transform: rotate(120deg);\\\n        transform: rotate(120deg);\\\n    }\\\n    .sk-fading-circle .sk-circle6 {\\\n        -webkit-transform: rotate(150deg);\\\n        -ms-transform: rotate(150deg);\\\n        transform: rotate(150deg);\\\n    }\\\n    .sk-fading-circle .sk-circle7 {\\\n        -webkit-transform: rotate(180deg);\\\n        -ms-transform: rotate(180deg);\\\n        transform: rotate(180deg);\\\n    }\\\n    .sk-fading-circle .sk-circle8 {\\\n        -webkit-transform: rotate(210deg);\\\n        -ms-transform: rotate(210deg);\\\n        transform: rotate(210deg);\\\n    }\\\n    .sk-fading-circle .sk-circle9 {\\\n        -webkit-transform: rotate(240deg);\\\n        -ms-transform: rotate(240deg);\\\n        transform: rotate(240deg);\\\n    }\\\n    .sk-fading-circle .sk-circle10 {\\\n        -webkit-transform: rotate(270deg);\\\n        -ms-transform: rotate(270deg);\\\n        transform: rotate(270deg);\\\n    }\\\n    .sk-fading-circle .sk-circle11 {\\\n        -webkit-transform: rotate(300deg);\\\n        -ms-transform: rotate(300deg);\\\n        transform: rotate(300deg);\\\n    }\\\n    .sk-fading-circle .sk-circle12 {\\\n        -webkit-transform: rotate(330deg);\\\n        -ms-transform: rotate(330deg);\\\n        transform: rotate(330deg);\\\n    }\\\n    .sk-fading-circle .sk-circle2:before {\\\n        -webkit-animation-delay: -1.1s;\\\n        animation-delay: -1.1s;\\\n    }\\\n    .sk-fading-circle .sk-circle3:before {\\\n        -webkit-animation-delay: -1s;\\\n        animation-delay: -1s;\\\n    }\\\n    .sk-fading-circle .sk-circle4:before {\\\n        -webkit-animation-delay: -0.9s;\\\n        animation-delay: -0.9s;\\\n    }\\\n    .sk-fading-circle .sk-circle5:before {\\\n        -webkit-animation-delay: -0.8s;\\\n        animation-delay: -0.8s;\\\n    }\\\n    .sk-fading-circle .sk-circle6:before {\\\n        -webkit-animation-delay: -0.7s;\\\n        animation-delay: -0.7s;\\\n    }\\\n    .sk-fading-circle .sk-circle7:before {\\\n        -webkit-animation-delay: -0.6s;\\\n        animation-delay: -0.6s;\\\n    }\\\n    .sk-fading-circle .sk-circle8:before {\\\n        -webkit-animation-delay: -0.5s;\\\n        animation-delay: -0.5s;\\\n    }\\\n    .sk-fading-circle .sk-circle9:before {\\\n        -webkit-animation-delay: -0.4s;\\\n        animation-delay: -0.4s;\\\n    }\\\n    .sk-fading-circle .sk-circle10:before {\\\n        -webkit-animation-delay: -0.3s;\\\n        animation-delay: -0.3s;\\\n    }\\\n    .sk-fading-circle .sk-circle11:before {\\\n        -webkit-animation-delay: -0.2s;\\\n        animation-delay: -0.2s;\\\n    }\\\n    .sk-fading-circle .sk-circle12:before {\\\n        -webkit-animation-delay: -0.1s;\\\n        animation-delay: -0.1s;\\\n    }\\\n    @-webkit-keyframes sk-circleFadeDelay {\\\n        0%, 39%, 100% { opacity: 0; }\\\n        40% { opacity: 1; }\\\n    }\\\n    @keyframes sk-circleFadeDelay {\\\n        0%, 39%, 100% { opacity: 0; }\\\n        40% { opacity: 1; }\\\n    }\";\n\n/**\n * @desc Displays a progress animation at the center of its {@link Canvas} while things are loading or otherwise busy.\n *\n *\n * * Located at {@link Canvas#spinner}.\n * * Automatically shown while things are loading, however may also be shown by application code wanting to indicate busyness.\n * * {@link Spinner#processes} holds the count of active processes. As a process starts, it increments {@link Spinner#processes}, then decrements it on completion or failure.\n * * A Spinner is only visible while {@link Spinner#processes} is greater than zero.\n *\n * ````javascript\n * var spinner = viewer.scene.canvas.spinner;\n *\n * // Increment count of busy processes represented by the spinner;\n * // assuming the count was zero, this now shows the spinner\n * spinner.processes++;\n *\n * // Increment the count again, by some other process; spinner already visible, now requires two decrements\n * // before it becomes invisible again\n * spinner.processes++;\n *\n * // Decrement the count; count still greater than zero, so spinner remains visible\n * spinner.process--;\n *\n * // Decrement the count; count now zero, so spinner becomes invisible\n * spinner.process--;\n * ````\n */\nclass Spinner extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Spinner\";\n    }\n\n    /**\n     @private\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._canvas = cfg.canvas;\n        this._element = null;\n        this._isCustom = false; // True when the element is custom HTML\n\n        if (cfg.elementId) { // Custom spinner element supplied\n            this._element = document.getElementById(cfg.elementId);\n            if (!this._element) {\n                this.error(\"Can't find given Spinner HTML element: '\" + cfg.elementId + \"' - will automatically create default element\");\n            } else {\n                this._adjustPosition();\n            }\n        }\n\n        if (!this._element) {\n            this._createDefaultSpinner();\n        }\n\n        this.processes = 0;\n    }\n\n    /** @private */\n    _createDefaultSpinner() {\n        this._injectDefaultCSS();\n        const element = document.createElement('div');\n        const style = element.style;\n        style[\"z-index\"] = \"9000\";\n        style.position = \"absolute\";\n        element.innerHTML = '<div class=\"sk-fading-circle\">\\\n                <div class=\"sk-circle1 sk-circle\"></div>\\\n                <div class=\"sk-circle2 sk-circle\"></div>\\\n                <div class=\"sk-circle3 sk-circle\"></div>\\\n                <div class=\"sk-circle4 sk-circle\"></div>\\\n                <div class=\"sk-circle5 sk-circle\"></div>\\\n                <div class=\"sk-circle6 sk-circle\"></div>\\\n                <div class=\"sk-circle7 sk-circle\"></div>\\\n                <div class=\"sk-circle8 sk-circle\"></div>\\\n                <div class=\"sk-circle9 sk-circle\"></div>\\\n                <div class=\"sk-circle10 sk-circle\"></div>\\\n                <div class=\"sk-circle11 sk-circle\"></div>\\\n                <div class=\"sk-circle12 sk-circle\"></div>\\\n                </div>';\n        this._canvas.parentElement.appendChild(element);\n        this._element = element;\n        this._isCustom = false;\n        this._adjustPosition();\n    }\n\n    /**\n     * @private\n     */\n    _injectDefaultCSS() {\n        const elementId = \"xeokit-spinner-css\";\n        if (document.getElementById(elementId)) {\n            return;\n        }\n        const defaultCSSNode = document.createElement('style');\n        defaultCSSNode.innerHTML = defaultCSS;\n        defaultCSSNode.id = elementId;\n        document.body.appendChild(defaultCSSNode);\n    }\n\n    /**\n     * @private\n     */\n    _adjustPosition() { // (Re)positions spinner DIV over the center of the canvas - called by Canvas\n        if (this._isCustom) {\n            return;\n        }\n        const canvas = this._canvas;\n        const element = this._element;\n        const style = element.style;\n        style[\"left\"] = (canvas.offsetLeft + (canvas.clientWidth * 0.5) - (element.clientWidth * 0.5)) + \"px\";\n        style[\"top\"] = (canvas.offsetTop + (canvas.clientHeight * 0.5) - (element.clientHeight * 0.5)) + \"px\";\n    }\n\n    /**\n     * Sets the number of processes this Spinner represents.\n     *\n     * The Spinner is visible while this property is greater than zero.\n     *\n     * Increment this property whenever you commence some process during which you want the Spinner to be visible, then decrement it again when the process is complete.\n     *\n     * Clamps to zero if you attempt to set to to a negative value.\n     *\n     * Fires a {@link Spinner#processes:event} event on change.\n\n     * Default value is ````0````.\n     *\n     * @param {Number} value New processes count.\n     */\n    set processes(value) {\n        value = value || 0;\n        if (this._processes === value) {\n            return;\n        }\n        if (value < 0) {\n            return;\n        }\n        const prevValue = this._processes;\n        this._processes = value;\n        const element = this._element;\n        if (element) {\n            element.style[\"visibility\"] = (this._processes > 0) ? \"visible\" : \"hidden\";\n        }\n        /**\n         Fired whenever this Spinner's {@link Spinner#visible} property changes.\n\n         @event processes\n         @param value The property's new value\n         */\n        this.fire(\"processes\", this._processes);\n        if (this._processes === 0 && this._processes !== prevValue) {\n            /**\n             Fired whenever this Spinner's {@link Spinner#visible} property becomes zero.\n\n             @event zeroProcesses\n             */\n            this.fire(\"zeroProcesses\", this._processes);\n        }\n    }\n\n    /**\n     * Gets the number of processes this Spinner represents.\n     *\n     * The Spinner is visible while this property is greater than zero.\n     *\n     * @returns {Number} Current processes count.\n     */\n    get processes() {\n        return this._processes;\n    }\n\n    _destroy() {\n        if (this._element && (!this._isCustom)) {\n            this._element.parentNode.removeChild(this._element);\n            this._element = null;\n        }\n        const styleElement = document.getElementById(\"xeokit-spinner-css\");\n        if (styleElement) {\n            styleElement.parentNode.removeChild(styleElement);\n        }\n    }\n}\n\nconst WEBGL_CONTEXT_NAMES = [\n    \"webgl2\",\n    \"experimental-webgl\",\n    \"webkit-3d\",\n    \"moz-webgl\",\n    \"moz-glweb20\"\n];\n\n/**\n * @desc Manages its {@link Scene}'s HTML canvas.\n *\n * * Provides the HTML canvas element in {@link Canvas#canvas}.\n * * Has a {@link Spinner}, provided at {@link Canvas#spinner}, which manages the loading progress indicator.\n */\nclass Canvas extends Component {\n\n    /**\n     * @constructor\n     * @private\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._backgroundColor = math.vec3([\n            cfg.backgroundColor ? cfg.backgroundColor[0] : 1,\n            cfg.backgroundColor ? cfg.backgroundColor[1] : 1,\n            cfg.backgroundColor ? cfg.backgroundColor[2] : 1]);\n        this._backgroundColorFromAmbientLight = !!cfg.backgroundColorFromAmbientLight;\n\n        /**\n         * The HTML canvas.\n         *\n         * @property canvas\n         * @type {HTMLCanvasElement}\n         * @final\n         */\n        this.canvas = cfg.canvas;\n\n        /**\n         * The WebGL rendering context.\n         *\n         * @property gl\n         * @type {WebGLRenderingContext}\n         * @final\n         */\n        this.gl = null;\n\n        /**\n         * True when WebGL 2 support is enabled.\n         *\n         * @property webgl2\n         * @type {Boolean}\n         * @final\n         */\n        this.webgl2 = false; // Will set true in _initWebGL if WebGL is requested and we succeed in getting it.\n\n        /**\n         * Indicates if this Canvas is transparent.\n         *\n         * @property transparent\n         * @type {Boolean}\n         * @default {false}\n         * @final\n         */\n        this.transparent = !!cfg.transparent;\n\n        /**\n         * Attributes for the WebGL context\n         *\n         * @type {{}|*}\n         */\n        this.contextAttr = cfg.contextAttr || {};\n        this.contextAttr.alpha = this.transparent;\n\n        this.contextAttr.preserveDrawingBuffer = !!this.contextAttr.preserveDrawingBuffer;\n        this.contextAttr.stencil = false;\n        this.contextAttr.premultipliedAlpha = (!!this.contextAttr.premultipliedAlpha);  // False by default: https://github.com/xeokit/xeokit-sdk/issues/251\n        this.contextAttr.antialias = (this.contextAttr.antialias !== false);\n\n        // If the canvas uses css styles to specify the sizes make sure the basic\n        // width and height attributes match or the WebGL context will use 300 x 150\n\n        this.resolutionScale = cfg.resolutionScale;\n\n        this.canvas.width = Math.round(this.canvas.clientWidth * this._resolutionScale);\n        this.canvas.height = Math.round(this.canvas.clientHeight * this._resolutionScale);\n\n        /**\n         * Boundary of the Canvas in absolute browser window coordinates.\n         *\n         * ### Usage:\n         *\n         * ````javascript\n         * var boundary = myScene.canvas.boundary;\n         *\n         * var xmin = boundary[0];\n         * var ymin = boundary[1];\n         * var width = boundary[2];\n         * var height = boundary[3];\n         * ````\n         *\n         * @property boundary\n         * @type {Number[]}\n         * @final\n         */\n        this.boundary = [\n            this.canvas.offsetLeft, this.canvas.offsetTop,\n            this.canvas.clientWidth, this.canvas.clientHeight\n        ];\n\n        // Get WebGL context\n\n        this._initWebGL(cfg);\n\n        const self = this;\n\n        // Attach to resize events on the canvas\n        let dirtyBoundary = true; // make sure we publish the 1st boundary event\n\n        const resizeObserver = new ResizeObserver((entries) => {\n            for (const entry of entries) {\n                if (entry.contentBoxSize) {\n                    dirtyBoundary = true;\n                }\n            }\n        });\n\n        resizeObserver.observe(this.canvas);\n\n        // Publish canvas size and position changes on each scene tick\n        this._tick = this.scene.on(\"tick\", () => {\n            // Only publish if the canvas bounds changed\n            if (!dirtyBoundary) {\n                return;\n            }\n\n            dirtyBoundary = false;\n\n            // Set the real size of the canvas (the drawable w*h)\n            self.canvas.width = Math.round(self.canvas.clientWidth * self._resolutionScale);\n            self.canvas.height = Math.round(self.canvas.clientHeight * self._resolutionScale);\n\n            // Publish the boundary change\n            self.boundary[0] = self.canvas.offsetLeft;\n            self.boundary[1] = self.canvas.offsetTop;\n            self.boundary[2] = self.canvas.clientWidth;\n            self.boundary[3] = self.canvas.clientHeight;\n\n            self.fire(\"boundary\", self.boundary);\n        });\n\n        this._spinner = new Spinner(this.scene, {\n            canvas: this.canvas,\n            elementId: cfg.spinnerElementId\n        });\n    }\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Canvas\";\n    }\n\n    /**\n     * Gets whether the canvas clear color will be derived from {@link AmbientLight} or {@link Canvas#backgroundColor}\n     * when {@link Canvas#transparent} is ```true```.\n     *\n     * When {@link Canvas#transparent} is ```true``` and this is ````true````, then the canvas clear color will\n     * be taken from the {@link Scene}'s ambient light color.\n     *\n     * When {@link Canvas#transparent} is ```true``` and this is ````false````, then the canvas clear color will\n     * be taken from {@link Canvas#backgroundColor}.\n     *\n     * Default value is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get backgroundColorFromAmbientLight() {\n        return this._backgroundColorFromAmbientLight;\n    }\n\n    /**\n     * Sets if the canvas background color is derived from an {@link AmbientLight}.\n     *\n     * This only has effect when the canvas is not transparent. When not enabled, the background color\n     * will be the canvas element's HTML/CSS background color.\n     *\n     * Default value is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set backgroundColorFromAmbientLight(backgroundColorFromAmbientLight) {\n        this._backgroundColorFromAmbientLight = (backgroundColorFromAmbientLight !== false);\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the canvas clear color.\n     *\n     * Default value is ````[1, 1, 1]````.\n     *\n     * @type {Number[]}\n     */\n    get backgroundColor() {\n        return this._backgroundColor;\n    }\n\n    /**\n     * Sets the canvas clear color.\n     *\n     * Default value is ````[1, 1, 1]````.\n     *\n     * @type {Number[]}\n     */\n    set backgroundColor(value) {\n        if (value) {\n            this._backgroundColor[0] = value[0];\n            this._backgroundColor[1] = value[1];\n            this._backgroundColor[2] = value[2];\n        } else {\n            this._backgroundColor[0] = 1.0;\n            this._backgroundColor[1] = 1.0;\n            this._backgroundColor[2] = 1.0;\n        }\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the scale of the canvas back buffer relative to the CSS-defined size of the canvas.\n     *\n     * This is a common way to trade off rendering quality for speed. If the canvas size is defined in CSS, then\n     * setting this to a value between ````[0..1]```` (eg ````0.5````) will render into a smaller back buffer, giving\n     * a performance boost.\n     *\n     * @returns {*|number} The resolution scale.\n     */\n    get resolutionScale() {\n        return this._resolutionScale;\n    }\n\n    /**\n     * Sets the scale of the canvas back buffer relative to the CSS-defined size of the canvas.\n     *\n     * This is a common way to trade off rendering quality for speed. If the canvas size is defined in CSS, then\n     * setting this to a value between ````[0..1]```` (eg ````0.5````) will render into a smaller back buffer, giving\n     * a performance boost.\n     *\n     * @param {*|number} resolutionScale The resolution scale.\n     */\n    set resolutionScale(resolutionScale) {\n        resolutionScale = resolutionScale || 1.0;\n        if (resolutionScale === this._resolutionScale) {\n            return;\n        }\n        this._resolutionScale = resolutionScale;\n        const canvas = this.canvas;\n        canvas.width = Math.round(canvas.clientWidth * this._resolutionScale);\n        canvas.height = Math.round(canvas.clientHeight * this._resolutionScale);\n        this.glRedraw();\n    }\n\n    /**\n     * The busy {@link Spinner} for this Canvas.\n     *\n     * @property spinner\n     * @type Spinner\n     * @final\n     */\n    get spinner() {\n        return this._spinner;\n    }\n\n    /**\n     * Creates a default canvas in the DOM.\n     * @private\n     */\n    _createCanvas() {\n\n        const canvasId = \"xeokit-canvas-\" + math.createUUID();\n        const body = document.getElementsByTagName(\"body\")[0];\n        const div = document.createElement('div');\n\n        const style = div.style;\n        style.height = \"100%\";\n        style.width = \"100%\";\n        style.padding = \"0\";\n        style.margin = \"0\";\n        style.background = \"rgba(0,0,0,0);\";\n        style.float = \"left\";\n        style.left = \"0\";\n        style.top = \"0\";\n        style.position = \"absolute\";\n        style.opacity = \"1.0\";\n        style[\"z-index\"] = \"-10000\";\n\n        div.innerHTML += '<canvas id=\"' + canvasId + '\" style=\"width: 100%; height: 100%; float: left; margin: 0; padding: 0;\"></canvas>';\n\n        body.appendChild(div);\n\n        this.canvas = document.getElementById(canvasId);\n    }\n\n    _getElementXY(e) {\n        let x = 0, y = 0;\n        while (e) {\n            x += (e.offsetLeft - e.scrollLeft);\n            y += (e.offsetTop - e.scrollTop);\n            e = e.offsetParent;\n        }\n        return {x: x, y: y};\n    }\n\n    /**\n     * Initialises the WebGL context\n     * @private\n     */\n    _initWebGL() {\n\n        // Default context attribute values\n\n        if (!this.gl) {\n            for (let i = 0; !this.gl && i < WEBGL_CONTEXT_NAMES.length; i++) {\n                try {\n                    this.gl = this.canvas.getContext(WEBGL_CONTEXT_NAMES[i], this.contextAttr);\n                } catch (e) { // Try with next context name\n                }\n            }\n        }\n\n        if (!this.gl) {\n\n            this.error('Failed to get a WebGL context');\n\n            /**\n             * Fired whenever the canvas failed to get a WebGL context, which probably means that WebGL\n             * is either unsupported or has been disabled.\n             * @event webglContextFailed\n             */\n            this.fire(\"webglContextFailed\", true, true);\n        }\n\n        // data-textures: avoid to re-bind same texture\n        {\n            const gl = this.gl;\n\n            let lastTextureUnit = \"__\";\n\n            let originalActiveTexture = gl.activeTexture;\n\n            gl.activeTexture = function (arg1) {\n                if (lastTextureUnit === arg1) {\n                    return;\n                }\n\n                lastTextureUnit = arg1;\n\n                originalActiveTexture.call (this, arg1);\n            };\n\n            let lastBindTexture = {};\n\n            let originalBindTexture = gl.bindTexture;\n\n            gl.bindTexture = function (arg1, arg2) {\n                if (lastBindTexture[lastTextureUnit] === arg2)\n                {\n                    return;\n                }\n\n                lastBindTexture[lastTextureUnit] = arg2;\n\n                originalBindTexture.call (this, arg1, arg2);\n            };\n\n            // setInterval (\n            //     () => {\n            //         console.log (`${avoidedRebinds} avoided texture binds/sec`);\n            //         avoidedRebinds = 0;\n            //     },\n            //     1000\n            // );\n        }\n\n        if (this.gl) {\n            // Setup extension (if necessary) and hints for fragment shader derivative functions\n            if (this.webgl2) {\n                this.gl.hint(this.gl.FRAGMENT_SHADER_DERIVATIVE_HINT, this.gl.FASTEST);\n\n                // data-textures: not using standard-derivatives\n                if (!(this.gl instanceof WebGL2RenderingContext)) ;\n            }\n        }\n    }\n\n    /**\n     * @private\n     * @deprecated\n     */\n    getSnapshot(params) {\n        throw \"Canvas#getSnapshot() has been replaced by Viewer#getSnapshot() - use that method instead.\";\n    }\n\n    /**\n     * Reads colors of pixels from the last rendered frame.\n     *\n     * Call this method like this:\n     *\n     * ````JavaScript\n     *\n     * var colors = new Float32Array(8);\n     *\n     * viewer.scene.canvas.readPixels([ 100, 22, 12, 33 ], colors, 2);\n     * ````\n     *\n     * Then the r,g,b components of the colors will be set to the colors at those pixels.\n     *\n     * @param {Number[]} pixels\n     * @param {Number[]} colors\n     * @param {Number} size\n     */\n    readPixels(pixels, colors, size) {\n        return this.scene._renderer.snapshot.readPixels(pixels, colors, size);\n    }\n\n    /**\n     * Simulates lost WebGL context.\n     */\n    loseWebGLContext() {\n        if (this.canvas.loseContext) {\n            this.canvas.loseContext();\n        }\n    }\n\n    destroy() {\n        this.scene.off(this._tick);\n        this._spinner._destroy();\n        this.gl = null;\n        super.destroy();\n    }\n}\n\n/**\n * @desc Provides rendering context to {@link Drawable\"}s as xeokit renders them for a frame.\n *\n * Also creates RTC viewing and picking matrices, caching and reusing matrices within each frame.\n *\n * @private\n */\nclass FrameContext {\n\n    constructor(scene) {\n        this._matPool = [];\n        this.reset();\n    }\n\n    /**\n     * Called by the renderer before each frame.\n     * @private\n     */\n    reset() {\n\n        this._matPoolNextFreeIndex = 0;\n        this._rtcViewMats = {};\n\n        /**\n         * ID of the last {@link WebGLProgram} that was bound during the current frame.\n         * @property lastProgramId\n         * @type {Number}\n         */\n        this.lastProgramId = null;\n\n        /**\n         * Whether to render a physically-based representation for triangle surfaces.\n         *\n         * When ````false````, we'll render them with a fast vertex-shaded Gouraud-shaded representation, which\n         * is great for zillions of objects.\n         *\n         * When ````true````, we'll render them at a better visual quality, using smooth, per-fragment shading\n         * and a more realistic lighting model.\n         *\n         * @property quality\n         * @default false\n         * @type {Boolean}\n         */\n        this.pbrEnabled = false;\n\n        /**\n         * Whether to render color textures for triangle surfaces.\n         *\n         * @property quality\n         * @default false\n         * @type {Boolean}\n         */\n        this.colorTextureEnabled = false;\n\n        /**\n         * Whether SAO is currently enabled during the current frame.\n         * @property withSAO\n         * @default false\n         * @type {Boolean}\n         */\n        this.withSAO = false;\n\n        /**\n         * Whether backfaces are currently enabled during the current frame.\n         * @property backfaces\n         * @default false\n         * @type {Boolean}\n         */\n        this.backfaces = false;\n\n        /**\n         * The vertex winding order for what we currently consider to be a backface during current\n         * frame: true == \"cw\", false == \"ccw\".\n         * @property frontFace\n         * @default true\n         * @type {Boolean}\n         */\n        this.frontface = true;\n\n        /**\n         * The next available texture unit to bind a {@link Texture} to.\n         * @defauilt 0\n         * @property textureUnit\n         * @type {number}\n         */\n        this.textureUnit = 0;\n\n        /**\n         * Performance statistic that counts how many times the renderer has called ````gl.drawElements()```` has been\n         * called so far within the current frame.\n         * @default 0\n         * @property drawElements\n         * @type {number}\n         */\n        this.drawElements = 0;\n\n        /**\n         * Performance statistic that counts how many times ````gl.drawArrays()```` has been called so far within\n         * the current frame.\n         * @default 0\n         * @property drawArrays\n         * @type {number}\n         */\n        this.drawArrays = 0;\n\n        /**\n         * Performance statistic that counts how many times ````gl.useProgram()```` has been called so far within\n         * the current frame.\n         * @default 0\n         * @property useProgram\n         * @type {number}\n         */\n        this.useProgram = 0;\n\n        /**\n         * Statistic that counts how many times ````gl.bindTexture()```` has been called so far within the current frame.\n         * @default 0\n         * @property bindTexture\n         * @type {number}\n         */\n        this.bindTexture = 0;\n\n        /**\n         * Counts how many times the renderer has called ````gl.bindArray()```` so far within the current frame.\n         * @defaulr 0\n         * @property bindArray\n         * @type {number}\n         */\n        this.bindArray = 0;\n\n        /**\n         * Indicates which pass the renderer is currently rendering.\n         *\n         * See {@link Scene/passes:property\"}}Scene#passes{{/crossLink}}, which configures how many passes we render\n         * per frame, which typically set to ````2```` when rendering a stereo view.\n         *\n         * @property pass\n         * @type {number}\n         */\n        this.pass = 0;\n\n        this.viewParams = { };\n\n        /**\n         * The 4x4 view matrix.\n         *\n         * @property viewMatrix\n         * @type {Number[]}\n         */\n        this.viewParams.viewMatrix = null;\n\n        /**\n         * The 4x4 projection matrix.\n         *\n         * @property projMatrix\n         * @type {Number[]}\n         */\n        this.viewParams.projMatrix = null;\n\n        /**\n         * Distance to the near clipping plane when rendering depth fragments for GPU-accelerated 3D picking.\n         *\n         * @property near\n         * @type {Number|*}\n         */\n        this.viewParams.near = 0.01;\n\n        /**\n         * Distance to the far clipping plane when rendering depth fragments for GPU-accelerated 3D picking.\n         *\n         * @property far\n         * @type {Number|*}\n         */\n        this.viewParams.far = 5000;\n\n        /**\n         * Whether or not the renderer is currently picking invisible objects.\n         *\n         * @property pickInvisible\n         * @type {Number}\n         */\n        this.pickInvisible = false;\n\n        /** The current line width.\n         *\n         * @property lineWidth\n         * @type Number\n         */\n        this.lineWidth = 1;\n\n        /**\n         * Collects info from SceneModel.drawSnapInit and SceneModel.drawSnap,\n         * which is then used in Renderer to determine snap-picking results.\n         *\n         * @type {[]}\n         */\n        this.snapPickLayerParams = [];\n\n        /**\n         * Collects info from SceneModel.drawSnapInit and SceneModel.drawSnap,\n         * which is then used in Renderer to determine snap-picking results.\n         * @type {Number[]}\n         */\n        this.snapPickCoordinateScale = math.vec3();\n\n        /**\n         * Collects info from SceneModel.drawSnapInit and SceneModel.drawSnap,\n         * which is then used in Renderer to determine snap-picking results.\n         * @type {Number[]}\n         */\n        this.snapPickOrigin = math.vec3();\n    }\n\n    /**\n     * Get View matrix for the given RTC center.\n     */\n    getRTCViewMatrix(originHash, origin) {\n        let rtcViewMat = this._rtcViewMats[originHash];\n        if (!rtcViewMat) {\n            rtcViewMat = this._getNewMat();\n            createRTCViewMat(this.viewParams.viewMatrix, origin, rtcViewMat);\n            this._rtcViewMats[originHash] = rtcViewMat;\n        }\n        return rtcViewMat;\n    }\n\n    _getNewMat() {\n        let mat = this._matPool[this._matPoolNextFreeIndex];\n        if (!mat) {\n            mat = math.mat4();\n            this._matPool[this._matPoolNextFreeIndex] = mat;\n        }\n        this._matPoolNextFreeIndex++;\n        return mat;\n    }\n}\n\n/**\n * @private\n * @type {{WEBGL: boolean, SUPPORTED_EXTENSIONS: {}}}\n */\nconst WEBGL_INFO = {\n    WEBGL: false,\n    SUPPORTED_EXTENSIONS: {}\n};\n\nconst canvas = document.createElement(\"canvas\");\n\nif (canvas) {\n\n    const gl = canvas.getContext(\"webgl\", {antialias: true}) || canvas.getContext(\"experimental-webgl\", {antialias: true});\n\n    WEBGL_INFO.WEBGL = !!gl;\n\n    if (WEBGL_INFO.WEBGL) {\n        WEBGL_INFO.ANTIALIAS = gl.getContextAttributes().antialias;\n        if (gl.getShaderPrecisionFormat) {\n            if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) {\n                WEBGL_INFO.FS_MAX_FLOAT_PRECISION = \"highp\";\n            } else if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) {\n                WEBGL_INFO.FS_MAX_FLOAT_PRECISION = \"mediump\";\n            } else {\n                WEBGL_INFO.FS_MAX_FLOAT_PRECISION = \"lowp\";\n            }\n        } else {\n            WEBGL_INFO.FS_MAX_FLOAT_PRECISION = \"mediump\";\n        }\n        WEBGL_INFO.DEPTH_BUFFER_BITS = gl.getParameter(gl.DEPTH_BITS);\n        WEBGL_INFO.MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n        WEBGL_INFO.MAX_CUBE_MAP_SIZE = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);\n        WEBGL_INFO.MAX_RENDERBUFFER_SIZE = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);\n        WEBGL_INFO.MAX_TEXTURE_UNITS = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);\n        WEBGL_INFO.MAX_TEXTURE_IMAGE_UNITS = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);\n        WEBGL_INFO.MAX_VERTEX_ATTRIBS = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);\n        WEBGL_INFO.MAX_VERTEX_UNIFORM_VECTORS = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);\n        WEBGL_INFO.MAX_FRAGMENT_UNIFORM_VECTORS = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS);\n        WEBGL_INFO.MAX_VARYING_VECTORS = gl.getParameter(gl.MAX_VARYING_VECTORS);\n        gl.getSupportedExtensions().forEach(function (ext) {\n            WEBGL_INFO.SUPPORTED_EXTENSIONS[ext] = true;\n        });\n    }\n}\n\n/**\n * @private\n */\nclass OcclusionLayer {\n\n    constructor(origin) {\n        this.aabb = math.AABB3();\n        this.origin = math.vec3(origin);\n        this.originHash = this.origin.join();\n        this.numMarkers = 0;\n        this.markers = {};\n        this.markerList = [];                  // Ordered array of Markers\n        this.markerIndices = {};               // ID map of Marker indices in _markerList\n        this.positions = [];                   // Packed array of World-space marker positions\n        this.indices = [];                     // Indices corresponding to array above\n        this.positionsBuf = null;\n        this.lenPositionsBuf = 0;\n        this.indicesBuf = null;\n        this.sectionPlanesActive = [];\n        this.occlusionTestList = [];           // List of\n        this.lenOcclusionTestList = 0;\n        this.pixels = [];\n        this.markerListDirty = false;\n        this.positionsDirty = true;\n        this.occlusionTestListDirty = false;\n    }\n\n    addMarker(marker) {\n        this.markers[marker.id] = marker;\n        this.markerListDirty = true;\n        this.numMarkers++;\n    }\n\n    markerWorldPosUpdated(marker) {\n        if (!this.markers[marker.id]) { // Not added\n            return;\n        }\n        const i = this.markerIndices[marker.id];\n        this.positions[i * 3 + 0] = marker.worldPos[0];\n        this.positions[i * 3 + 1] = marker.worldPos[1];\n        this.positions[i * 3 + 2] = marker.worldPos[2];\n        this.positionsDirty = true; // TODO: avoid reallocating VBO each time\n    }\n\n    removeMarker(marker) {\n        delete this.markers[marker.id];\n        this.markerListDirty = true;\n        this.numMarkers--;\n    }\n\n    update(gl, markerInView) {\n        if (this.markerListDirty) {\n            this.numMarkers = 0;\n            for (var id in this.markers) {\n                if (this.markers.hasOwnProperty(id)) {\n                    this.markerList[this.numMarkers] = this.markers[id];\n                    this.markerIndices[id] = this.numMarkers;\n                    this.numMarkers++;\n                }\n            }\n            this.markerList.length = this.numMarkers;\n            this.markerListDirty = false;\n            this.positionsDirty = true;\n            this.occlusionTestListDirty = true;\n        }\n\n        if (this.positionsDirty) { //////////////  TODO: Don't rebuild this when positions change, very wasteful\n            let j = 0;\n            for (let i = 0; i < this.numMarkers; i++) {\n                if (this.markerList[i]) {\n                    const marker = this.markerList[i];\n                    const worldPos = marker.rtcPos;\n                    this.positions[j++] = worldPos[0];\n                    this.positions[j++] = worldPos[1];\n                    this.positions[j++] = worldPos[2];\n                    this.indices[i] = i;\n                }\n            }\n            this.positions.length = this.numMarkers * 3;\n            this.indices.length = this.numMarkers;\n            this.positionsDirty = false;\n\n            const aabb = this.aabb;\n            math.collapseAABB3(aabb);\n            math.expandAABB3Points3(aabb, this.positions);\n            const origin = this.origin;\n            aabb[0] += origin[0];\n            aabb[1] += origin[1];\n            aabb[2] += origin[2];\n            aabb[3] += origin[0];\n            aabb[4] += origin[1];\n            aabb[5] += origin[2];\n\n            if (this.positionsBuf && (this.lenPositionsBuf !== this.positions.length)) {\n                this.positionsBuf.destroy();\n                this.positionsBuf = null;\n                this.indicesBuf.destroy();\n                this.indicesBuf = null;\n            }\n\n            const positionsArr = new Float32Array(this.positions);\n            if (this.positionsBuf) {\n                this.positionsBuf.setData(positionsArr); // Just updating buffer elements, don't need to reallocate; Indices don't need updating\n            } else {\n                this.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, positionsArr, positionsArr.length, 3, gl.STATIC_DRAW);\n                this.indicesBuf = new ArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.indices), this.indices.length, 1, gl.STATIC_DRAW);\n                this.lenPositionsBuf = this.positions.length;\n            }\n        }\n\n        if (this.occlusionTestListDirty) {\n            let lenPixels = 0;\n            this.lenOcclusionTestList = 0;\n            for (let i = 0; i < this.numMarkers; i++) {\n                const marker = this.markerList[i];\n                if ((marker.entity && !marker.entity.visible) || (! markerInView(marker))) {\n                    marker._setVisible(false);\n                } else if (marker.occludable) {\n                    this.occlusionTestList[this.lenOcclusionTestList++] = marker;\n                    this.pixels[lenPixels++] = marker.canvasPos[0];\n                    this.pixels[lenPixels++] = marker.canvasPos[1];\n                } else {\n                    marker._setVisible(true);\n                }\n            }\n        }\n    }\n\n    destroy() {\n        this.markers = {};\n        this.markerList.length = 0;\n        if (this.positionsBuf) {\n            this.positionsBuf.destroy();\n        }\n        if (this.indicesBuf) {\n            this.indicesBuf.destroy();\n        }\n    }\n}\n\nconst MARKER_COLOR = math.vec3([ 255, 0, 0 ]);\n\nmath.vec3();\n\n/**\n * Manages occlusion testing. Private member of a Renderer.\n * @private\n */\nclass OcclusionTester {\n\n    constructor(scene) {\n\n        this._scene = scene;\n\n        this._occlusionLayers = {};\n        this._occlusionLayersList = [];\n        this._occlusionLayersListDirty = false;\n\n        this._drawable = null;\n\n        this._markersToOcclusionLayersMap = {};\n\n        const camera = scene.camera;\n        const markOcclusionTestListDirty = () => { this._occlusionTestListDirty = true; };\n        this._onCameraViewMatrix = camera.on(\"viewMatrix\",   markOcclusionTestListDirty);\n        this._onCameraProjMatrix = camera.on(\"projMatrix\",   markOcclusionTestListDirty);\n        this._onCanvasBoundary = scene.canvas.on(\"boundary\", markOcclusionTestListDirty);\n    }\n\n    _addMarker(marker, originHash) {\n        if (! this._occlusionLayers[originHash]) {\n            this._occlusionLayers[originHash] = new OcclusionLayer(marker.origin);\n            this._occlusionLayersListDirty = true;\n        }\n        const occlusionLayer = this._occlusionLayers[originHash];\n        occlusionLayer.addMarker(marker);\n        this._markersToOcclusionLayersMap[marker.id] = occlusionLayer;\n    }\n\n    _removeMarker(occlusionLayer, marker) {\n        if (occlusionLayer.numMarkers === 1) {\n            occlusionLayer.destroy();\n            delete this._occlusionLayers[occlusionLayer.originHash];\n            this._occlusionLayersListDirty = true;\n        } else {\n            occlusionLayer.removeMarker(marker);\n        }\n        delete this._markersToOcclusionLayersMap[marker.id];\n    }\n\n    /**\n     * Adds a Marker for occlusion testing.\n     * @param marker\n     */\n    addMarker(marker) {\n        const originHash = marker.origin.join();\n        this._addMarker(marker, originHash);\n        this._occlusionTestListDirty = true;\n    }\n\n    /**\n     * Notifies OcclusionTester that a Marker has updated its World-space position.\n     * @param marker\n     */\n    markerWorldPosUpdated(marker) {\n        const occlusionLayer = this._markersToOcclusionLayersMap[marker.id];\n        if (occlusionLayer) {\n            const originHash = marker.origin.join();\n            if (originHash !== occlusionLayer.originHash) {\n                this._removeMarker(occlusionLayer, marker);\n                this._addMarker(marker, originHash);\n            } else {\n                occlusionLayer.markerWorldPosUpdated(marker);\n            }\n        }\n    }\n\n    /**\n     * Removes a Marker from occlusion testing.\n     * @param marker\n     */\n    removeMarker(marker) {\n        const originHash = marker.origin.join();\n        const occlusionLayer = this._occlusionLayers[originHash];\n        if (occlusionLayer) {\n            this._removeMarker(occlusionLayer, marker);\n        }\n    }\n\n    /**\n     * Returns true if an occlusion test is needed.\n     *\n     * @returns {Boolean}\n     */\n    get needOcclusionTest() {\n        return this._occlusionTestListDirty;\n    }\n\n    /**\n     * Draws {@link Marker}s to the render buffer.\n     */\n    drawMarkers() {\n\n        const scene = this._scene;\n        const canvas = scene.canvas;\n        const gl = canvas.gl;\n        const sectionPlanesState = scene._sectionPlanesState;\n        const shaderSourceHash = [canvas.canvas.id, sectionPlanesState.getHash()].join(\";\");\n\n        if ((! this._drawable) || (shaderSourceHash !== this._drawable.shaderSourceHash)) {\n            if (this._drawable) {\n                this._drawable.destroy();\n            }\n\n            const programVariablesState = createProgramVariablesState();\n\n            const programVariables = programVariablesState.programVariables;\n            const viewMatrix = programVariables.createUniform(\"mat4\",  \"viewMatrix\");\n            const projMatrix = programVariables.createUniform(\"mat4\",  \"projMatrix\");\n            const position   = programVariables.createAttribute(\"vec3\", \"position\");\n            const outColor   = programVariables.createOutput(\"vec4\", \"outColor\");\n            const clipPos    = \"clipPos\";\n\n            const [program, errors] = programVariablesState.buildProgram(\n                gl,\n                \"OcclusionTester\",\n                {\n                    sectionPlanesState: sectionPlanesState,\n                    getLogDepth: scene.logarithmicDepthBufferEnabled && (vFragDepth => vFragDepth),\n                    clippableTest: () => \"true\",\n                    getVertexData: () => {\n                        const src = [ ];\n                        src.push(`vec4 worldPosition = vec4(${position}, 1.0);`);\n                        src.push(`vec4 ${clipPos} = ${projMatrix} * ${viewMatrix} * worldPosition;`);\n                        if ((! scene.logarithmicDepthBufferEnabled) && (scene.markerZOffset < 0.000)) {\n                            src.push(`${clipPos}.z += ${scene.markerZOffset};`);\n                        }\n                        return src;\n                    },\n                    worldPositionAttribute: \"worldPosition\",\n                    getPointSize: () => \"20.0\",\n                    clipPos: clipPos,\n                    appendFragmentOutputs: (src) => src.push(`${outColor} = vec4(1.0, 0.0, 0.0, 1.0);`)\n                });\n\n            if (errors) {\n                console.error(errors.join(\"\\n\"));\n                throw errors.join(\"\\n\");\n            } else {\n                this._occlusionTestListDirty = true;\n                this._drawable = {\n                    shaderSourceHash: shaderSourceHash,\n                    destroy: () => program.destroy(),\n                    drawCall: () => {\n                        const camera = scene.camera;\n                        const project = camera.project;\n\n                        program.bind();\n\n                        projMatrix.setInputValue(project.matrix);\n\n                        const boundary = canvas.boundary;\n                        const canvasWidth = boundary[2];\n                        const canvasHeight = boundary[3];\n                        const near = camera.perspective.near; // Assume near enough to ortho near\n                        const markerInView = marker => {\n                            const viewPos = marker.viewPos;\n                            const canvasPos = marker.canvasPos;\n                            const canvasX = canvasPos[0];\n                            const canvasY = canvasPos[1];\n                            return (viewPos[2] <= -near) && (canvasX >= -10) && (canvasY >= -10) && (canvasX <= canvasWidth + 10) && (canvasY <= canvasHeight + 10);\n                        };\n\n                        this._occlusionLayersList.forEach(occlusionLayer => {\n                            occlusionLayer.update(gl, markerInView);\n\n                            const culled = sectionPlanesState.sectionPlanes.some((sectionPlane, i) => {\n                                const intersect = sectionPlane.active ? math.planeAABB3Intersect(sectionPlane.dir, sectionPlane.dist, occlusionLayer.aabb) : 1;\n                                const outside = (intersect === -1);\n                                occlusionLayer.sectionPlanesActive[i] = (intersect === 0); // if outside, then sectionPlanesActive won't be even tested\n                                return outside;\n                            });\n\n                            if (! culled) {\n                                const origin = occlusionLayer.origin;\n\n                                viewMatrix.setInputValue(createRTCViewMat(camera.viewMatrix, origin));\n\n                                program.inputSetters.setUniforms(\n                                    null,\n                                    {\n                                        view: { far: project.far },\n                                        mesh: {\n                                            origin: origin,\n                                            renderFlags: { sectionPlanesActivePerLayer: occlusionLayer.sectionPlanesActive }\n                                        }\n                                    });\n\n                                position.setInputValue(occlusionLayer.positionsBuf);\n\n                                const indicesBuf = occlusionLayer.indicesBuf;\n                                indicesBuf.bind();\n                                gl.drawElements(gl.POINTS, indicesBuf.numItems, indicesBuf.itemType, 0);\n                            }\n                        });\n                    }\n                };\n            }\n        }\n\n        if (this._occlusionLayersListDirty) {\n            let numOcclusionLayers = 0;\n            for (let originHash in this._occlusionLayers) {\n                if (this._occlusionLayers.hasOwnProperty(originHash)) {\n                    this._occlusionLayersList[numOcclusionLayers++] = this._occlusionLayers[originHash];\n                }\n            }\n            this._occlusionLayersList.length = numOcclusionLayers;\n            this._occlusionLayersListDirty = false;\n        }\n\n        if (this._occlusionTestListDirty) {\n            for (let i = 0, len = this._occlusionLayersList.length; i < len; i++) {\n                const occlusionLayer = this._occlusionLayersList[i];\n                occlusionLayer.occlusionTestListDirty = true;\n            }\n            this._occlusionTestListDirty = false;\n        }\n\n        this._drawable.drawCall();\n    }\n\n    /**\n     * Sets visibilities of {@link Marker}s according to whether or not they are obscured by anything in the render buffer.\n     */\n    doOcclusionTest(readColorPixel) {\n        this._occlusionLayersList.forEach(occlusionLayer => {\n            for (let i = 0; i < occlusionLayer.lenOcclusionTestList; i++) {\n                const j = i * 2;\n                const color = readColorPixel(occlusionLayer.pixels[j], occlusionLayer.pixels[j + 1]);\n                occlusionLayer.occlusionTestList[i]._setVisible(math.compareVec3(MARKER_COLOR, color));\n            }\n        });\n    }\n\n    /**\n     * Destroys this OcclusionTester.\n     */\n    destroy() {\n        if (! this.destroyed) {\n            this._occlusionLayersList.forEach(layer => layer.destroy());\n            this._drawable && this._drawable.destroy();\n            this._scene.camera.off(this._onCameraViewMatrix);\n            this._scene.camera.off(this._onCameraProjMatrix);\n            this._scene.canvas.off(this._onCanvasBoundary);\n            this.destroyed = true;\n        }\n    }\n}\n\nconst vec3_0 = math.vec3([0,0,0]);\n\nconst iota = (n) => { const ret = [ ]; for (let i = 0; i < n; ++i) ret.push(i); return ret; };\n\nconst tempPlanes = iota(6).map(() => math.vec4());\nconst tempVec4 = math.vec4();\n\nconst bitShiftScreenZ = math.vec4([1.0 / (256.0 * 256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0]);\n\nconst pixelToInt = pix => pix[0] + (pix[1] << 8) + (pix[2] << 16) + (pix[3] << 24);\n\nconst toWorldNormal = (n) => math.normalizeVec3(math.divVec3Scalar(n, math.MAX_INT, math.vec3()));\nconst toWorldPos    = (p, origin, scale) => math.vec3([ p[0] * scale[0] + origin[0],\n                                                        p[1] * scale[1] + origin[1],\n                                                        p[2] * scale[2] + origin[2] ]);\n\nconst makeFrustumAABBIntersectionTest = function(camera) {\n    const m = math.mat4();\n    math.mulMat4(camera.projMatrix, camera.viewMatrix, m);\n\n    for (let i = 0; i < 3; ++i) {\n        tempPlanes[i * 2 + 0][0] = m[ 3] + m[i];\n        tempPlanes[i * 2 + 0][1] = m[ 7] + m[i + 4];\n        tempPlanes[i * 2 + 0][2] = m[11] + m[i + 8];\n        tempPlanes[i * 2 + 0][3] = m[15] + m[i + 12];\n\n        tempPlanes[i * 2 + 1][0] = m[ 3] - m[i];\n        tempPlanes[i * 2 + 1][1] = m[ 7] - m[i + 4];\n        tempPlanes[i * 2 + 1][2] = m[11] - m[i + 8];\n        tempPlanes[i * 2 + 1][3] = m[15] - m[i + 12];\n    }\n\n    // Normalize each plane\n    tempPlanes.forEach(p => math.divVec4Scalar(p, math.lenVec3(p), p));\n\n    return aabb => tempPlanes.every(p => {\n        // Compute the positive vertex (farthest in direction of normal)\n        tempVec4[0] = aabb[(p[0] >= 0) ? 3 : 0];\n        tempVec4[1] = aabb[(p[1] >= 0) ? 4 : 1];\n        tempVec4[2] = aabb[(p[2] >= 0) ? 5 : 2];\n        tempVec4[3] = 1;\n        return math.dotVec4(p, tempVec4) >= 0;\n    });\n};\n\nconst makeRayAABBIntersectionTest = (O, D) => aabb => {\n    let tmin = -Infinity;\n    let tmax = Infinity;\n\n    for (let i = 0; i < 3; i++) {\n        const origin = O[i];\n        const direction = D[i];\n        const minBound = aabb[i];\n        const maxBound = aabb[i + 3];\n\n        if (Math.abs(direction) < 1e-8) {\n            // Ray is parallel to plane\n            if ((origin < minBound) || (origin > maxBound)) {\n                return false; // No intersection\n            }\n        } else {\n            const t1 = (minBound - origin) / direction;\n            const t2 = (maxBound - origin) / direction;\n\n            tmin = Math.max(tmin, Math.min(t1, t2)); // near\n            tmax = Math.min(tmax, Math.max(t1, t2)); // far\n\n            if (tmin > tmax) {\n                return false; // No intersection\n            }\n        }\n    }\n\n    return tmax >= 0; // Check if intersection is in front of ray\n};\n\n/**\n * @private\n */\nconst Renderer$1 = function (scene, options) {\n\n    options = options || {};\n\n    const frameCtx = new FrameContext();\n    const canvas = scene.canvas.canvas;\n    /**\n     * @type {WebGL2RenderingContext}\n     */\n    const gl = scene.canvas.gl;\n    const canvasTransparent = (!!options.transparent);\n    const alphaDepthMask = options.alphaDepthMask;\n\n    const pickIDs = new Map$1({});\n\n    let drawableTypeInfo = {};\n    let drawables = {};\n\n    let postSortDrawableList = [];\n    let postCullDrawableList = [];\n    let uiDrawableList       = [];\n\n    let drawableListDirty = true;\n    let stateSortDirty = true;\n    let imageDirty = true;\n\n    let transparentEnabled = true;\n    let edgesEnabled = true;\n    let saoEnabled = true;\n    let pbrEnabled = true;\n    let colorTextureEnabled = true;\n\n    const renderBufferManager = (function() {\n        const renderBuffersBasic  = {};\n        const renderBuffersScaled = {};\n        return {\n            getRenderBuffer: (id, colorFormats, hasDepthTexture) => {\n                const renderBuffers = (scene.canvas.resolutionScale === 1.0) ? renderBuffersBasic : renderBuffersScaled;\n                if (! renderBuffers[id]) {\n                    renderBuffers[id] = new RenderBuffer(gl, colorFormats, hasDepthTexture);\n                }\n                return renderBuffers[id];\n            },\n            destroy: () => {\n                Object.values(renderBuffersBasic ).forEach(buf => buf.destroy());\n                Object.values(renderBuffersScaled).forEach(buf => buf.destroy());\n            }\n        };\n    })();\n\n    const SAOProgram = (gl, name, programVariablesState, createOutColorDefinition) => {\n        const programVariables = programVariablesState.programVariables;\n\n        const uViewportInv   = programVariables.createUniform(\"vec2\", \"uViewportInv\");\n        const uCameraNear    = programVariables.createUniform(\"float\", \"uCameraNear\");\n        const uCameraFar     = programVariables.createUniform(\"float\", \"uCameraFar\");\n        const uDepthTexture  = programVariables.createUniform(\"sampler2D\", \"uDepthTexture\");\n\n        const uv       = programVariables.createAttribute(\"vec2\", \"uv\");\n        const vUV      = programVariables.createVarying(\"vec2\", \"vUV\", () => uv);\n        const outColor = programVariables.createOutput(\"vec4\", \"outColor\");\n\n        const getOutColor = programVariables.createFragmentDefinition(\n            \"getOutColor\",\n            (name, src) => {\n                const getDepth = \"getDepth\";\n                src.push(`\n                float ${getDepth}(const in vec2 uv) {\n                    return texture(${uDepthTexture}, uv).r;\n                }\n            `);\n                src.push(createOutColorDefinition(name, vUV, uViewportInv, uCameraNear, uCameraFar, getDepth));\n            });\n\n        const [program, errors] = programVariablesState.buildProgram(\n            gl,\n            name,\n            {\n                clipPos: `vec4(2.0 * ${uv} - 1.0, 0.0, 1.0)`,\n                appendFragmentOutputs: (src) => src.push(`${outColor} = ${getOutColor}();`)\n            });\n\n        if (errors) {\n            console.error(errors.join(\"\\n\"));\n            throw errors;\n        } else {\n            const uvs = new Float32Array([1,1, 0,1, 0,0, 1,0]);\n            const uvBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, uvs, uvs.length, 2, gl.STATIC_DRAW);\n\n            // Mitigation: if Uint8Array is used, the geometry is corrupted on OSX when using Chrome with data-textures\n            const indices = new Uint32Array([0, 1, 2, 0, 2, 3]);\n            const indicesBuf = new ArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, indices, indices.length, 1, gl.STATIC_DRAW);\n\n            return {\n                destroy: program.destroy,\n                bind:    (viewportSize, project, depthTexture) => {\n                    program.bind();\n                    uViewportInv.setInputValue([1 / viewportSize[0], 1 / viewportSize[1]]);\n                    uCameraNear.setInputValue(project.near);\n                    uCameraFar.setInputValue(project.far);\n                    uDepthTexture.setInputValue(depthTexture);\n                    uv.setInputValue(uvBuf);\n                },\n                draw:    () => {\n                    indicesBuf.bind();\n                    gl.drawElements(gl.TRIANGLES, indicesBuf.numItems, indicesBuf.itemType, 0);\n                }\n            };\n        }\n    };\n\n    // SAO implementation inspired from previous SAO work in THREE.js by ludobaka / ludobaka.github.io and bhouston\n    const saoOcclusionRenderer = (function() {\n        let currentRenrerer = null;\n        let curNumSamples = null;\n        return {\n            destroy: () => currentRenrerer && currentRenrerer.destroy(),\n            render: (viewportSize, project, sao, depthTexture) => {\n                const numSamples = Math.floor(sao.numSamples);\n                if (curNumSamples !== numSamples) {\n                    currentRenrerer && currentRenrerer.destroy();\n\n                    const programVariablesState = createProgramVariablesState();\n\n                    const programVariables = programVariablesState.programVariables;\n\n                    const uProjectMatrix = programVariables.createUniform(\"mat4\", \"uProjectMatrix\");\n                    const uInvProjMatrix = programVariables.createUniform(\"mat4\", \"uInvProjMatrix\");\n                    const uPerspective   = programVariables.createUniform(\"bool\", \"uPerspective\");\n                    const uScale         = programVariables.createUniform(\"float\", \"uScale\");\n                    const uIntensity     = programVariables.createUniform(\"float\", \"uIntensity\");\n                    const uBias          = programVariables.createUniform(\"float\", \"uBias\");\n                    const uKernelRadius  = programVariables.createUniform(\"float\", \"uKernelRadius\");\n                    const uMinResolution = programVariables.createUniform(\"float\", \"uMinResolution\");\n                    const uRandomSeed    = programVariables.createUniform(\"float\", \"uRandomSeed\");\n\n                    const program = SAOProgram(\n                        gl,\n                        \"SAOOcclusionRenderer\",\n                        programVariablesState,\n                        (name, vUV, uViewportInv, uCameraNear, uCameraFar, getDepth) => {\n                            return `\n                                #define EPSILON 1e-6\n                                #define PI 3.14159265359\n                                #define PI2 6.28318530718\n                                #define NUM_SAMPLES ${numSamples}\n                                #define NUM_RINGS 4\n\n                                const vec3 packFactors = vec3(256. * 256. * 256., 256. * 256., 256.);\n\n                                vec4 packFloatToRGBA(const in float v) {\n                                    vec4 r = vec4(fract(v * packFactors), v);\n                                    r.yzw -= r.xyz / 256.;\n                                    return r * 256. / 255.;\n                                }\n\n                                highp float rand(const in vec2 uv) {\n                                    const highp float a = 12.9898, b = 78.233, c = 43758.5453;\n                                    return fract(sin(mod(dot(uv, vec2(a, b)), PI)) * c);\n                                }\n\n                                vec3 getViewPos(const in vec2 screenPos, const in float depth) {\n                                    float near = ${uCameraNear};\n                                    float far  = ${uCameraFar};\n                                    float viewZ = (${uPerspective}\n                                                   ? ((near * far) / ((far - near) * depth - far))\n                                                   : (depth * (near - far) - near));\n                                    float clipW = ${uProjectMatrix}[2][3] * viewZ + ${uProjectMatrix}[3][3];\n                                    return (${uInvProjMatrix} * (clipW * vec4((vec3(screenPos, depth) - 0.5) * 2.0, 1.0))).xyz;\n                                }\n\n                                vec4 ${name}() {\n                                    float centerDepth = ${getDepth}(${vUV});\n                                    if (centerDepth >= (1.0 - EPSILON)) {\n                                        discard;\n                                    }\n\n                                    vec3 centerViewPosition = getViewPos(${vUV}, centerDepth);\n                                    float scaleDividedByCameraFar = ${uScale} / ${uCameraFar};\n                                    float minResolutionMultipliedByCameraFar = ${uMinResolution} * ${uCameraFar};\n                                    vec3 centerViewNormal = normalize(cross(dFdx(centerViewPosition), dFdy(centerViewPosition)));\n\n                                    vec2 radiusStep = ${uKernelRadius} * ${uViewportInv} / float(NUM_SAMPLES);\n                                    vec2 radius = radiusStep;\n                                    const float angleStep = PI2 * float(NUM_RINGS) / float(NUM_SAMPLES);\n                                    float angle = PI2 * rand(${vUV} + ${uRandomSeed});\n\n                                    float occlusionSum = 0.0;\n                                    float weightSum = 0.0;\n\n                                    for (int i = 0; i < NUM_SAMPLES; i++) {\n                                        vec2 sampleUv = ${vUV} + vec2(cos(angle), sin(angle)) * radius;\n                                        radius += radiusStep;\n                                        angle += angleStep;\n\n                                        float sampleDepth = ${getDepth}(sampleUv);\n                                        if (sampleDepth >= (1.0 - EPSILON)) {\n                                            continue;\n                                        }\n\n                                        vec3 sampleViewPosition = getViewPos(sampleUv, sampleDepth);\n                                        vec3 viewDelta = sampleViewPosition - centerViewPosition;\n                                        float scaledScreenDistance = scaleDividedByCameraFar * length(viewDelta);\n                                        occlusionSum += max(0.0, (dot(centerViewNormal, viewDelta) - minResolutionMultipliedByCameraFar) / scaledScreenDistance - ${uBias}) / (1.0 + scaledScreenDistance * scaledScreenDistance );\n                                        weightSum += 1.0;\n                                    }\n\n                                    return packFloatToRGBA(1.0 - occlusionSum * ${uIntensity} / weightSum);\n                                }`;\n                        });\n\n                    currentRenrerer = {\n                        destroy: program.destroy,\n                        render:  (viewportSize, project, sao, depthTexture) => {\n                            program.bind(viewportSize, project, depthTexture);\n\n                            uProjectMatrix.setInputValue(project.matrix);\n                            uInvProjMatrix.setInputValue(project.inverseMatrix);\n                            uPerspective.setInputValue(project.type === \"Perspective\");\n                            uScale.setInputValue(sao.scale * project.far / 5);\n                            uIntensity.setInputValue(sao.intensity);\n                            uBias.setInputValue(sao.bias);\n                            uKernelRadius.setInputValue(sao.kernelRadius);\n                            uMinResolution.setInputValue(sao.minResolution);\n                            uRandomSeed.setInputValue(Math.random());\n\n                            program.draw();\n                        }\n                    };\n\n                    curNumSamples = numSamples;\n                }\n\n                currentRenrerer.render(viewportSize, project, sao, depthTexture);\n            }\n        };\n    })();\n\n    const saoDepthLimitedBlurRenderer = (function() {\n        const blurStdDev = 4;\n        const blurDepthCutoff = 0.01;\n        const KERNEL_RADIUS = 16;\n\n        const createSampleOffsets = (uvIncrement) => {\n            const offsets = [];\n            for (let i = 0; i <= KERNEL_RADIUS + 1; i++) {\n                offsets.push(uvIncrement[0] * i);\n                offsets.push(uvIncrement[1] * i);\n            }\n            return new Float32Array(offsets);\n        };\n\n        const sampleOffsetsVer = createSampleOffsets([0, 1]);\n        const sampleOffsetsHor = createSampleOffsets([1, 0]);\n\n        const gaussian = (i, stdDev) => Math.exp(-(i * i) / (2.0 * (stdDev * stdDev))) / (Math.sqrt(2.0 * Math.PI) * stdDev);\n        const sampleWeights = new Float32Array(iota(KERNEL_RADIUS + 1).map(i => gaussian(i, blurStdDev))); // TODO: Optimize\n\n        const programVariablesState = createProgramVariablesState();\n\n        const programVariables = programVariablesState.programVariables;\n\n        const uDepthCutoff   = programVariables.createUniform(\"float\", \"uDepthCutoff\");\n        const uSampleOffsets = programVariables.createUniformArray(\"vec2\",  \"uSampleOffsets\", KERNEL_RADIUS + 1);\n        const uSampleWeights = programVariables.createUniformArray(\"float\", \"uSampleWeights\", KERNEL_RADIUS + 1);\n\n        const uOcclusionTex  = programVariables.createUniform(\"sampler2D\", \"uOcclusionTex\");\n\n        const program = SAOProgram(\n            gl,\n            \"SAODepthLimitedBlurRenderer\",\n            programVariablesState,\n            (name, vUV, uViewportInv, uCameraNear, uCameraFar, getDepth) => {\n                return `\n                    #define EPSILON 1e-6\n\n                    const vec3 packFactors = vec3(256. * 256. * 256., 256. * 256., 256.);\n\n                    vec4 packFloatToRGBA(const in float v) {\n                        vec4 r = vec4(fract(v * packFactors), v);\n                        r.yzw -= r.xyz / 256.;\n                        return r * 256. / 255.;\n                    }\n\n                    float getOcclusion(const in vec2 uv) {\n                        vec4 v = texture(${uOcclusionTex}, uv);\n                        return dot(floor(v * 255.0 + 0.5) / 255.0, 255. / 256. / vec4(packFactors, 1.)); // unpackRGBAToFloat\n                    }\n\n                    float getViewZ(const in float depth) {\n                        return (${uCameraNear} * ${uCameraFar}) / ((${uCameraFar} - ${uCameraNear}) * depth - ${uCameraFar});\n                    }\n\n                    vec4 ${name}() {\n                        float centerDepth = ${getDepth}(${vUV});\n                        if (centerDepth >= (1.0 - EPSILON)) {\n                            discard;\n                        }\n\n                        float centerViewZ = getViewZ(centerDepth);\n                        bool rBreak = false;\n                        bool lBreak = false;\n\n                        float weightSum = ${uSampleWeights}[0];\n                        float occlusionSum = getOcclusion(${vUV}) * weightSum;\n\n                        for (int i = 1; i <= ${KERNEL_RADIUS}; i++) {\n                            float sampleWeight = ${uSampleWeights}[i];\n                            vec2 sampleUVOffset = ${uSampleOffsets}[i] * ${uViewportInv};\n\n                            if (! rBreak) {\n                                vec2 rSampleUV = ${vUV} + sampleUVOffset;\n                                if (abs(centerViewZ - getViewZ(${getDepth}(rSampleUV))) > ${uDepthCutoff}) {\n                                    rBreak = true;\n                                } else {\n                                    occlusionSum += getOcclusion(rSampleUV) * sampleWeight;\n                                    weightSum += sampleWeight;\n                                }\n                            }\n\n                            if (! lBreak) {\n                                vec2 lSampleUV = ${vUV} - sampleUVOffset;\n                                if (abs(centerViewZ - getViewZ(${getDepth}(lSampleUV))) > ${uDepthCutoff}) {\n                                    lBreak = true;\n                                } else {\n                                    occlusionSum += getOcclusion(lSampleUV) * sampleWeight;\n                                    weightSum += sampleWeight;\n                                }\n                            }\n                        }\n\n                        return packFloatToRGBA(occlusionSum / weightSum);\n                    }`;\n            });\n\n        return {\n            destroy: program.destroy,\n            render:  (viewportSize, project, direction, depthTexture, occlusionTexture) => {\n                program.bind(viewportSize, project, depthTexture);\n\n                uDepthCutoff.setInputValue(blurDepthCutoff);\n                uSampleOffsets.setInputValue((direction === 0) ? sampleOffsetsHor : sampleOffsetsVer);\n                uSampleWeights.setInputValue(sampleWeights);\n                uOcclusionTex.setInputValue(occlusionTexture);\n\n                program.draw();\n            }\n        };\n    })();\n\n    const getSceneCameraViewParams = (function() {\n        let params = null; // scene.camera not defined yet\n        return function() {\n            if (! params) {\n                const camera = scene.camera;\n                params = {\n                    get eye() { return camera.eye; },\n                    get far() { return camera.project.far; },\n                    get projMatrix() { return camera.projMatrix; },\n                    get viewMatrix() { return camera.viewMatrix; },\n                    get viewNormalMatrix() { return camera.viewNormalMatrix; }\n                };\n            }\n            return params;\n        };\n    })();\n\n    const getNearPlaneHeight = (camera, drawingBufferHeight) => ((camera.projection === \"ortho\")\n                                                                 ? 1.0\n                                                                 : (drawingBufferHeight / (2 * Math.tan(0.5 * camera.perspective.fov * Math.PI / 180.0))));\n\n    this.scene = scene;\n\n    this._occlusionTester = null; // Lazy-created in #addMarker()\n\n    this.capabilities = {\n        astcSupported: !!getExtension(gl, 'WEBGL_compressed_texture_astc'),\n        etc1Supported: true, // WebGL2\n        etc2Supported: !!getExtension(gl, 'WEBGL_compressed_texture_etc'),\n        dxtSupported: !!getExtension(gl, 'WEBGL_compressed_texture_s3tc'),\n        bptcSupported: !!getExtension(gl, 'EXT_texture_compression_bptc'),\n        pvrtcSupported: !!(getExtension(gl, 'WEBGL_compressed_texture_pvrtc') || getExtension(gl, 'WEBKIT_WEBGL_compressed_texture_pvrtc'))\n    };\n\n    this.setTransparentEnabled = function (enabled) {\n        transparentEnabled = enabled;\n        imageDirty = true;\n    };\n\n    this.setEdgesEnabled = function (enabled) {\n        edgesEnabled = enabled;\n        imageDirty = true;\n    };\n\n    this.setSAOEnabled = function (enabled) {\n        saoEnabled = enabled;\n        imageDirty = true;\n    };\n\n    this.setPBREnabled = function (enabled) {\n        pbrEnabled = enabled;\n        imageDirty = true;\n    };\n\n    this.setColorTextureEnabled = function (enabled) {\n        colorTextureEnabled = enabled;\n        imageDirty = true;\n    };\n\n    this.needStateSort = function () {\n        stateSortDirty = true;\n    };\n\n    this.shadowsDirty = function () {\n    };\n\n    this.imageDirty = function () {\n        imageDirty = true;\n    };\n\n    /**\n     * Inserts a drawable into this renderer.\n     *  @private\n     */\n    this.addDrawable = function (id, drawable) {\n        const type = drawable.type;\n        if (!type) {\n            console.error(\"Renderer#addDrawable() : drawable with ID \" + id + \" has no 'type' - ignoring\");\n            return;\n        }\n        let drawableInfo = drawableTypeInfo[type];\n        if (!drawableInfo) {\n            drawableInfo = {\n                type: drawable.type,\n                count: 0,\n                isStateSortable: drawable.isStateSortable,\n                stateSortCompare: drawable.stateSortCompare,\n                drawableMap: {},\n                drawableListPreCull: [],\n                drawableList: []\n            };\n            drawableTypeInfo[type] = drawableInfo;\n        }\n        drawableInfo.count++;\n        drawableInfo.drawableMap[id] = drawable;\n        drawables[id] = drawable;\n        drawableListDirty = true;\n    };\n\n    /**\n     * Removes a drawable from this renderer.\n     *  @private\n     */\n    this.removeDrawable = function (id) {\n        const drawable = drawables[id];\n        if (!drawable) {\n            console.error(\"Renderer#removeDrawable() : drawable not found with ID \" + id + \" - ignoring\");\n            return;\n        }\n        const type = drawable.type;\n        const drawableInfo = drawableTypeInfo[type];\n        if (--drawableInfo.count <= 0) {\n            delete drawableTypeInfo[type];\n        } else {\n            delete drawableInfo.drawableMap[id];\n        }\n        delete drawables[id];\n        drawableListDirty = true;\n    };\n\n    /**\n     * Gets a unique pick ID for the given Pickable. A Pickable can be a {@link Mesh} or a {@link PerformanceMesh}.\n     * @returns {Number} New pick ID.\n     */\n    this.getPickID = function (entity) {\n        return pickIDs.addItem(entity);\n    };\n\n    /**\n     * Released a pick ID for reuse.\n     * @param {Number} pickID Pick ID to release.\n     */\n    this.putPickID = function (pickID) {\n        pickIDs.removeItem(pickID);\n    };\n\n    /**\n     * Clears the canvas.\n     *  @private\n     */\n    this.clear = function (params) {\n        gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n        if (canvasTransparent) {\n            gl.clearColor(1, 1, 1, 1);\n        } else {\n            const backgroundColor = scene.canvas.backgroundColorFromAmbientLight ? this.lights.getAmbientColorAndIntensity() : scene.canvas.backgroundColor;\n            gl.clearColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], 1.0);\n        }\n        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n    };\n\n    /**\n     * Returns true if the next call to render() will draw something\n     * @returns {Boolean}\n     */\n    this.needsRender = function () {\n        const needsRender = (imageDirty || drawableListDirty || stateSortDirty);\n        return needsRender;\n    };\n\n    /**\n     * Renders inserted drawables.\n     *  @private\n     */\n    this.render = function(pass, clear) {\n        updateDrawlist();\n        if (imageDirty) {\n            draw(pass, clear);\n            stats.frame.frameCount++;\n            imageDirty = false;\n        }\n    };\n\n    function updateDrawlist() { // Prepares state-sorted array of drawables from maps of inserted drawables\n        if (drawableListDirty) {\n            Object.values(drawableTypeInfo).forEach(drawableInfo => {\n                const drawableListPreCull = drawableInfo.drawableListPreCull;\n                let lenDrawableList = 0;\n                Object.values(drawableInfo.drawableMap).forEach(drawable => { drawableListPreCull[lenDrawableList++] = drawable; });\n                drawableListPreCull.length = lenDrawableList;\n            });\n            drawableListDirty = false;\n            stateSortDirty = true;\n        }\n        if (stateSortDirty) {\n            let lenDrawableList = 0;\n            Object.values(drawableTypeInfo).forEach(drawableInfo => {\n                drawableInfo.drawableListPreCull.forEach(drawable => { postSortDrawableList[lenDrawableList++] = drawable; });\n            });\n            postSortDrawableList.length = lenDrawableList;\n            postSortDrawableList.sort((a, b) => a.renderOrder - b.renderOrder);\n            stateSortDirty = false;\n            imageDirty = true;\n        }\n        if (imageDirty) { // Image is usually dirty because the camera moved\n            let lenDrawableList = 0;\n            let lenUiList       = 0;\n            postSortDrawableList.forEach(drawable => {\n                drawable.rebuildRenderFlags();\n                if (!drawable.renderFlags.culled) {\n                    if (drawable.isUI) {\n                        uiDrawableList[lenUiList++] = drawable;\n                    } else {\n                        postCullDrawableList[lenDrawableList++] = drawable;\n                    }\n                }\n            });\n            postCullDrawableList.length = lenDrawableList;\n            uiDrawableList.length       = lenUiList;\n        }\n    }\n\n    function draw(pass, clear) {\n\n        const sao = scene.sao;\n        const occlusionTexture = saoEnabled && sao.possible && (sao.numSamples >= 1) && drawSAOBuffers(pass);\n\n        scene._lightsState.lights.forEach(light => {\n\n            if (light.castsShadow) {\n                const shadowRenderBuf = light.getShadowRenderBuf();\n                shadowRenderBuf.bind();\n\n                frameCtx.reset();\n                frameCtx.backfaces = true;\n                frameCtx.frontface = true;\n                frameCtx.viewParams.viewMatrix = light.getShadowViewMatrix();\n                frameCtx.viewParams.projMatrix = light.getShadowProjMatrix();\n                frameCtx.nearPlaneHeight = getNearPlaneHeight(scene.camera, gl.drawingBufferHeight);\n\n                gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\n                gl.clearColor(0, 0, 0, 1);\n                gl.enable(gl.DEPTH_TEST);\n                gl.disable(gl.BLEND);\n\n                gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n                Object.values(drawableTypeInfo).forEach(\n                    drawableInfo => {\n                        drawableInfo.drawableList.forEach(\n                            drawable => {\n                                if ((drawable.visible !== false) && drawable.castsShadow && drawable.drawShadow) {\n                                    if (drawable.renderFlags.colorOpaque) { // Transparent objects don't cast shadows (yet)\n                                        drawable.drawShadow(frameCtx);\n                                    }\n                                }\n                            });\n                    });\n\n                shadowRenderBuf.unbind();\n            }\n        });\n\n        drawColor(pass, clear, occlusionTexture);\n    }\n\n    function drawSAOBuffers(pass) {\n\n        const sao = scene.sao;\n\n        const size = [gl.drawingBufferWidth, gl.drawingBufferHeight];\n\n        // Render depth buffer\n        const saoDepthRenderBuffer = renderBufferManager.getRenderBuffer(\"saoDepth\", [], true);\n        saoDepthRenderBuffer.setSize(size);\n        saoDepthRenderBuffer.bind();\n        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n        frameCtx.reset();\n        frameCtx.pass = pass;\n        frameCtx.viewParams = getSceneCameraViewParams();\n        frameCtx.nearPlaneHeight = getNearPlaneHeight(scene.camera, gl.drawingBufferHeight);\n\n        gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n        gl.clearColor(0, 0, 0, 0);\n        gl.enable(gl.DEPTH_TEST);\n        gl.frontFace(gl.CCW);\n        gl.enable(gl.CULL_FACE);\n        gl.depthMask(true);\n        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n        postCullDrawableList.forEach(drawable => {\n            if (!drawable.culled && drawable.visible && drawable.drawDepth && drawable.saoEnabled && drawable.renderFlags.colorOpaque) {\n                drawable.drawDepth(frameCtx);\n            }\n        });\n\n        saoDepthRenderBuffer.unbind();\n\n        const depthTexture = saoDepthRenderBuffer.depthTexture;\n\n        // Render occlusion buffer\n\n        const occlusionRenderBuffer1 = renderBufferManager.getRenderBuffer(\"saoOcclusion\");\n        occlusionRenderBuffer1.setSize(size);\n        occlusionRenderBuffer1.bind();\n\n        gl.viewport(0, 0, size[0], size[1]);\n        gl.clearColor(0, 0, 0, 1);\n        gl.disable(gl.DEPTH_TEST);\n        gl.disable(gl.BLEND);\n        gl.frontFace(gl.CCW);\n        gl.clear(gl.COLOR_BUFFER_BIT);\n\n        saoOcclusionRenderer.render(size, scene.camera.project, sao, depthTexture);\n\n        occlusionRenderBuffer1.unbind();\n\n        if (sao.blur) {\n            const occlusionRenderBuffer2 = renderBufferManager.getRenderBuffer(\"saoOcclusion2\");\n            occlusionRenderBuffer2.setSize(size);\n\n            const blurSAO = (src, dst, direction) => {\n                dst.bind();\n\n                gl.viewport(0, 0, size[0], size[1]);\n                gl.clearColor(0, 0, 0, 1);\n                gl.enable(gl.DEPTH_TEST);\n                gl.disable(gl.BLEND);\n                gl.frontFace(gl.CCW);\n                gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n                const project = scene.camera.project;\n                saoDepthLimitedBlurRenderer.render(size, project, direction, depthTexture, src.colorTextures[0]);\n\n                dst.unbind();\n            };\n\n            blurSAO(occlusionRenderBuffer1, occlusionRenderBuffer2, 0); // horizontally\n            blurSAO(occlusionRenderBuffer2, occlusionRenderBuffer1, 1); // vertically\n        }\n\n        return occlusionRenderBuffer1.colorTextures[0];\n    }\n\n    function drawColor(pass, clear, occlusionTexture) {\n\n        const normalDrawSAOBin = [];\n        const normalEdgesOpaqueBin = [];\n        const normalFillTransparentBin = [];\n        const normalEdgesTransparentBin = [];\n\n        const xrayedFillOpaqueBin = [];\n        const xrayEdgesOpaqueBin = [];\n        const xrayedFillTransparentBin = [];\n        const xrayEdgesTransparentBin = [];\n\n        const highlightedFillOpaqueBin = [];\n        const highlightedEdgesOpaqueBin = [];\n        const highlightedFillTransparentBin = [];\n        const highlightedEdgesTransparentBin = [];\n\n        const selectedFillOpaqueBin = [];\n        const selectedEdgesOpaqueBin = [];\n        const selectedFillTransparentBin = [];\n        const selectedEdgesTransparentBin = [];\n\n\n        const ambientColorAndIntensity = scene._lightsState.getAmbientColorAndIntensity();\n\n        frameCtx.reset();\n        frameCtx.pass = pass;\n        frameCtx.withSAO = false;\n        frameCtx.pbrEnabled = pbrEnabled && !!scene.pbrEnabled;\n        frameCtx.colorTextureEnabled = colorTextureEnabled && !!scene.colorTextureEnabled;\n        frameCtx.viewParams = getSceneCameraViewParams();\n        frameCtx.nearPlaneHeight = getNearPlaneHeight(scene.camera, gl.drawingBufferHeight);\n\n        gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n\n        if (canvasTransparent) {\n            gl.clearColor(0, 0, 0, 0);\n        } else {\n            const backgroundColor = scene.canvas.backgroundColorFromAmbientLight ? ambientColorAndIntensity : scene.canvas.backgroundColor;\n            gl.clearColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], 1.0);\n        }\n\n        gl.enable(gl.DEPTH_TEST);\n        gl.frontFace(gl.CCW);\n        gl.enable(gl.CULL_FACE);\n        gl.depthMask(true);\n        gl.lineWidth(1);\n\n        frameCtx.lineWidth = 1;\n\n        scene.sao;\n        frameCtx.saoParams = [gl.drawingBufferWidth, gl.drawingBufferHeight, scene.sao.blendCutoff, scene.sao.blendFactor];\n        frameCtx.occlusionTexture = occlusionTexture;\n\n        let i;\n        let drawable;\n\n        const startTime = Date.now();\n\n        if (clear) {\n            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n        }\n\n        frameCtx.testAABB = makeFrustumAABBIntersectionTest(scene.camera);\n\n        const renderDrawables = function(drawables) {\n\n        let normalDrawSAOBinLen = 0;\n        let normalEdgesOpaqueBinLen = 0;\n        let normalFillTransparentBinLen = 0;\n        let normalEdgesTransparentBinLen = 0;\n\n        let xrayedFillOpaqueBinLen = 0;\n        let xrayEdgesOpaqueBinLen = 0;\n        let xrayedFillTransparentBinLen = 0;\n        let xrayEdgesTransparentBinLen = 0;\n\n        let highlightedFillOpaqueBinLen = 0;\n        let highlightedEdgesOpaqueBinLen = 0;\n        let highlightedFillTransparentBinLen = 0;\n        let highlightedEdgesTransparentBinLen = 0;\n\n        let selectedFillOpaqueBinLen = 0;\n        let selectedEdgesOpaqueBinLen = 0;\n        let selectedFillTransparentBinLen = 0;\n        let selectedEdgesTransparentBinLen = 0;\n\n        //------------------------------------------------------------------------------------------------------\n        // Render normal opaque solids, defer others to bins to render after\n        //------------------------------------------------------------------------------------------------------\n        for (let i = 0, len = drawables.length; i < len; i++) {\n\n            drawable = drawables[i];\n\n            if (drawable.culled === true || drawable.visible === false) {\n                continue;\n            }\n\n            const renderFlags = drawable.renderFlags;\n\n            if (renderFlags.colorOpaque) {\n                if (drawable.saoEnabled && occlusionTexture) {\n                    normalDrawSAOBin[normalDrawSAOBinLen++] = drawable;\n                } else {\n                    drawable.drawColorOpaque(frameCtx);\n                }\n            }\n\n            if (transparentEnabled) {\n                if (renderFlags.colorTransparent) {\n                    normalFillTransparentBin[normalFillTransparentBinLen++] = drawable;\n                }\n            }\n\n            if (renderFlags.xrayedSilhouetteTransparent) {\n                xrayedFillTransparentBin[xrayedFillTransparentBinLen++] = drawable;\n            }\n\n            if (renderFlags.xrayedSilhouetteOpaque) {\n                xrayedFillOpaqueBin[xrayedFillOpaqueBinLen++] = drawable;\n            }\n\n            if (renderFlags.highlightedSilhouetteTransparent) {\n                highlightedFillTransparentBin[highlightedFillTransparentBinLen++] = drawable;\n            }\n\n            if (renderFlags.highlightedSilhouetteOpaque) {\n                highlightedFillOpaqueBin[highlightedFillOpaqueBinLen++] = drawable;\n            }\n\n            if (renderFlags.selectedSilhouetteTransparent) {\n                selectedFillTransparentBin[selectedFillTransparentBinLen++] = drawable;\n            }\n\n            if (renderFlags.selectedSilhouetteOpaque) {\n                selectedFillOpaqueBin[selectedFillOpaqueBinLen++] = drawable;\n            }\n\n            if (drawable.edges && edgesEnabled) {\n                if (renderFlags.edgesOpaque) {\n                    normalEdgesOpaqueBin[normalEdgesOpaqueBinLen++] = drawable;\n                }\n\n                if (renderFlags.edgesTransparent) {\n                    normalEdgesTransparentBin[normalEdgesTransparentBinLen++] = drawable;\n                }\n\n                if (renderFlags.selectedEdgesTransparent) {\n                    selectedEdgesTransparentBin[selectedEdgesTransparentBinLen++] = drawable;\n                }\n\n                if (renderFlags.selectedEdgesOpaque) {\n                    selectedEdgesOpaqueBin[selectedEdgesOpaqueBinLen++] = drawable;\n                }\n\n                if (renderFlags.xrayedEdgesTransparent) {\n                    xrayEdgesTransparentBin[xrayEdgesTransparentBinLen++] = drawable;\n                }\n\n                if (renderFlags.xrayedEdgesOpaque) {\n                    xrayEdgesOpaqueBin[xrayEdgesOpaqueBinLen++] = drawable;\n                }\n\n                if (renderFlags.highlightedEdgesTransparent) {\n                    highlightedEdgesTransparentBin[highlightedEdgesTransparentBinLen++] = drawable;\n                }\n\n                if (renderFlags.highlightedEdgesOpaque) {\n                    highlightedEdgesOpaqueBin[highlightedEdgesOpaqueBinLen++] = drawable;\n                }\n            }\n        }\n\n        //------------------------------------------------------------------------------------------------------\n        // Render deferred bins\n        //------------------------------------------------------------------------------------------------------\n\n        // Opaque color with SAO\n\n        if (normalDrawSAOBinLen > 0) {\n            frameCtx.withSAO = true;\n            for (i = 0; i < normalDrawSAOBinLen; i++) {\n                normalDrawSAOBin[i].drawColorOpaque(frameCtx);\n            }\n        }\n\n        // Opaque edges\n\n        if (normalEdgesOpaqueBinLen > 0) {\n            for (i = 0; i < normalEdgesOpaqueBinLen; i++) {\n                normalEdgesOpaqueBin[i].drawEdgesColorOpaque(frameCtx);\n            }\n        }\n\n        // Opaque X-ray fill\n\n        if (xrayedFillOpaqueBinLen > 0) {\n            for (i = 0; i < xrayedFillOpaqueBinLen; i++) {\n                xrayedFillOpaqueBin[i].drawSilhouetteXRayed(frameCtx);\n            }\n        }\n\n        // Opaque X-ray edges\n\n        if (xrayEdgesOpaqueBinLen > 0) {\n            for (i = 0; i < xrayEdgesOpaqueBinLen; i++) {\n                xrayEdgesOpaqueBin[i].drawEdgesXRayed(frameCtx);\n            }\n        }\n\n        // Transparent\n\n        if (xrayedFillTransparentBinLen > 0 || xrayEdgesTransparentBinLen > 0 || normalFillTransparentBinLen > 0 || normalEdgesTransparentBinLen > 0) {\n            gl.enable(gl.CULL_FACE);\n            gl.enable(gl.BLEND);\n            if (canvasTransparent) {\n                gl.blendEquation(gl.FUNC_ADD);\n                gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n            } else {\n                gl.blendEquation(gl.FUNC_ADD);\n                gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n            }\n            frameCtx.backfaces = false;\n            if (!alphaDepthMask) {\n                gl.depthMask(false);\n            }\n\n            // Transparent color edges\n\n            if (normalFillTransparentBinLen > 0 || normalEdgesTransparentBinLen > 0) {\n                gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n            }\n            if (normalEdgesTransparentBinLen > 0) {\n                for (i = 0; i < normalEdgesTransparentBinLen; i++) {\n                    drawable = normalEdgesTransparentBin[i];\n                    drawable.drawEdgesColorTransparent(frameCtx);\n                }\n            }\n\n            // Transparent color fill\n\n            if (normalFillTransparentBinLen > 0) {\n                const eye = frameCtx.viewParams.eye;\n                normalFillTransparentBin.length = normalFillTransparentBinLen; // normalFillTransparentBin reused by renderDrawables calls, so needs to be truncated if necessary\n                const byDist = normalFillTransparentBin.map(d => ({ drawable: d, distSq: math.distVec3(d.origin || vec3_0, eye) }));\n                byDist.sort((a, b) => b.distSq - a.distSq);\n                for (i = 0; i < normalFillTransparentBinLen; i++) {\n                    byDist[i].drawable.drawColorTransparent(frameCtx);\n                }\n            }\n\n            // Transparent X-ray edges\n\n            if (xrayEdgesTransparentBinLen > 0) {\n                for (i = 0; i < xrayEdgesTransparentBinLen; i++) {\n                    xrayEdgesTransparentBin[i].drawEdgesXRayed(frameCtx);\n                }\n            }\n\n            // Transparent X-ray fill\n\n            if (xrayedFillTransparentBinLen > 0) {\n                for (i = 0; i < xrayedFillTransparentBinLen; i++) {\n                    xrayedFillTransparentBin[i].drawSilhouetteXRayed(frameCtx);\n                }\n            }\n\n            gl.disable(gl.BLEND);\n            if (!alphaDepthMask) {\n                gl.depthMask(true);\n            }\n        }\n\n        // Opaque highlight\n\n        if (highlightedFillOpaqueBinLen > 0 || highlightedEdgesOpaqueBinLen > 0) {\n            frameCtx.lastProgramId = null;\n            if (scene.highlightMaterial.glowThrough) {\n                gl.clear(gl.DEPTH_BUFFER_BIT);\n            }\n\n            // Opaque highlighted edges\n\n            if (highlightedEdgesOpaqueBinLen > 0) {\n                for (i = 0; i < highlightedEdgesOpaqueBinLen; i++) {\n                    highlightedEdgesOpaqueBin[i].drawEdgesHighlighted(frameCtx);\n                }\n            }\n\n            // Opaque highlighted fill\n\n            if (highlightedFillOpaqueBinLen > 0) {\n                for (i = 0; i < highlightedFillOpaqueBinLen; i++) {\n                    highlightedFillOpaqueBin[i].drawSilhouetteHighlighted(frameCtx);\n                }\n            }\n        }\n\n        // Highlighted transparent\n\n        if (highlightedFillTransparentBinLen > 0 || highlightedEdgesTransparentBinLen > 0 || highlightedFillOpaqueBinLen > 0) {\n            frameCtx.lastProgramId = null;\n            if (scene.selectedMaterial.glowThrough) {\n                gl.clear(gl.DEPTH_BUFFER_BIT);\n            }\n            gl.enable(gl.BLEND);\n            if (canvasTransparent) {\n                gl.blendEquation(gl.FUNC_ADD);\n                gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n            } else {\n                gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n            }\n            gl.enable(gl.CULL_FACE);\n\n            // Highlighted transparent edges\n\n            if (highlightedEdgesTransparentBinLen > 0) {\n                for (i = 0; i < highlightedEdgesTransparentBinLen; i++) {\n                    highlightedEdgesTransparentBin[i].drawEdgesHighlighted(frameCtx);\n                }\n            }\n\n            // Highlighted transparent fill\n\n            if (highlightedFillTransparentBinLen > 0) {\n                for (i = 0; i < highlightedFillTransparentBinLen; i++) {\n                    highlightedFillTransparentBin[i].drawSilhouetteHighlighted(frameCtx);\n                }\n            }\n            gl.disable(gl.BLEND);\n        }\n\n        // Selected opaque\n\n        if (selectedFillOpaqueBinLen > 0 || selectedEdgesOpaqueBinLen > 0) {\n            frameCtx.lastProgramId = null;\n            if (scene.selectedMaterial.glowThrough) {\n                gl.clear(gl.DEPTH_BUFFER_BIT);\n            }\n\n            // Selected opaque fill\n\n            if (selectedEdgesOpaqueBinLen > 0) {\n                for (i = 0; i < selectedEdgesOpaqueBinLen; i++) {\n                    selectedEdgesOpaqueBin[i].drawEdgesSelected(frameCtx);\n                }\n            }\n\n            // Selected opaque edges\n\n            if (selectedFillOpaqueBinLen > 0) {\n                for (i = 0; i < selectedFillOpaqueBinLen; i++) {\n                    selectedFillOpaqueBin[i].drawSilhouetteSelected(frameCtx);\n                }\n            }\n        }\n\n        // Selected transparent\n\n        if (selectedFillTransparentBinLen > 0 || selectedEdgesTransparentBinLen > 0) {\n            frameCtx.lastProgramId = null;\n            if (scene.selectedMaterial.glowThrough) {\n                gl.clear(gl.DEPTH_BUFFER_BIT);\n            }\n            gl.enable(gl.CULL_FACE);\n            gl.enable(gl.BLEND);\n            if (canvasTransparent) {\n                gl.blendEquation(gl.FUNC_ADD);\n                gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n            } else {\n                gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n            }\n\n            // Selected transparent edges\n\n            if (selectedEdgesTransparentBinLen > 0) {\n                for (i = 0; i < selectedEdgesTransparentBinLen; i++) {\n                    selectedEdgesTransparentBin[i].drawEdgesSelected(frameCtx);\n                }\n            }\n\n            // Selected transparent fill\n\n            if (selectedFillTransparentBinLen > 0) {\n                for (i = 0; i < selectedFillTransparentBinLen; i++) {\n                    selectedFillTransparentBin[i].drawSilhouetteSelected(frameCtx);\n                }\n            }\n            gl.disable(gl.BLEND);\n        }\n\n        };\n\n        renderDrawables(postCullDrawableList);\n        if (uiDrawableList.length > 0) {\n            gl.clear(gl.DEPTH_BUFFER_BIT);\n            renderDrawables(uiDrawableList);\n        }\n\n        frameCtx.testAABB = null;\n\n        const endTime = Date.now();\n        const frameStats = stats.frame;\n\n        frameStats.renderTime = (endTime - startTime) / 1000.0;\n        frameStats.drawElements = frameCtx.drawElements;\n        frameStats.drawArrays = frameCtx.drawArrays;\n        frameStats.useProgram = frameCtx.useProgram;\n        frameStats.bindTexture = frameCtx.bindTexture;\n        frameStats.bindArray = frameCtx.bindArray;\n\n        const numTextureUnits = WEBGL_INFO.MAX_TEXTURE_IMAGE_UNITS;\n        for (let ii = 0; ii < numTextureUnits; ii++) {\n            gl.activeTexture(gl.TEXTURE0 + ii);\n        }\n        gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);\n        gl.bindTexture(gl.TEXTURE_2D, null);\n\n        const numVertexAttribs = WEBGL_INFO.MAX_VERTEX_ATTRIBS; // Fixes https://github.com/xeokit/xeokit-sdk/issues/174\n        for (let ii = 0; ii < numVertexAttribs; ii++) {\n            gl.disableVertexAttribArray(ii);\n        }\n    }\n\n    const resetPickFrameCtx = (canvasPos, clipTransformDiv, camera, eye, projMatrix, viewMatrix, frameCtx) => {\n        frameCtx.reset();\n        frameCtx.backfaces = true;\n        frameCtx.frontface = true; // \"ccw\"\n\n        frameCtx.viewParams.eye = eye;\n        frameCtx.viewParams.projMatrix = projMatrix;\n        frameCtx.viewParams.viewMatrix = viewMatrix;\n        frameCtx.nearPlaneHeight = getNearPlaneHeight(camera, gl.drawingBufferHeight);\n\n        const resolutionScale = scene.canvas.resolutionScale;\n        frameCtx.pickClipPos = [\n            canvasPos ? (    2 * canvasPos[0] * resolutionScale / gl.drawingBufferWidth - 1) : 0,\n            canvasPos ? (1 - 2 * canvasPos[1] * resolutionScale / gl.drawingBufferHeight)    : 0\n        ];\n\n        frameCtx.pickClipPosInv = [\n            gl.drawingBufferWidth  / clipTransformDiv,\n            gl.drawingBufferHeight / clipTransformDiv\n        ];\n    };\n\n    /**\n     * Picks an Entity.\n     * @private\n     */\n    this.pick = (function () {\n\n        const tempVec3a = math.vec3();\n        const tempVec3b = math.vec3();\n        const tempVec4a = math.vec4();\n        const tempVec4b = math.vec4();\n        const tempVec4c = math.vec4();\n        const tempVec4d = math.vec4();\n        const tempVec4e = math.vec4();\n        const tempMat4a = math.mat4();\n        const tempMat4b = math.mat4();\n        const tempMat4c = math.mat4();\n        const tempMat4d = math.mat4();\n\n        const upVec = math.vec3([0, 1, 0]);\n        const _pickResult = new PickResult();\n\n        const nearAndFar = math.vec2();\n\n        const canvasPos = math.vec3();\n\n        const worldRayOrigin = math.vec3();\n        const worldRayDir = math.vec3();\n        math.vec3();\n        math.vec3();\n\n        const pickBuffer = new RenderBuffer(gl);\n        pickBuffer.setSize([1, 1]);\n\n        const pickNormalBuffer = new RenderBuffer(gl, [gl.RGBA32I]);\n        pickNormalBuffer.setSize([3, 3]);\n\n        return function (params, pickResult = _pickResult) {\n\n            pickResult.reset();\n\n            updateDrawlist();\n\n            let pickViewMatrix = null;\n            let pickProjMatrix = null;\n            let projection = null;\n            const camera = scene.camera;\n\n            pickResult.pickSurface = params.pickSurface;\n\n            if (params.canvasPos) {\n\n                canvasPos[0] = params.canvasPos[0];\n                canvasPos[1] = params.canvasPos[1];\n\n                pickViewMatrix = camera.viewMatrix;\n                pickProjMatrix = camera.projMatrix;\n                projection     = camera.projection;\n\n                nearAndFar[0] = camera.project.near;\n                nearAndFar[1] = camera.project.far;\n\n                pickResult.canvasPos = params.canvasPos;\n\n                math.canvasPosToWorldRay(canvas, pickViewMatrix, pickProjMatrix, projection, canvasPos, tempVec3a, tempVec3b);\n                frameCtx.testAABB = makeRayAABBIntersectionTest(tempVec3a, tempVec3b);\n            } else {\n\n                // Picking with arbitrary World-space ray\n                // Align camera along ray and fire ray through center of canvas\n\n                canvasPos[0] = canvas.clientWidth * 0.5;\n                canvasPos[1] = canvas.clientHeight * 0.5;\n\n                if (params.matrix) {\n\n                    pickViewMatrix = params.matrix;\n                    pickProjMatrix = camera.projMatrix;\n                    projection     = camera.projection;\n\n                    nearAndFar[0] = camera.project.near;\n                    nearAndFar[1] = camera.project.far;\n\n                    math.canvasPosToWorldRay(canvas, pickViewMatrix, pickProjMatrix, projection, canvasPos, tempVec3a, tempVec3b);\n                    frameCtx.testAABB = makeRayAABBIntersectionTest(tempVec3a, tempVec3b);\n                } else {\n\n                    worldRayOrigin.set(params.origin || [0, 0, 0]);\n                    worldRayDir.set(params.direction || [0, 0, 1]);\n\n                    const look = math.addVec3(worldRayOrigin, worldRayDir, tempVec3a);\n                    const up = tempVec3b;\n\n                    if (Math.abs(math.dotVec3(worldRayDir, upVec)) > (1 - 1e-6)) { // worldRayDir aligned with Y axis\n                        up[0] = 0;\n                        up[1] = 0;\n                        up[2] = Math.sign(worldRayDir[1]);\n                    } else {\n                        math.cross3Vec3(worldRayDir, upVec, up);\n                        math.cross3Vec3(up, worldRayDir, up);\n                        math.normalizeVec3(up, up);\n                    }\n\n                    pickViewMatrix = math.lookAtMat4v(worldRayOrigin, look, up, tempMat4b);\n                    //    pickProjMatrix = camera.projMatrix;\n                    pickProjMatrix = camera.ortho.matrix;\n                    projection     = \"ortho\";\n\n                    nearAndFar[0] = camera.ortho.near;\n                    nearAndFar[1] = camera.ortho.far;\n\n                    pickResult.origin = worldRayOrigin;\n                    pickResult.direction = worldRayDir;\n\n                    frameCtx.testAABB = makeRayAABBIntersectionTest(pickResult.origin, pickResult.direction);\n                }\n            }\n\n            pickBuffer.bind();\n\n            const resetFrameCtx = (clipTransformDiv) => resetPickFrameCtx(canvasPos, clipTransformDiv, camera, pickResult.origin || camera.eye, pickProjMatrix || camera.projMatrix, pickViewMatrix || camera.viewMatrix, frameCtx);\n\n            // gpuPickPickable\n            resetFrameCtx(1);\n            frameCtx.pickInvisible = !!params.pickInvisible;\n\n            gl.viewport(0, 0, 1, 1);\n            gl.depthMask(true);\n            gl.enable(gl.DEPTH_TEST);\n            gl.disable(gl.CULL_FACE);\n            gl.disable(gl.BLEND);\n            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n            const includeEntityIds = params.includeEntityIds;\n            const excludeEntityIds = params.excludeEntityIds;\n\n            const renderDrawables = function(drawables) {\n                drawables.forEach(drawable => {\n                    if (!drawable.culled && drawable.visible && drawable.pickable && drawable.drawPickMesh // TODO: push this logic into drawable\n                        && ((! includeEntityIds) || includeEntityIds[drawable.id])\n                        && ((! excludeEntityIds) || (! excludeEntityIds[drawable.id]))) {\n                        drawable.drawPickMesh(frameCtx);\n                    }\n                });\n            };\n\n            renderDrawables(postCullDrawableList);\n            if (uiDrawableList.length > 0) {\n                gl.clear(gl.DEPTH_BUFFER_BIT);\n                renderDrawables(uiDrawableList);\n            }\n\n            frameCtx.testAABB = null;\n\n            const pickID = pixelToInt(pickBuffer.read(0, 0));\n            const pickable = (pickID >= 0) && pickIDs.items[pickID];\n\n            if (!pickable) {\n                pickBuffer.unbind();\n                return null;\n            }\n\n            const pickedEntity = (pickable.delegatePickedEntity) ? pickable.delegatePickedEntity() : pickable;\n\n            if (!pickedEntity) {\n                pickBuffer.unbind();\n                return null;\n            }\n\n            if (params.pickSurface) {\n\n                // GPU-based ray-picking\n\n                if (pickable.canPickTriangle && pickable.canPickTriangle()) {\n\n                    if (pickable.drawPickTriangles) {\n                        resetFrameCtx(1);\n                        // frameCtx.pickInvisible = !!params.pickInvisible;\n\n                        gl.viewport(0, 0, 1, 1);\n                        gl.clearColor(0, 0, 0, 0);\n                        gl.enable(gl.DEPTH_TEST);\n                        gl.disable(gl.CULL_FACE);\n                        gl.disable(gl.BLEND);\n                        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n                        pickable.drawPickTriangles(frameCtx);\n\n                        pickResult.primIndex = 3 * pixelToInt(pickBuffer.read(0, 0)); // Convert from triangle number to first vertex in indices\n                    }\n\n                    pickable.pickTriangleSurface(pickViewMatrix, pickProjMatrix, projection, pickResult);\n\n                    pickResult.pickSurfacePrecision = false;\n\n                } else {\n\n                    if (pickable.canPickWorldPos && pickable.canPickWorldPos()) {\n\n                        // pickWorldPos\n                        resetFrameCtx(1);\n                        frameCtx.viewParams.near = nearAndFar[0];\n                        frameCtx.viewParams.far  = nearAndFar[1];\n\n                        gl.viewport(0, 0, 1, 1);\n\n                        gl.clearColor(0, 0, 0, 0);\n                        gl.depthMask(true);\n                        gl.enable(gl.DEPTH_TEST);\n                        gl.disable(gl.CULL_FACE);\n                        gl.disable(gl.BLEND);\n                        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n                        pickable.drawPickDepths(frameCtx); // Draw color-encoded fragment screen-space depths\n\n                        const screenZ = math.dotVec4(pickBuffer.read(0, 0), bitShiftScreenZ);\n\n                        // Calculate clip space coordinates, which will be in range of x=[-1..1] and y=[-1..1], with y=(+1) at top\n                        const x = (canvasPos[0] - canvas.clientWidth / 2) / (canvas.clientWidth / 2);\n                        const y = -(canvasPos[1] - canvas.clientHeight / 2) / (canvas.clientHeight / 2);\n\n                        const origin = pickable.origin;\n\n                        const pvMatInverse = math.inverseMat4(math.mulMat4(pickProjMatrix, (origin ? createRTCViewMat(pickViewMatrix, origin, tempMat4a) : pickViewMatrix), tempMat4c), tempMat4d);\n\n                        const toWorld = (z, dst) => {\n                            dst[0] = x;\n                            dst[1] = y;\n                            dst[2] = z;\n                            dst[3] = 1;\n                            math.transformVec4(pvMatInverse, dst, dst);\n                            return math.mulVec4Scalar(dst, 1 / dst[3]);\n                        };\n\n                        const world1 = toWorld(-1, tempVec4a);\n                        const world2 = toWorld( 1, tempVec4b);\n\n                        const dir = math.subVec3(world2, world1, tempVec4c);\n                        const worldPos = math.addVec3(world1, math.mulVec4Scalar(dir, screenZ, tempVec4d), tempVec4e);\n\n                        if (origin) {\n                            math.addVec3(worldPos, origin);\n                        }\n\n                        pickResult.worldPos = worldPos;\n\n                        if (params.pickSurfaceNormal !== false) {\n                            // gpuPickWorldNormal\n                            resetFrameCtx(3);\n\n                            pickNormalBuffer.bind();\n\n                            gl.viewport(0, 0, pickNormalBuffer.size[0], pickNormalBuffer.size[1]);\n                            gl.enable(gl.DEPTH_TEST);\n                            gl.disable(gl.CULL_FACE);\n                            gl.disable(gl.BLEND);\n                            gl.clear(gl.DEPTH_BUFFER_BIT);\n                            gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));\n\n                            pickable.drawPickNormals(frameCtx); // Draw color-encoded fragment World-space normals\n\n                            const pix = pickNormalBuffer.read(1, 1, gl.RGBA_INTEGER, gl.INT, Int32Array, 4);\n\n                            pickNormalBuffer.unbind();\n\n                            pickResult.worldNormal = toWorldNormal(pix);\n                        }\n\n                        pickResult.pickSurfacePrecision = false;\n                    }\n                }\n            }\n            pickBuffer.unbind();\n            pickResult.entity = pickedEntity;\n            return pickResult;\n        };\n    })();\n\n    /**\n     * @param {[number, number]} canvasPos\n     * @param {number} [snapRadiusInPixels=30]\n     * @param {boolean} [snapToVertex=true]\n     * @param {boolean} [snapToEdge=true]\n     * @param pickResult\n     * @returns {PickResult}\n     */\n    this.snapPick = (function () {\n\n        const _pickResult = new PickResult();\n\n        const getVertexPickBuffer = (function() {\n            const cache = { };\n            return (snapRadiusInPixels) => {\n                if (! (snapRadiusInPixels in cache)) {\n                    const buf = new RenderBuffer(gl, [gl.RGBA32I, gl.RGBA32I, gl.RGBA8UI], true);\n                    buf.setSize([2 * snapRadiusInPixels + 1, 2 * snapRadiusInPixels + 1]);\n                    cache[snapRadiusInPixels] = buf;\n                }\n                return cache[snapRadiusInPixels];\n            };\n        })();\n\n        return function (params, pickResult = _pickResult) {\n\n            const {canvasPos, origin, direction, snapRadius, snapToVertex, snapToEdge} = params;\n\n            if (!snapToVertex && !snapToEdge) {\n                return this.pick({canvasPos, pickSurface: true});\n            }\n\n            const camera = scene.camera;\n            const snapRadiusInPixels = snapRadius || 30;\n            const viewMatrix = (canvasPos\n                                ? camera.viewMatrix\n                                : math.lookAtMat4v(\n                                    origin,\n                                    math.addVec3(origin, direction, math.vec3()),\n                                    math.vec3([0, 1, 0]),\n                                    math.mat4()));\n            resetPickFrameCtx(canvasPos, 2 * snapRadiusInPixels, camera, camera.eye, camera.projMatrix, viewMatrix, frameCtx);\n\n            // Bind and clear the snap render target\n\n            const vertexPickBuffer = getVertexPickBuffer(snapRadiusInPixels);\n            vertexPickBuffer.bind();\n            gl.viewport(0, 0, vertexPickBuffer.size[0], vertexPickBuffer.size[1]);\n            gl.enable(gl.DEPTH_TEST);\n            gl.frontFace(gl.CCW);\n            gl.disable(gl.CULL_FACE);\n            gl.depthMask(true);\n            gl.disable(gl.BLEND);\n            gl.depthFunc(gl.LEQUAL);\n            gl.clear(gl.DEPTH_BUFFER_BIT);\n            gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));\n            gl.clearBufferiv(gl.COLOR, 1, new Int32Array([0, 0, 0, 0]));\n            gl.clearBufferuiv(gl.COLOR, 2, new Uint32Array([0, 0, 0, 0]));\n\n            // a) init z-buffer\n            gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);\n\n            frameCtx.snapPickLayerParams = [];\n            frameCtx.snapPickLayerParams.push(null); // This recreates previous situation, which relied on snapPickLayerNumber\n            postCullDrawableList.forEach(drawable => {\n                if (!drawable.culled && drawable.visible && drawable.pickable && drawable.drawSnapInit) {\n                    drawable.drawSnapInit(frameCtx);\n                }\n            });\n\n            const layerParamsSurface = frameCtx.snapPickLayerParams;\n\n            // b) snap-pick\n            frameCtx.snapPickLayerParams = [];\n\n            gl.depthMask(false);\n            gl.drawBuffers([gl.COLOR_ATTACHMENT0]);\n\n            const drawSnap = (snapMode) => {\n                frameCtx.snapMode = snapMode;\n                frameCtx.snapPickLayerParams.push(null); // This recreates previous situation, which relied on snapPickLayerNumber\n                postCullDrawableList.forEach(drawable => {\n                    if (!drawable.culled && drawable.visible && drawable.pickable && drawable.drawSnap) {\n                        drawable.drawSnap(frameCtx);\n                    }\n                });\n            };\n\n            if (snapToEdge) {\n                drawSnap(\"edge\");\n            }\n            if (snapToVertex) {\n                drawSnap(\"vertex\");\n            }\n\n            gl.depthMask(true);\n\n            const layerParamsSnap = frameCtx.snapPickLayerParams;\n\n            // Read and decode the snapped coordinates\n            const readSnapPickBuffer = (source, arrayType, glType) => {\n                const w = vertexPickBuffer.buffer.width;\n                const h = vertexPickBuffer.buffer.height;\n                const pix = new arrayType(4 * w * h);\n                gl.readBuffer(source);\n                gl.readPixels(0, 0, w, h, gl.RGBA_INTEGER, glType, pix, 0);\n                return pix;\n            };\n\n            const snapPickResultArray       = readSnapPickBuffer(gl.COLOR_ATTACHMENT0, Int32Array,  gl.INT);\n            const snapPickNormalResultArray = readSnapPickBuffer(gl.COLOR_ATTACHMENT1, Int32Array,  gl.INT);\n            const snapPickIdResultArray     = readSnapPickBuffer(gl.COLOR_ATTACHMENT2, Uint32Array, gl.UNSIGNED_INT);\n\n            vertexPickBuffer.unbind();\n\n            // result 1) regular hi-precision world position\n\n            let worldPos = null;\n            let worldNormal = null;\n            let pickable = null;\n\n            const middleX = snapRadiusInPixels;\n            const middleY = snapRadiusInPixels;\n            const middleIndex = (middleX * 4) + (middleY * vertexPickBuffer.size[0] * 4);\n            const pickResultMiddleXY = snapPickResultArray.slice(middleIndex, middleIndex + 4);\n            const pickNormalResultMiddleXY = snapPickNormalResultArray.slice(middleIndex, middleIndex + 4);\n            const pickPickableResultMiddleXY = snapPickIdResultArray.slice(middleIndex, middleIndex + 4);\n\n            if (pickResultMiddleXY[3] !== 0) {\n                const pickedLayerParmasSurface = layerParamsSurface[Math.abs(pickResultMiddleXY[3]) % layerParamsSurface.length];\n                worldPos = toWorldPos(pickResultMiddleXY, pickedLayerParmasSurface.origin, pickedLayerParmasSurface.coordinateScale);\n                worldNormal = toWorldNormal(pickNormalResultMiddleXY);\n\n                pickable = pickIDs.items[pixelToInt(pickPickableResultMiddleXY)];\n            }\n\n            // result 2) hi-precision snapped (to vertex/edge) world position\n\n            const snapPickResult = [ ];\n            for (let i = 0; i < snapPickResultArray.length; i += 4) {\n                const layerNumber = snapPickResultArray[i + 3];\n                if (layerNumber > 0) {\n                    const pixelNumber = Math.floor(i / 4);\n                    const w = vertexPickBuffer.size[0];\n                    const x = pixelNumber % w - Math.floor(w / 2);\n                    const y = Math.floor(pixelNumber / w) - Math.floor(w / 2);\n                    snapPickResult.push({\n                        dist:     math.lenVec2([ x, y ]),\n                        isVertex: (snapToVertex && snapToEdge) ? (layerNumber > layerParamsSnap.length / 2) : snapToVertex,\n                        result:   snapPickResultArray.subarray(i, i+4),\n                        normal:   snapPickNormalResultArray.subarray(i, i+4),\n                        id:       snapPickIdResultArray.subarray(i, i+4)\n                    });\n                }\n            }\n\n            const getPickedEntity = pickable => (pickable && pickable.delegatePickedEntity) ? pickable.delegatePickedEntity() : pickable;\n\n            if (snapPickResult.length > 0) {\n                // closest vertex snap first, then closest edge snap\n                const res = snapPickResult.reduce((a,b) => ((((a.isVertex-b.isVertex) || (b.dist-a.dist)) > 0) ? a : b));\n                const snapPick = res.result;\n                const pickedLayerParmas = layerParamsSnap[snapPick[3]];\n                const snappedWorldPos = toWorldPos(snapPick, pickedLayerParmas.origin, pickedLayerParmas.coordinateScale);\n                const snappedCanvasPos = camera.projectWorldPos(snappedWorldPos);\n\n                pickResult.reset();\n                pickResult.snappedToEdge    = !res.isVertex;\n                pickResult.snappedToVertex  = res.isVertex;\n                pickResult.worldPos         = snappedWorldPos;\n                pickResult.worldNormal      = toWorldNormal(res.normal);\n                pickResult.entity           = getPickedEntity(pickIDs.items[pixelToInt(res.id)]);\n                pickResult.canvasPos        = canvasPos || (worldPos && camera.projectWorldPos(worldPos)) || snappedCanvasPos;\n                pickResult.snappedCanvasPos = snappedCanvasPos;\n                return pickResult;\n\n            } else if (worldPos) {\n\n                pickResult.reset();\n                pickResult.snappedToEdge    = false;\n                pickResult.snappedToVertex  = false;\n                pickResult.worldPos         = worldPos;\n                pickResult.worldNormal      = worldNormal;\n                pickResult.entity           = getPickedEntity(pickable);\n                pickResult.canvasPos        = canvasPos || camera.projectWorldPos(worldPos);\n                pickResult.snappedCanvasPos = canvasPos;\n                return pickResult;\n\n            } else {\n                return null;\n            }\n        };\n    })();\n\n    /**\n     * Adds a {@link Marker} for occlusion testing.\n     * @param marker\n     */\n    this.addMarker = function (marker) {\n        this._occlusionTester = this._occlusionTester || new OcclusionTester(scene);\n        this._occlusionTester.addMarker(marker);\n        scene.occlusionTestCountdown = 0;\n    };\n\n    /**\n     * Notifies that a {@link Marker#worldPos} has updated.\n     * @param marker\n     */\n    this.markerWorldPosUpdated = function (marker) {\n        this._occlusionTester.markerWorldPosUpdated(marker);\n    };\n\n    /**\n     * Removes a {@link Marker} from occlusion testing.\n     * @param marker\n     */\n    this.removeMarker = function (marker) {\n        this._occlusionTester.removeMarker(marker);\n    };\n\n    /**\n     * Performs an occlusion test for all added {@link Marker}s, updating\n     * their {@link Marker#visible} properties accordingly.\n     */\n    this.doOcclusionTest = function () {\n\n        if (this._occlusionTester && this._occlusionTester.needOcclusionTest) {\n\n            updateDrawlist();\n\n            const readPixelBuf = renderBufferManager.getRenderBuffer(\"occlusionReadPix\");\n            if (readPixelBuf) {\n                readPixelBuf.setSize([gl.drawingBufferWidth, gl.drawingBufferHeight]);\n                readPixelBuf.bind();\n            }\n\n            frameCtx.reset();\n            frameCtx.backfaces = true;\n            frameCtx.frontface = true; // \"ccw\"\n            frameCtx.viewParams = getSceneCameraViewParams();\n            frameCtx.nearPlaneHeight = getNearPlaneHeight(scene.camera, gl.drawingBufferHeight);\n\n            gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n            gl.clearColor(0, 0, 0, 0);\n            gl.enable(gl.DEPTH_TEST);\n            gl.disable(gl.CULL_FACE);\n            gl.disable(gl.BLEND);\n            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n            postCullDrawableList.forEach(drawable => {\n                if (!drawable.culled && drawable.visible && drawable.pickable && drawable.drawOcclusion) { // TODO: Option to exclude transparent?\n                    drawable.drawOcclusion(frameCtx);\n                }\n            });\n\n            this._occlusionTester.drawMarkers();\n\n            if (readPixelBuf) {\n                const resolutionScale = scene.canvas.resolutionScale;\n                this._occlusionTester.doOcclusionTest( // Updates Marker \"visible\" properties\n                    (x, y) => readPixelBuf.read(Math.round(resolutionScale * x), Math.round(resolutionScale * y)));\n                readPixelBuf.unbind();\n            }\n        }\n    };\n\n    this.snapshot = (() => {\n        let snapshotBound = false;\n        const snapshotBuffer = new RenderBuffer(gl);\n        let snapshotCanvas = null;\n\n        return {\n            /**\n             * Read pixels from the renderer's current output. Performs a force-render first.\n             * @param pixels\n             * @param colors\n             * @param len\n             * @private\n             */\n            readPixels: (pixels, colors, len) => {\n                snapshotBuffer.bind();\n                gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n                imageDirty = true;\n                this.render();\n                for (let i = 0; i < len; i++) {\n                    const j = i * 2;\n                    const k = i * 4;\n                    const color = snapshotBuffer.read(pixels[j], pixels[j + 1]);\n                    colors[k] = color[0];\n                    colors[k + 1] = color[1];\n                    colors[k + 2] = color[2];\n                    colors[k + 3] = color[3];\n                }\n                snapshotBuffer.unbind();\n                imageDirty = true;\n            },\n\n            /**\n             * Enter snapshot mode.\n             *\n             * Switches rendering to a hidden snapshot canvas.\n             *\n             * Exit snapshot mode using endSnapshot().\n             */\n            beginSnapshot: () => {\n                snapshotBuffer.setSize([gl.drawingBufferWidth, gl.drawingBufferHeight]);\n                snapshotBuffer.bind();\n                gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n                snapshotBound = true;\n            },\n\n            /**\n             * Returns an HTMLCanvas containing an image of the snapshot canvas.\n             *\n             * - The HTMLCanvas has a CanvasRenderingContext2D.\n             * - Expects the caller to draw more things on the HTMLCanvas (annotations etc).\n             *\n             * @returns {HTMLCanvasElement}\n             */\n            renderSnapshotToCanvas: () => {\n                const width  = snapshotBuffer.buffer.width;\n                const height = snapshotBuffer.buffer.height;\n\n                if ((! snapshotCanvas) || (snapshotCanvas.width !== width) || (snapshotCanvas.height !== height)) {\n                    snapshotCanvas = (function() {\n                        const canvas  = document.createElement('canvas');\n                        const context = canvas.getContext('2d');\n                        canvas.width  = width;\n                        canvas.height = height;\n                        const pixelData = new Uint8Array(width * height * 4);\n                        const imageData = context.createImageData(width, height);\n\n                        return {\n                            width:            width,\n                            height:           height,\n                            getUpdatedCanvas: () => {\n                                gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);\n\n                                // flip verically\n                                const halfHeight = Math.floor(height / 2);\n                                const bytesPerRow = width * 4;\n                                const temp = new Uint8Array(bytesPerRow);\n                                for (let y = 0; y < halfHeight; ++y) {\n                                    const topOffset = y * bytesPerRow;\n                                    const bottomOffset = (height - y - 1) * bytesPerRow;\n                                    temp.set(pixelData.subarray(topOffset, topOffset + bytesPerRow));\n                                    pixelData.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\n                                    pixelData.set(temp, bottomOffset);\n                                }\n\n                                imageData.data.set(pixelData);\n\n                                context.resetTransform(); // Prevents strange scale-accumulation effect with html2canvas\n                                context.putImageData(imageData, 0, 0);\n\n                                return canvas;\n                            }\n                        };\n                    })();\n                }\n\n                if (snapshotBound) {\n                    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n                    imageDirty = true;\n                    this.render();\n                    imageDirty = true;\n                }\n\n                return snapshotCanvas.getUpdatedCanvas();\n            },\n\n            /**\n             * Exists snapshot mode.\n             *\n             * Switches rendering back to the main canvas.\n             */\n            endSnapshot: () => {\n                if (snapshotBound) {\n                    snapshotBuffer.unbind();\n                    snapshotBound = false;\n                }\n                imageDirty = true;\n                this.render();\n            }\n        };\n    })();\n\n    /**\n     * Destroys this renderer.\n     * @private\n     */\n    this.destroy = function () {\n\n        drawableTypeInfo = {};\n        drawables = {};\n\n        renderBufferManager.destroy();\n\n        saoOcclusionRenderer.destroy();\n        saoDepthLimitedBlurRenderer.destroy();\n\n        if (this._occlusionTester) {\n            this._occlusionTester.destroy();\n        }\n    };\n};\n\n/**\n * @desc Meditates mouse, touch and keyboard events for various interaction controls.\n *\n * Ordinarily, you would only use this component as a utility to help manage input events and state for your\n * own custom input handlers.\n *\n * * Located at {@link Scene#input}\n * * Used by (at least) {@link CameraControl}\n *\n * ## Usage\n *\n * Subscribing to mouse events on the canvas:\n *\n * ````javascript\n * import {Viewer} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * const input = viewer.scene.input;\n *\n * const onMouseDown = input.on(\"mousedown\", (canvasCoords) => {\n *       console.log(\"Mouse down at: x=\" + canvasCoords[0] + \", y=\" + coords[1]);\n * });\n *\n * const onMouseUp = input.on(\"mouseup\", (canvasCoords) => {\n *       console.log(\"Mouse up at: x=\" + canvasCoords[0] + \", y=\" + canvasCoords[1]);\n * });\n *\n * const onMouseClicked = input.on(\"mouseclicked\", (canvasCoords) => {\n *      console.log(\"Mouse clicked at: x=\" + canvasCoords[0] + \", y=\" + canvasCoords[1]);\n * });\n *\n * const onDblClick = input.on(\"dblclick\", (canvasCoords) => {\n *       console.log(\"Double-click at: x=\" + canvasCoords[0] + \", y=\" + canvasCoords[1]);\n * });\n * ````\n *\n * Subscribing to keyboard events on the canvas:\n *\n * ````javascript\n * const onKeyDown = input.on(\"keydown\", (keyCode) => {\n *      switch (keyCode) {\n *          case this.KEY_A:\n *              console.log(\"The 'A' key is down\");\n *              break;\n *\n *          case this.KEY_B:\n *              console.log(\"The 'B' key is down\");\n *              break;\n *\n *          case this.KEY_C:\n *              console.log(\"The 'C' key is down\");\n *              break;\n *\n *          default:\n *              console.log(\"Some other key is down\");\n *      }\n * });\n *\n * const onKeyUp = input.on(\"keyup\", (keyCode) => {\n *      switch (keyCode) {\n *          case this.KEY_A:\n *              console.log(\"The 'A' key is up\");\n *              break;\n *\n *          case this.KEY_B:\n *              console.log(\"The 'B' key is up\");\n *              break;\n *\n *          case this.KEY_C:\n *              console.log(\"The 'C' key is up\");\n *              break;\n *\n *          default:\n *              console.log(\"Some other key is up\");\n *      }\n *  });\n * ````\n *\n * Checking if keys are down:\n *\n * ````javascript\n * const isCtrlDown = input.ctrlDown;\n * const isAltDown = input.altDown;\n * const shiftDown = input.shiftDown;\n * //...\n *\n * const isAKeyDown = input.keyDown[input.KEY_A];\n * const isBKeyDown = input.keyDown[input.KEY_B];\n * const isShiftKeyDown = input.keyDown[input.KEY_SHIFT];\n * //...\n *\n * ````\n * Unsubscribing from events:\n *\n * ````javascript\n * input.off(onMouseDown);\n * input.off(onMouseUp);\n * //...\n * ````\n *\n * ## Disabling all events\n *\n * Event handling is enabled by default.\n *\n * To disable all events:\n *\n * ````javascript\n * myViewer.scene.input.setEnabled(false);\n * ````\n * To enable all events again:\n *\n * ````javascript\n * myViewer.scene.input.setEnabled(true);\n * ````\n *\n * ## Disabling keyboard input\n *\n * When the mouse is over the canvas, the canvas will consume keyboard events. Therefore, sometimes we need\n * to disable keyboard control, so that other UI elements can get those events.\n *\n * To disable keyboard events:\n *\n * ````javascript\n * myViewer.scene.input.setKeyboardEnabled(false);\n * ````\n *\n * To enable keyboard events again:\n *\n * ````javascript\n * myViewer.scene.input.setKeyboardEnabled(true)\n * ````\n */\nclass Input extends Component {\n\n    /**\n     * @private\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        /**\n         * Code for the BACKSPACE key.\n         * @property KEY_BACKSPACE\n         * @final\n         * @type {Number}\n         */\n        this.KEY_BACKSPACE = 8;\n\n        /**\n         * Code for the TAB key.\n         * @property KEY_TAB\n         * @final\n         * @type {Number}\n         */\n        this.KEY_TAB = 9;\n\n        /**\n         * Code for the ENTER key.\n         * @property KEY_ENTER\n         * @final\n         * @type {Number}\n         */\n        this.KEY_ENTER = 13;\n\n        /**\n         * Code for the SHIFT key.\n         * @property KEY_SHIFT\n         * @final\n         * @type {Number}\n         */\n        this.KEY_SHIFT = 16;\n\n        /**\n         * Code for the CTRL key.\n         * @property KEY_CTRL\n         * @final\n         * @type {Number}\n         */\n        this.KEY_CTRL = 17;\n\n        /**\n         * Code for the ALT key.\n         * @property KEY_ALT\n         * @final\n         * @type {Number}\n         */\n        this.KEY_ALT = 18;\n\n        /**\n         * Code for the PAUSE_BREAK key.\n         * @property KEY_PAUSE_BREAK\n         * @final\n         * @type {Number}\n         */\n        this.KEY_PAUSE_BREAK = 19;\n\n        /**\n         * Code for the CAPS_LOCK key.\n         * @property KEY_CAPS_LOCK\n         * @final\n         * @type {Number}\n         */\n        this.KEY_CAPS_LOCK = 20;\n\n        /**\n         * Code for the ESCAPE key.\n         * @property KEY_ESCAPE\n         * @final\n         * @type {Number}\n         */\n        this.KEY_ESCAPE = 27;\n\n        /**\n         * Code for the PAGE_UP key.\n         * @property KEY_PAGE_UP\n         * @final\n         * @type {Number}\n         */\n        this.KEY_PAGE_UP = 33;\n\n        /**\n         * Code for the PAGE_DOWN key.\n         * @property KEY_PAGE_DOWN\n         * @final\n         * @type {Number}\n         */\n        this.KEY_PAGE_DOWN = 34;\n\n        /**\n         * Code for the END key.\n         * @property KEY_END\n         * @final\n         * @type {Number}\n         */\n        this.KEY_END = 35;\n\n        /**\n         * Code for the HOME key.\n         * @property KEY_HOME\n         * @final\n         * @type {Number}\n         */\n        this.KEY_HOME = 36;\n\n        /**\n         * Code for the LEFT_ARROW key.\n         * @property KEY_LEFT_ARROW\n         * @final\n         * @type {Number}\n         */\n        this.KEY_LEFT_ARROW = 37;\n\n        /**\n         * Code for the UP_ARROW key.\n         * @property KEY_UP_ARROW\n         * @final\n         * @type {Number}\n         */\n        this.KEY_UP_ARROW = 38;\n\n        /**\n         * Code for the RIGHT_ARROW key.\n         * @property KEY_RIGHT_ARROW\n         * @final\n         * @type {Number}\n         */\n        this.KEY_RIGHT_ARROW = 39;\n\n        /**\n         * Code for the DOWN_ARROW key.\n         * @property KEY_DOWN_ARROW\n         * @final\n         * @type {Number}\n         */\n        this.KEY_DOWN_ARROW = 40;\n\n        /**\n         * Code for the INSERT key.\n         * @property KEY_INSERT\n         * @final\n         * @type {Number}\n         */\n        this.KEY_INSERT = 45;\n\n        /**\n         * Code for the DELETE key.\n         * @property KEY_DELETE\n         * @final\n         * @type {Number}\n         */\n        this.KEY_DELETE = 46;\n\n        /**\n         * Code for the 0 key.\n         * @property KEY_NUM_0\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_0 = 48;\n\n        /**\n         * Code for the 1 key.\n         * @property KEY_NUM_1\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_1 = 49;\n\n        /**\n         * Code for the 2 key.\n         * @property KEY_NUM_2\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_2 = 50;\n\n        /**\n         * Code for the 3 key.\n         * @property KEY_NUM_3\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_3 = 51;\n\n        /**\n         * Code for the 4 key.\n         * @property KEY_NUM_4\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_4 = 52;\n\n        /**\n         * Code for the 5 key.\n         * @property KEY_NUM_5\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_5 = 53;\n\n        /**\n         * Code for the 6 key.\n         * @property KEY_NUM_6\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_6 = 54;\n\n        /**\n         * Code for the 7 key.\n         * @property KEY_NUM_7\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_7 = 55;\n\n        /**\n         * Code for the 8 key.\n         * @property KEY_NUM_8\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_8 = 56;\n\n        /**\n         * Code for the 9 key.\n         * @property KEY_NUM_9\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_9 = 57;\n\n        /**\n         * Code for the A key.\n         * @property KEY_A\n         * @final\n         * @type {Number}\n         */\n        this.KEY_A = 65;\n\n        /**\n         * Code for the B key.\n         * @property KEY_B\n         * @final\n         * @type {Number}\n         */\n        this.KEY_B = 66;\n\n        /**\n         * Code for the C key.\n         * @property KEY_C\n         * @final\n         * @type {Number}\n         */\n        this.KEY_C = 67;\n\n        /**\n         * Code for the D key.\n         * @property KEY_D\n         * @final\n         * @type {Number}\n         */\n        this.KEY_D = 68;\n\n        /**\n         * Code for the E key.\n         * @property KEY_E\n         * @final\n         * @type {Number}\n         */\n        this.KEY_E = 69;\n\n        /**\n         * Code for the F key.\n         * @property KEY_F\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F = 70;\n\n        /**\n         * Code for the G key.\n         * @property KEY_G\n         * @final\n         * @type {Number}\n         */\n        this.KEY_G = 71;\n\n        /**\n         * Code for the H key.\n         * @property KEY_H\n         * @final\n         * @type {Number}\n         */\n        this.KEY_H = 72;\n\n        /**\n         * Code for the I key.\n         * @property KEY_I\n         * @final\n         * @type {Number}\n         */\n        this.KEY_I = 73;\n\n        /**\n         * Code for the J key.\n         * @property KEY_J\n         * @final\n         * @type {Number}\n         */\n        this.KEY_J = 74;\n\n        /**\n         * Code for the K key.\n         * @property KEY_K\n         * @final\n         * @type {Number}\n         */\n        this.KEY_K = 75;\n\n        /**\n         * Code for the L key.\n         * @property KEY_L\n         * @final\n         * @type {Number}\n         */\n        this.KEY_L = 76;\n\n        /**\n         * Code for the M key.\n         * @property KEY_M\n         * @final\n         * @type {Number}\n         */\n        this.KEY_M = 77;\n\n        /**\n         * Code for the N key.\n         * @property KEY_N\n         * @final\n         * @type {Number}\n         */\n        this.KEY_N = 78;\n\n        /**\n         * Code for the O key.\n         * @property KEY_O\n         * @final\n         * @type {Number}\n         */\n        this.KEY_O = 79;\n\n        /**\n         * Code for the P key.\n         * @property KEY_P\n         * @final\n         * @type {Number}\n         */\n        this.KEY_P = 80;\n\n        /**\n         * Code for the Q key.\n         * @property KEY_Q\n         * @final\n         * @type {Number}\n         */\n        this.KEY_Q = 81;\n\n        /**\n         * Code for the R key.\n         * @property KEY_R\n         * @final\n         * @type {Number}\n         */\n        this.KEY_R = 82;\n\n        /**\n         * Code for the S key.\n         * @property KEY_S\n         * @final\n         * @type {Number}\n         */\n        this.KEY_S = 83;\n\n        /**\n         * Code for the T key.\n         * @property KEY_T\n         * @final\n         * @type {Number}\n         */\n        this.KEY_T = 84;\n\n        /**\n         * Code for the U key.\n         * @property KEY_U\n         * @final\n         * @type {Number}\n         */\n        this.KEY_U = 85;\n\n        /**\n         * Code for the V key.\n         * @property KEY_V\n         * @final\n         * @type {Number}\n         */\n        this.KEY_V = 86;\n\n        /**\n         * Code for the W key.\n         * @property KEY_W\n         * @final\n         * @type {Number}\n         */\n        this.KEY_W = 87;\n\n        /**\n         * Code for the X key.\n         * @property KEY_X\n         * @final\n         * @type {Number}\n         */\n        this.KEY_X = 88;\n\n        /**\n         * Code for the Y key.\n         * @property KEY_Y\n         * @final\n         * @type {Number}\n         */\n        this.KEY_Y = 89;\n\n        /**\n         * Code for the Z key.\n         * @property KEY_Z\n         * @final\n         * @type {Number}\n         */\n        this.KEY_Z = 90;\n\n        /**\n         * Code for the LEFT_WINDOW key.\n         * @property KEY_LEFT_WINDOW\n         * @final\n         * @type {Number}\n         */\n        this.KEY_LEFT_WINDOW = 91;\n\n        /**\n         * Code for the RIGHT_WINDOW key.\n         * @property KEY_RIGHT_WINDOW\n         * @final\n         * @type {Number}\n         */\n        this.KEY_RIGHT_WINDOW = 92;\n\n        /**\n         * Code for the SELECT key.\n         * @property KEY_SELECT\n         * @final\n         * @type {Number}\n         */\n        this.KEY_SELECT_KEY = 93;\n\n        /**\n         * Code for the number pad 0 key.\n         * @property KEY_NUMPAD_0\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUMPAD_0 = 96;\n\n        /**\n         * Code for the number pad 1 key.\n         * @property KEY_NUMPAD_1\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUMPAD_1 = 97;\n\n        /**\n         * Code for the number pad 2 key.\n         * @property KEY_NUMPAD 2\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUMPAD_2 = 98;\n\n        /**\n         * Code for the number pad 3 key.\n         * @property KEY_NUMPAD_3\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUMPAD_3 = 99;\n\n        /**\n         * Code for the number pad 4 key.\n         * @property KEY_NUMPAD_4\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUMPAD_4 = 100;\n\n        /**\n         * Code for the number pad 5 key.\n         * @property KEY_NUMPAD_5\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUMPAD_5 = 101;\n\n        /**\n         * Code for the number pad 6 key.\n         * @property KEY_NUMPAD_6\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUMPAD_6 = 102;\n\n        /**\n         * Code for the number pad 7 key.\n         * @property KEY_NUMPAD_7\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUMPAD_7 = 103;\n\n        /**\n         * Code for the number pad 8 key.\n         * @property KEY_NUMPAD_8\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUMPAD_8 = 104;\n\n        /**\n         * Code for the number pad 9 key.\n         * @property KEY_NUMPAD_9\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUMPAD_9 = 105;\n\n        /**\n         * Code for the MULTIPLY key.\n         * @property KEY_MULTIPLY\n         * @final\n         * @type {Number}\n         */\n        this.KEY_MULTIPLY = 106;\n\n        /**\n         * Code for the ADD key.\n         * @property KEY_ADD\n         * @final\n         * @type {Number}\n         */\n        this.KEY_ADD = 107;\n\n        /**\n         * Code for the SUBTRACT key.\n         * @property KEY_SUBTRACT\n         * @final\n         * @type {Number}\n         */\n        this.KEY_SUBTRACT = 109;\n\n        /**\n         * Code for the DECIMAL POINT key.\n         * @property KEY_DECIMAL_POINT\n         * @final\n         * @type {Number}\n         */\n        this.KEY_DECIMAL_POINT = 110;\n\n        /**\n         * Code for the DIVIDE key.\n         * @property KEY_DIVIDE\n         * @final\n         * @type {Number}\n         */\n        this.KEY_DIVIDE = 111;\n\n        /**\n         * Code for the F1 key.\n         * @property KEY_F1\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F1 = 112;\n\n        /**\n         * Code for the F2 key.\n         * @property KEY_F2\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F2 = 113;\n\n        /**\n         * Code for the F3 key.\n         * @property KEY_F3\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F3 = 114;\n\n        /**\n         * Code for the F4 key.\n         * @property KEY_F4\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F4 = 115;\n\n        /**\n         * Code for the F5 key.\n         * @property KEY_F5\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F5 = 116;\n\n        /**\n         * Code for the F6 key.\n         * @property KEY_F6\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F6 = 117;\n\n        /**\n         * Code for the F7 key.\n         * @property KEY_F7\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F7 = 118;\n\n        /**\n         * Code for the F8 key.\n         * @property KEY_F8\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F8 = 119;\n\n        /**\n         * Code for the F9 key.\n         * @property KEY_F9\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F9 = 120;\n\n        /**\n         * Code for the F10 key.\n         * @property KEY_F10\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F10 = 121;\n\n        /**\n         * Code for the F11 key.\n         * @property KEY_F11\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F11 = 122;\n\n        /**\n         * Code for the F12 key.\n         * @property KEY_F12\n         * @final\n         * @type {Number}\n         */\n        this.KEY_F12 = 123;\n\n        /**\n         * Code for the NUM_LOCK key.\n         * @property KEY_NUM_LOCK\n         * @final\n         * @type {Number}\n         */\n        this.KEY_NUM_LOCK = 144;\n\n        /**\n         * Code for the SCROLL_LOCK key.\n         * @property KEY_SCROLL_LOCK\n         * @final\n         * @type {Number}\n         */\n        this.KEY_SCROLL_LOCK = 145;\n\n        /**\n         * Code for the SEMI_COLON key.\n         * @property KEY_SEMI_COLON\n         * @final\n         * @type {Number}\n         */\n        this.KEY_SEMI_COLON = 186;\n\n        /**\n         * Code for the EQUAL_SIGN key.\n         * @property KEY_EQUAL_SIGN\n         * @final\n         * @type {Number}\n         */\n        this.KEY_EQUAL_SIGN = 187;\n\n        /**\n         * Code for the COMMA key.\n         * @property KEY_COMMA\n         * @final\n         * @type {Number}\n         */\n        this.KEY_COMMA = 188;\n\n        /**\n         * Code for the DASH key.\n         * @property KEY_DASH\n         * @final\n         * @type {Number}\n         */\n        this.KEY_DASH = 189;\n\n        /**\n         * Code for the PERIOD key.\n         * @property KEY_PERIOD\n         * @final\n         * @type {Number}\n         */\n        this.KEY_PERIOD = 190;\n\n        /**\n         * Code for the FORWARD_SLASH key.\n         * @property KEY_FORWARD_SLASH\n         * @final\n         * @type {Number}\n         */\n        this.KEY_FORWARD_SLASH = 191;\n\n        /**\n         * Code for the GRAVE_ACCENT key.\n         * @property KEY_GRAVE_ACCENT\n         * @final\n         * @type {Number}\n         */\n        this.KEY_GRAVE_ACCENT = 192;\n\n        /**\n         * Code for the OPEN_BRACKET key.\n         * @property KEY_OPEN_BRACKET\n         * @final\n         * @type {Number}\n         */\n        this.KEY_OPEN_BRACKET = 219;\n\n        /**\n         * Code for the BACK_SLASH key.\n         * @property KEY_BACK_SLASH\n         * @final\n         * @type {Number}\n         */\n        this.KEY_BACK_SLASH = 220;\n\n        /**\n         * Code for the CLOSE_BRACKET key.\n         * @property KEY_CLOSE_BRACKET\n         * @final\n         * @type {Number}\n         */\n        this.KEY_CLOSE_BRACKET = 221;\n\n        /**\n         * Code for the SINGLE_QUOTE key.\n         * @property KEY_SINGLE_QUOTE\n         * @final\n         * @type {Number}\n         */\n        this.KEY_SINGLE_QUOTE = 222;\n\n        /**\n         * Code for the SPACE key.\n         * @property KEY_SPACE\n         * @final\n         * @type {Number}\n         */\n        this.KEY_SPACE = 32;\n\n        /**\n         * Code for the left mouse button.\n         * @property MOUSE_LEFT_BUTTON\n         * @final\n         * @type {Number}\n         */\n        this.MOUSE_LEFT_BUTTON = 260;\n\n        /**\n         * Code for the middle mouse button.\n         * @property MOUSE_MIDDLE_BUTTON\n         * @final\n         * @type {Number}\n         */\n        this.MOUSE_MIDDLE_BUTTON = 261;\n\n        /**\n         * Code for the right mouse button.\n         * @property MOUSE_RIGHT_BUTTON\n         * @final\n         * @type {Number}\n         */\n        this.MOUSE_RIGHT_BUTTON = 262;\n\n        /**\n         * The canvas element that mouse and keyboards are bound to.\n         *\n         * @final\n         * @type {HTMLCanvasElement}\n         */\n        this.element = cfg.element;\n\n        /** True whenever ALT key is down.\n         *\n         * @type {boolean}\n         */\n        this.altDown = false;\n\n        /** True whenever CTRL key is down.\n         *\n         * @type {boolean}\n         */\n        this.ctrlDown = false;\n\n        /** True whenever left mouse button is down.\n         *\n         * @type {boolean}\n         */\n        this.mouseDownLeft = false;\n\n        /**\n         * True whenever middle mouse button is down.\n         *\n         * @type {boolean}\n         */\n        this.mouseDownMiddle = false;\n\n        /**\n         * True whenever the right mouse button is down.\n         *\n         * @type {boolean}\n         */\n        this.mouseDownRight = false;\n\n        /**\n         * Flag for each key that's down.\n         *\n         * @type {boolean[]}\n         */\n        this.keyDown = [];\n\n        /** True while input enabled\n         *\n         * @type {boolean}\n         */\n        this.enabled = true;\n\n        /** True while keyboard input is enabled.\n         *\n         * Default value is ````true````.\n         *\n         * {@link CameraControl} will not respond to keyboard events while this is ````false````.\n         *\n         * @type {boolean}\n         */\n        this.keyboardEnabled = true;\n\n        /** True while the mouse is over the canvas.\n         *\n         * @type {boolean}\n         */\n        this.mouseover = false;\n\n        /**\n         * Current mouse position within the canvas.\n         * @type {Number[]}\n         */\n        this.mouseCanvasPos = math.vec2();\n\n        this._keyboardEventsElement = cfg.keyboardEventsElement || document;\n\n        this._bindEvents();\n    }\n\n    _bindEvents() {\n\n        if (this._eventsBound) {\n            return;\n        }\n\n        this._keyboardEventsElement.addEventListener(\"keydown\", this._keyDownListener = (e) => {\n            if (!this.enabled || (!this.keyboardEnabled)) {\n                return;\n            }\n            if (e.target.tagName !== \"INPUT\" && e.target.tagName !== \"TEXTAREA\") {\n                if (e.keyCode === this.KEY_CTRL) {\n                    this.ctrlDown = true;\n                } else if (e.keyCode === this.KEY_ALT) {\n                    this.altDown = true;\n                } else if (e.keyCode === this.KEY_SHIFT) {\n                    this.shiftDown = true;\n                }\n                this.keyDown[e.keyCode] = true;\n                this.fire(\"keydown\", e.keyCode, true);\n            }\n        }, false);\n\n        this._keyboardEventsElement.addEventListener(\"keyup\", this._keyUpListener = (e) => {\n            if (!this.enabled || (!this.keyboardEnabled)) {\n                return;\n            }\n            if (e.target.tagName !== \"INPUT\" && e.target.tagName !== \"TEXTAREA\") {\n                if (e.keyCode === this.KEY_CTRL) {\n                    this.ctrlDown = false;\n                } else if (e.keyCode === this.KEY_ALT) {\n                    this.altDown = false;\n                } else if (e.keyCode === this.KEY_SHIFT) {\n                    this.shiftDown = false;\n                }\n                this.keyDown[e.keyCode] = false;\n                this.fire(\"keyup\", e.keyCode, true);\n            }\n        });\n\n        this.element.addEventListener(\"mouseenter\", this._mouseEnterListener = (e) => {\n            if (!this.enabled) {\n                return;\n            }\n            this.mouseover = true;\n            this._getMouseCanvasPos(e);\n            this.fire(\"mouseenter\", this.mouseCanvasPos, true);\n        });\n\n        this.element.addEventListener(\"mouseleave\", this._mouseLeaveListener = (e) => {\n            if (!this.enabled) {\n                return;\n            }\n            this.mouseover = false;\n            this._getMouseCanvasPos(e);\n            this.fire(\"mouseleave\", this.mouseCanvasPos, true);\n        });\n\n        this.element.addEventListener(\"mousedown\", this._mouseDownListener = (e) => {\n            if (!this.enabled) {\n                return;\n            }\n            switch (e.which) {\n                case 1:// Left button\n                    this.mouseDownLeft = true;\n                    break;\n                case 2:// Middle/both buttons\n                    this.mouseDownMiddle = true;\n                    break;\n                case 3:// Right button\n                    this.mouseDownRight = true;\n                    break;\n            }\n            this._getMouseCanvasPos(e);\n            this.element.focus();\n            this.fire(\"mousedown\", this.mouseCanvasPos, true);\n            if (this.mouseover) {\n                e.preventDefault();\n            }\n        });\n\n        document.addEventListener(\"mouseup\", this._mouseUpListener = (e) => {\n            if (!this.enabled) {\n                return;\n            }\n            switch (e.which) {\n                case 1:// Left button\n                    this.mouseDownLeft = false;\n                    break;\n                case 2:// Middle/both buttons\n                    this.mouseDownMiddle = false;\n                    break;\n                case 3:// Right button\n                    this.mouseDownRight = false;\n                    break;\n            }\n            this.fire(\"mouseup\", this.mouseCanvasPos, true);\n            // if (this.mouseover) {\n            //     e.preventDefault();\n            // }\n        }, true);\n\n        document.addEventListener(\"click\", this._clickListener = (e) => {\n            if (!this.enabled) {\n                return;\n            }\n            switch (e.which) {\n                case 1:// Left button\n                    this.mouseDownLeft = false;\n                    this.mouseDownRight = false;\n                    break;\n                case 2:// Middle/both buttons\n                    this.mouseDownMiddle = false;\n                    break;\n                case 3:// Right button\n                    this.mouseDownLeft = false;\n                    this.mouseDownRight = false;\n                    break;\n            }\n            this._getMouseCanvasPos(e);\n            this.fire(\"click\", this.mouseCanvasPos, true);\n            if (this.mouseover) {\n                e.preventDefault();\n            }\n        });\n\n        document.addEventListener(\"dblclick\", this._dblClickListener = (e) => {\n            if (!this.enabled) {\n                return;\n            }\n            switch (e.which) {\n                case 1:// Left button\n                    this.mouseDownLeft = false;\n                    this.mouseDownRight = false;\n                    break;\n                case 2:// Middle/both buttons\n                    this.mouseDownMiddle = false;\n                    break;\n                case 3:// Right button\n                    this.mouseDownLeft = false;\n                    this.mouseDownRight = false;\n                    break;\n            }\n            this._getMouseCanvasPos(e);\n            this.fire(\"dblclick\", this.mouseCanvasPos, true);\n            if (this.mouseover) {\n                e.preventDefault();\n            }\n        });\n\n        const tickifedMouseMoveFn = this.scene.tickify(\n            () => this.fire(\"mousemove\", this.mouseCanvasPos, true)\n        );\n\n        this.element.addEventListener(\"mousemove\", this._mouseMoveListener = (e) => {\n            if (!this.enabled) {\n                return;\n            }\n            this._getMouseCanvasPos(e);\n            tickifedMouseMoveFn();  \n            if (this.mouseover) {\n                e.preventDefault();\n            }\n        });\n\n        this.element.addEventListener(\"contextmenu\", this._contextmenuListener = (e) => {\n            if (!this.enabled) {\n                return;\n            }\n            this._getMouseCanvasPos(e);\n            this.fire(\"contextmenu\", this.mouseCanvasPos, true);\n        });\n\n        const tickifiedMouseWheelFn = this.scene.tickify(\n            (delta) => { this.fire(\"mousewheel\", delta, true); }\n        );\n\n        this.element.addEventListener(\"wheel\", this._mouseWheelListener = (e, d) => {\n            if (!this.enabled) {\n                return;\n            }\n            const delta = Math.max(-1, Math.min(1, -e.deltaY * 40));\n            tickifiedMouseWheelFn(delta);\n        }, {passive: true});\n\n        // mouseclicked\n\n        {\n            let downX;\n            let downY;\n            // Tolerance between down and up positions for a mouse click\n            const tolerance = 2;\n            this.on(\"mousedown\", (params) => {\n                downX = params[0];\n                downY = params[1];\n            });\n            this.on(\"mouseup\", (params) => {\n                if (downX >= (params[0] - tolerance) &&\n                    downX <= (params[0] + tolerance) &&\n                    downY >= (params[1] - tolerance) &&\n                    downY <= (params[1] + tolerance)) {\n                    this.fire(\"mouseclicked\", params, true);\n                }\n            });\n        }\n\n        this.element.addEventListener(\"touchstart\", this._touchstartListener = (e) => {\n            if (!this.enabled) {\n                return;\n            }\n            [...e.changedTouches].forEach(e => {\n                this.fire(\"touchstart\", [ e.identifier, this._getTouchCanvasPos(e) ], true);\n            });\n        });\n\n        this.element.addEventListener(\"touchend\", this._touchendListener = (e) => {\n            if (!this.enabled) {\n                return;\n            }\n            [...e.changedTouches].forEach(e => {\n                this.fire(\"touchend\", [ e.identifier, this._getTouchCanvasPos(e) ], true);\n            });\n        });\n\n        this._eventsBound = true;\n    }\n\n    _unbindEvents() {\n        if (!this._eventsBound) {\n            return;\n        }\n        this._keyboardEventsElement.removeEventListener(\"keydown\", this._keyDownListener);\n        this._keyboardEventsElement.removeEventListener(\"keyup\", this._keyUpListener);\n        this.element.removeEventListener(\"mouseenter\", this._mouseEnterListener);\n        this.element.removeEventListener(\"mouseleave\", this._mouseLeaveListener);\n        this.element.removeEventListener(\"mousedown\", this._mouseDownListener);\n        document.removeEventListener(\"mouseup\", this._mouseDownListener);\n        document.removeEventListener(\"click\", this._clickListener);\n        document.removeEventListener(\"dblclick\", this._dblClickListener);\n        this.element.removeEventListener(\"mousemove\", this._mouseMoveListener);\n        this.element.removeEventListener(\"contextmenu\", this._contextmenuListener);\n        this.element.removeEventListener(\"wheel\", this._mouseWheelListener);\n        this.element.removeEventListener(\"touchstart\", this._touchstartListener);\n        this.element.removeEventListener(\"touchend\", this._touchendListener);\n        if (window.OrientationChangeEvent) {\n            window.removeEventListener('orientationchange', this._orientationchangedListener);\n        }\n        if (window.DeviceMotionEvent) {\n            window.removeEventListener('devicemotion', this._deviceMotionListener);\n        }\n        if (window.DeviceOrientationEvent) {\n            window.removeEventListener(\"deviceorientation\", this._deviceOrientListener);\n        }\n        this._eventsBound = false;\n    }\n\n    _getTouchCanvasPos(event) {\n        let element = event.target;\n        let totalOffsetLeft = 0;\n        let totalOffsetTop = 0;\n        while (element.offsetParent) {\n            totalOffsetLeft += element.offsetLeft;\n            totalOffsetTop += element.offsetTop;\n            element = element.offsetParent;\n        }\n        return [ event.pageX - totalOffsetLeft, event.pageY - totalOffsetTop ];\n    }\n\n    _getMouseCanvasPos(event) {\n        if (!event) {\n            event = window.event;\n            this.mouseCanvasPos[0] = event.x;\n            this.mouseCanvasPos[1] = event.y;\n        } else {\n            let element = event.target;\n\n            const rect = element.getBoundingClientRect();\n\n            this.mouseCanvasPos[0] = event.clientX - rect.left;\n            this.mouseCanvasPos[1] = event.clientY - rect.top;\n        }\n    }\n\n    /**\n     * Sets whether input handlers are enabled.\n     *\n     * Default value is ````true````.\n     *\n     * @param {Boolean} enable Indicates if input handlers are enabled.\n     */\n    setEnabled(enable) {\n        if (this.enabled !== enable) {\n            this.fire(\"enabled\", this.enabled = enable);\n        }\n    }\n\n    /**\n     * Gets whether input handlers are enabled.\n     *\n     * Default value is ````true````.\n     *\n     * @returns {Boolean} Indicates if input handlers are enabled.\n     */\n    getEnabled() {\n        return this.enabled;\n    }\n\n    /**\n     * Sets whether or not keyboard input is enabled.\n     *\n     * Default value is ````true````.\n     *\n     * {@link CameraControl} will not respond to keyboard events while this is set ````false````.\n     *\n     * @param {Boolean} value Indicates whether keyboard input is enabled.\n     */\n    setKeyboardEnabled(value) {\n        this.keyboardEnabled = value;\n    }\n\n    /**\n     * Gets whether keyboard input is enabled.\n     *\n     * Default value is ````true````.\n     *\n     * {@link CameraControl} will not respond to keyboard events while this is set ````false````.\n     *\n     * @returns {Boolean} Returns whether keyboard input is enabled.\n     */\n    getKeyboardEnabled() {\n        return this.keyboardEnabled;\n    }\n\n    /**\n     * @private\n     */\n    destroy() {\n        super.destroy();\n        this._unbindEvents();\n    }\n}\n\n/**\n * @desc controls the canvas viewport for a {@link Scene}.\n *\n * * One Viewport per scene.\n * * You can configure a Scene to render multiple times per frame, while setting the Viewport to different extents on each render.\n * * Make a Viewport automatically size to its {@link Scene} {@link Canvas} by setting its {@link Viewport#autoBoundary} ````true````.\n *\n *\n * Configuring the Scene to render twice on each frame, each time to a separate viewport:\n *\n * ````Javascript\n * // Load glTF model\n * var model = new xeokit.GLTFModel({\n    src: \"models/gltf/GearboxAssy/glTF-MaterialsCommon/GearboxAssy.gltf\"\n });\n\n var scene = model.scene;\n var viewport = scene.viewport;\n\n // Configure Scene to render twice for each frame\n scene.passes = 2; // Default is 1\n scene.clearEachPass = false; // Default is false\n\n // Render to a separate viewport on each render\n\n var viewport = scene.viewport;\n viewport.autoBoundary = false;\n\n scene.on(\"rendering\", function (e) {\n     switch (e.pass) {\n         case 0:\n             viewport.boundary = [0, 0, 200, 200]; // xmin, ymin, width, height\n             break;\n\n         case 1:\n             viewport.boundary = [200, 0, 200, 200];\n             break;\n     }\n });\n ````\n\n @class Viewport\n @module xeokit\n @submodule rendering\n @constructor\n @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n @param {*} [cfg] Viewport configuration\n @param {String} [cfg.id] Optional ID, unique among all components in the parent\n {@link Scene}, generated automatically when omitted.\n @param {String:Object} [cfg.meta] Optional map of user-defined metadata to attach to this Viewport.\n @param [cfg.boundary] {Number[]} Canvas-space Viewport boundary, given as\n (min, max, width, height). Defaults to the size of the parent\n {@link Scene} {@link Canvas}.\n @param [cfg.autoBoundary=false] {Boolean} Indicates if this Viewport's {@link Viewport#boundary}\n automatically synchronizes with the size of the parent {@link Scene} {@link Canvas}.\n\n @extends Component\n */\n\nclass Viewport extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Viewport\";\n    }\n\n    /**\n     @private\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            boundary: [0, 0, 100, 100]\n        });\n\n        this.boundary = cfg.boundary;\n        this.autoBoundary = cfg.autoBoundary;\n    }\n\n\n    /**\n     * Sets the canvas-space boundary of this Viewport, indicated as ````[min, max, width, height]````.\n     *\n     * When {@link Viewport#autoBoundary} is ````true````, ignores calls to this method and automatically synchronizes with {@link Canvas#boundary}.\n     *\n     * Fires a \"boundary\"\" event on change.\n     *\n     * Defaults to the {@link Canvas} extents.\n     *\n     * @param {Number[]} value New Viewport extents.\n     */\n    set boundary(value) {\n\n        if (this._autoBoundary) {\n            return;\n        }\n\n        if (!value) {\n\n            const canvasBoundary = this.scene.canvas.boundary;\n\n            const width = canvasBoundary[2];\n            const height = canvasBoundary[3];\n\n            value = [0, 0, width, height];\n        }\n\n        this._state.boundary = value;\n\n        this.glRedraw();\n\n        /**\n         Fired whenever this Viewport's {@link Viewport#boundary} property changes.\n\n         @event boundary\n         @param value {Boolean} The property's new value\n         */\n        this.fire(\"boundary\", this._state.boundary);\n    }\n\n    /**\n     * Gets the canvas-space boundary of this Viewport, indicated as ````[min, max, width, height]````.\n     *\n     * @returns {Number[]} The Viewport extents.\n     */\n    get boundary() {\n        return this._state.boundary;\n    }\n\n    /**\n     * Sets if {@link Viewport#boundary} automatically synchronizes with {@link Canvas#boundary}.\n     *\n     * Default is ````false````.\n     *\n     * @param {Boolean} value Set true to automatically sycnhronize.\n     */\n    set autoBoundary(value) {\n\n        value = !!value;\n\n        if (value === this._autoBoundary) {\n            return;\n        }\n\n        this._autoBoundary = value;\n\n        if (this._autoBoundary) {\n            this._onCanvasSize = this.scene.canvas.on(\"boundary\",\n                function (boundary) {\n\n                    const width = boundary[2];\n                    const height = boundary[3];\n\n                    this._state.boundary = [0, 0, width, height];\n\n                    this.glRedraw();\n\n                    /**\n                     Fired whenever this Viewport's {@link Viewport#boundary} property changes.\n\n                     @event boundary\n                     @param value {Boolean} The property's new value\n                     */\n                    this.fire(\"boundary\", this._state.boundary);\n\n                }, this);\n\n        } else if (this._onCanvasSize) {\n            this.scene.canvas.off(this._onCanvasSize);\n            this._onCanvasSize = null;\n        }\n\n        /**\n         Fired whenever this Viewport's {@link autoBoundary/autoBoundary} property changes.\n\n         @event autoBoundary\n         @param value The property's new value\n         */\n        this.fire(\"autoBoundary\", this._autoBoundary);\n    }\n\n    /**\n     * Gets if {@link Viewport#boundary} automatically synchronizes with {@link Canvas#boundary}.\n     *\n     * Default is ````false````.\n     *\n     * @returns {Boolean} Returns ````true```` when automatically sycnhronizing.\n     */\n    get autoBoundary() {\n        return this._autoBoundary;\n    }\n\n    _getState() {\n        return this._state;\n    }\n\n    /**\n     * @private\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\n/**\n * @desc Defines its {@link Camera}'s perspective projection using a field-of-view angle.\n *\n * * Located at {@link Camera#perspective}.\n * * Implicitly sets the left, right, top, bottom frustum planes using {@link Perspective#fov}.\n * * {@link Perspective#near} and {@link Perspective#far} specify the distances to the WebGL clipping planes.\n */\nclass Perspective extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Perspective\";\n    }\n\n    /**\n     * @constructor\n     * @private\n     */\n    constructor(camera, cfg = {}) {\n\n        super(camera, cfg);\n\n        /**\n         * The Camera this Perspective belongs to.\n         *\n         * @property camera\n         * @type {Camera}\n         * @final\n         */\n        this.camera = camera;\n\n        this._state = new RenderState({\n            matrix: math.mat4(),\n            inverseMatrix: math.mat4(),\n            transposedMatrix: math.mat4(),\n            near: 0.1,\n            far: 10000.0\n        });\n\n        this._inverseMatrixDirty = true;\n        this._transposedMatrixDirty = true;\n\n        this._fov = 60.0;\n\n        // Recompute aspect from change in canvas size\n        this._canvasResized = this.scene.canvas.on(\"boundary\", this._needUpdate, this);\n\n        this.fov = cfg.fov;\n        this.fovAxis = cfg.fovAxis;\n        this.near = cfg.near;\n        this.far = cfg.far;\n    }\n\n    _update() {\n\n        const WIDTH_INDEX = 2;\n        const HEIGHT_INDEX = 3;\n        const boundary = this.scene.canvas.boundary;\n        const aspect = boundary[WIDTH_INDEX] / boundary[HEIGHT_INDEX];\n        const fovAxis = this._fovAxis;\n\n        let fov = this._fov;\n        if (fovAxis === \"x\" || (fovAxis === \"min\" && aspect < 1) || (fovAxis === \"max\" && aspect > 1)) {\n            fov = fov / aspect;\n        }\n        fov = Math.min(fov, 120);\n\n        math.perspectiveMat4(fov * (Math.PI / 180.0), aspect, this._state.near, this._state.far, this._state.matrix);\n\n        this._inverseMatrixDirty = true;\n        this._transposedMatrixDirty = true;\n\n        this.glRedraw();\n\n        this.camera._updateScheduled = true;\n\n        this.fire(\"matrix\", this._state.matrix);\n    }\n\n    /**\n     * Sets the Perspective's field-of-view angle (FOV).\n     *\n     * Fires an \"fov\" event on change.\n\n     * Default value is ````60.0````.\n     *\n     * @param {Number} value New field-of-view.\n     */\n    set fov(value) {\n        value = (value !== undefined && value !== null) ? value : 60.0;\n        if (value === this._fov) {\n            return;\n        }\n        this._fov = value;\n        this._needUpdate(0); // Ensure matrix built on next \"tick\"\n        this.fire(\"fov\", this._fov);\n    }\n\n    /**\n     * Gets the Perspective's field-of-view angle (FOV).\n     *\n     * Default value is ````60.0````.\n     *\n     * @returns {Number} Current field-of-view.\n     */\n    get fov() {\n        return this._fov;\n    }\n\n    /**\n     * Sets the Perspective's FOV axis.\n     *\n     * Options are ````\"x\"````, ````\"y\"```` or ````\"min\"````, to use the minimum axis.\n     *\n     * Fires an \"fovAxis\" event on change.\n\n     * Default value ````\"min\"````.\n     *\n     * @param {String} value New FOV axis value.\n     */\n    set fovAxis(value) {\n        value = value || \"min\";\n        if (this._fovAxis === value) {\n            return;\n        }\n        if (value !== \"x\" && value !== \"y\" && value !== \"min\") {\n            this.error(\"Unsupported value for 'fovAxis': \" + value + \" - defaulting to 'min'\");\n            value = \"min\";\n        }\n        this._fovAxis = value;\n        this._needUpdate(0); // Ensure matrix built on next \"tick\"\n        this.fire(\"fovAxis\", this._fovAxis);\n    }\n\n    /**\n     * Gets the Perspective's FOV axis.\n     *\n     * Options are ````\"x\"````, ````\"y\"```` or ````\"min\"````, to use the minimum axis.\n     *\n     * Fires an \"fovAxis\" event on change.\n\n     * Default value is ````\"min\"````.\n     *\n     * @returns {String} The current FOV axis value.\n     */\n    get fovAxis() {\n        return this._fovAxis;\n    }\n\n    /**\n     * Sets the position of the Perspective's near plane on the positive View-space Z-axis.\n     *\n     * Fires a \"near\" event on change.\n     *\n     * Default value is ````0.1````.\n     *\n     * @param {Number} value New Perspective near plane position.\n     */\n    set near(value) {\n        const near = (value !== undefined && value !== null) ? value : 0.1;\n        if (this._state.near === near) {\n            return;\n        }\n        this._state.near = near;\n        this._needUpdate(0); // Ensure matrix built on next \"tick\"\n        this.fire(\"near\", this._state.near);\n    }\n\n    /**\n     * Gets the position of the Perspective's near plane on the positive View-space Z-axis.\n     *\n     * Fires an \"emits\" emits on change.\n     *\n     * Default value is ````0.1````.\n     *\n     * @returns The Perspective's near plane position.\n     */\n    get near() {\n        return this._state.near;\n    }\n\n    /**\n     * Sets the position of this Perspective's far plane on the positive View-space Z-axis.\n     *\n     * Fires a \"far\" event on change.\n     *\n     * Default value is ````10000.0````.\n     *\n     * @param {Number} value New Perspective far plane position.\n     */\n    set far(value) {\n        const far = (value !== undefined && value !== null) ? value : 10000.0;\n        if (this._state.far === far) {\n            return;\n        }\n        this._state.far = far;\n        this._needUpdate(0); // Ensure matrix built on next \"tick\"\n        this.fire(\"far\", this._state.far);\n    }\n\n    /**\n     * Gets the position of this Perspective's far plane on the positive View-space Z-axis.\n     *\n     * Default value is ````10000.0````.\n     *\n     * @return {Number} The Perspective's far plane position.\n     */\n    get far() {\n        return this._state.far;\n    }\n\n    /**\n     * Gets the Perspective's projection transform matrix.\n     *\n     * Fires a \"matrix\" event on change.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @returns {Number[]} The Perspective's projection matrix.\n     */\n    get matrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        return this._state.matrix;\n    }\n\n    /**\n     * Gets the inverse of {@link Perspective#matrix}.\n     *\n     * @returns {Number[]} The inverse of {@link Perspective#matrix}.\n     */\n    get inverseMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        if (this._inverseMatrixDirty) {\n            math.inverseMat4(this._state.matrix, this._state.inverseMatrix);\n            this._inverseMatrixDirty = false;\n        }\n        return this._state.inverseMatrix;\n    }\n\n    /**\n     * Gets the transpose of {@link Perspective#matrix}.\n     *\n     * @returns {Number[]} The transpose of {@link Perspective#matrix}.\n     */\n    get transposedMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        if (this._transposedMatrixDirty) {\n            math.transposeMat4(this._state.matrix, this._state.transposedMatrix);\n            this._transposedMatrixDirty = false;\n        }\n        return this._state.transposedMatrix;\n    }\n\n    /**\n     * Un-projects the given Canvas-space coordinates and Screen-space depth, using this Perspective projection.\n     *\n     * @param {Number[]} canvasPos Inputs 2D Canvas-space coordinates.\n     * @param {Number} screenZ Inputs Screen-space Z coordinate.\n     * @param {Number[]} screenPos Outputs 3D Screen/Clip-space coordinates.\n     * @param {Number[]} viewPos Outputs un-projected 3D View-space coordinates.\n     * @param {Number[]} worldPos Outputs un-projected 3D World-space coordinates.\n     */\n    unproject(canvasPos, screenZ, screenPos, viewPos, worldPos) {\n\n        const canvas = this.scene.canvas.canvas;\n\n        const halfCanvasWidth = canvas.offsetWidth / 2.0;\n        const halfCanvasHeight = canvas.offsetHeight / 2.0;\n\n        screenPos[0] = (canvasPos[0] - halfCanvasWidth) / halfCanvasWidth;\n        screenPos[1] = (canvasPos[1] - halfCanvasHeight) / halfCanvasHeight;\n        screenPos[2] = screenZ;\n        screenPos[3] = 1.0;\n\n        math.mulMat4v4(this.inverseMatrix, screenPos, viewPos);\n        math.mulVec3Scalar(viewPos, 1.0 / viewPos[3]);\n\n        viewPos[3] = 1.0;\n        viewPos[1] *= -1;\n\n        math.mulMat4v4(this.camera.inverseViewMatrix, viewPos, worldPos);\n\n        return worldPos;\n    }\n\n    /** @private\n     *\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n        this.scene.canvas.off(this._canvasResized);\n    }\n}\n\n/**\n * @desc Defines its {@link Camera}'s orthographic projection as a box-shaped view volume.\n *\n * * Located at {@link Camera#ortho}.\n * * Works like Blender's orthographic projection, where the positions of the left, right, top and bottom planes are implicitly\n * indicated with a single {@link Ortho#scale} property, which causes the frustum to be symmetrical on X and Y axis, large enough to\n * contain the number of units given by {@link Ortho#scale}.\n * * {@link Ortho#near} and {@link Ortho#far} indicated the distances to the WebGL clipping planes.\n */\nclass Ortho extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Ortho\";\n    }\n\n    /**\n     * @constructor\n     * @private\n     */\n    constructor(camera, cfg = {}) {\n\n        super(camera, cfg);\n\n        /**\n         * The Camera this Ortho belongs to.\n         *\n         * @property camera\n         * @type {Camera}\n         * @final\n         */\n        this.camera = camera;\n\n        this._state = new RenderState({\n            matrix: math.mat4(),\n            inverseMatrix: math.mat4(),\n            transposedMatrix: math.mat4(),\n            near: 0.1,\n            far: 10000.0\n        });\n\n        this._inverseMatrixDirty = true;\n        this._transposedMatrixDirty = true;\n\n        this.scale = cfg.scale;\n        this.near = cfg.near;\n        this.far = cfg.far;\n\n        this._onCanvasBoundary = this.scene.canvas.on(\"boundary\", this._needUpdate, this);\n    }\n\n    _update() {\n\n        const WIDTH_INDEX = 2;\n        const HEIGHT_INDEX = 3;\n\n        const scene = this.scene;\n        const scale = this._scale;\n        const halfSize = 0.5 * scale;\n\n        const boundary = scene.canvas.boundary;\n        const boundaryWidth = boundary[WIDTH_INDEX];\n        const boundaryHeight = boundary[HEIGHT_INDEX];\n        const aspect = boundaryWidth / boundaryHeight;\n\n        let left;\n        let right;\n        let top;\n        let bottom;\n\n        if (boundaryWidth > boundaryHeight) {\n            left = -halfSize;\n            right = halfSize;\n            top = halfSize / aspect;\n            bottom = -halfSize / aspect;\n\n        } else {\n            left = -halfSize * aspect;\n            right = halfSize * aspect;\n            top = halfSize;\n            bottom = -halfSize;\n        }\n\n        math.orthoMat4c(left, right, bottom, top, this._state.near, this._state.far, this._state.matrix);\n\n        this._inverseMatrixDirty = true;\n        this._transposedMatrixDirty = true;\n\n        this.glRedraw();\n\n        this.fire(\"matrix\", this._state.matrix);\n    }\n\n\n    /**\n     * Sets scale factor for this Ortho's extents on X and Y axis.\n     *\n     * Clamps to minimum value of ````0.01```.\n     *\n     * Fires a \"scale\" event on change.\n     *\n     * Default value is ````1.0````\n     * @param {Number} value New scale value.\n     */\n    set scale(value) {\n        if (value === undefined || value === null) {\n            value = 1.0;\n        }\n        if (value <= 0) {\n            value = 0.01;\n        }\n        this._scale = value;\n        this._needUpdate(0);\n        this.fire(\"scale\", this._scale);\n    }\n\n    /**\n     * Gets scale factor for this Ortho's extents on X and Y axis.\n     *\n     * Clamps to minimum value of ````0.01```.\n     *\n     * Default value is ````1.0````\n     *\n     * @returns {Number} New Ortho scale value.\n     */\n    get scale() {\n        return this._scale;\n    }\n\n    /**\n     * Sets the position of the Ortho's near plane on the positive View-space Z-axis.\n     *\n     * Fires a \"near\" emits on change.\n     *\n     * Default value is ````0.1````.\n     *\n     * @param {Number} value New Ortho near plane position.\n     */\n    set near(value) {\n        const near = (value !== undefined && value !== null) ? value : 0.1;\n        if (this._state.near === near) {\n            return;\n        }\n        this._state.near = near;\n        this._needUpdate(0);\n        this.fire(\"near\", this._state.near);\n    }\n\n    /**\n     * Gets the position of the Ortho's near plane on the positive View-space Z-axis.\n     *\n     * Default value is ````0.1````.\n     *\n     * @returns {Number} New Ortho near plane position.\n     */\n    get near() {\n        return this._state.near;\n    }\n\n    /**\n     * Sets the position of the Ortho's far plane on the positive View-space Z-axis.\n     *\n     * Fires a \"far\" event on change.\n     *\n     * Default value is ````10000.0````.\n     *\n     * @param {Number} value New far ortho plane position.\n     */\n    set far(value) {\n        const far = (value !== undefined && value !== null) ? value : 10000.0;\n        if (this._state.far === far) {\n            return;\n        }\n        this._state.far = far;\n        this._needUpdate(0);\n        this.fire(\"far\", this._state.far);\n    }\n\n    /**\n     * Gets the position of the Ortho's far plane on the positive View-space Z-axis.\n     *\n     * Default value is ````10000.0````.\n     *\n     * @returns {Number} New far ortho plane position.\n     */\n    get far() {\n        return this._state.far;\n    }\n\n    /**\n     * Gets the Ortho's projection transform matrix.\n     *\n     * Fires a \"matrix\" event on change.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @returns {Number[]} The Ortho's projection matrix.\n     */\n    get matrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        return this._state.matrix;\n    }\n\n    /**\n     * Gets the inverse of {@link Ortho#matrix}.\n     *\n     * @returns {Number[]} The inverse of {@link Ortho#matrix}.\n     */\n    get inverseMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        if (this._inverseMatrixDirty) {\n            math.inverseMat4(this._state.matrix, this._state.inverseMatrix);\n            this._inverseMatrixDirty = false;\n        }\n        return this._state.inverseMatrix;\n    }\n\n    /**\n     * Gets the transpose of {@link Ortho#matrix}.\n     *\n     * @returns {Number[]} The transpose of {@link Ortho#matrix}.\n     */\n    get transposedMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        if (this._transposedMatrixDirty) {\n            math.transposeMat4(this._state.matrix, this._state.transposedMatrix);\n            this._transposedMatrixDirty = false;\n        }\n        return this._state.transposedMatrix;\n    }\n\n    /**\n     * Un-projects the given Canvas-space coordinates, using this Ortho projection.\n     *\n     * @param {Number[]} canvasPos Inputs 2D Canvas-space coordinates.\n     * @param {Number} screenZ Inputs Screen-space Z coordinate.\n     * @param {Number[]} screenPos Outputs 3D Screen/Clip-space coordinates.\n     * @param {Number[]} viewPos Outputs un-projected 3D View-space coordinates.\n     * @param {Number[]} worldPos Outputs un-projected 3D World-space coordinates.\n     */\n    unproject(canvasPos, screenZ, screenPos, viewPos, worldPos) {\n\n        const canvas = this.scene.canvas.canvas;\n\n        const halfCanvasWidth = canvas.offsetWidth / 2.0;\n        const halfCanvasHeight = canvas.offsetHeight / 2.0;\n\n        screenPos[0] = (canvasPos[0] - halfCanvasWidth) / halfCanvasWidth;\n        screenPos[1] = (canvasPos[1] - halfCanvasHeight) / halfCanvasHeight;\n        screenPos[2] = screenZ;\n        screenPos[3] = 1.0;\n\n        math.mulMat4v4(this.inverseMatrix, screenPos, viewPos);\n        math.mulVec3Scalar(viewPos, 1.0 / viewPos[3]);\n\n        viewPos[3] = 1.0;\n        viewPos[1] *= -1;\n\n        math.mulMat4v4(this.camera.inverseViewMatrix, viewPos, worldPos);\n\n        return worldPos;\n    }\n\n    /** @private\n     *\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n        this.scene.canvas.off(this._onCanvasBoundary);\n    }\n}\n\n/**\n * @desc Defines its {@link Camera}'s perspective projection as a frustum-shaped view volume.\n *\n * * Located at {@link Camera#frustum}.\n * * Allows to explicitly set the positions of the left, right, top, bottom, near and far planes, which is useful for asymmetrical view volumes, such as for stereo viewing.\n * * {@link Frustum#near} and {@link Frustum#far} specify the distances to the WebGL clipping planes.\n */\nclass Frustum extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Frustum\";\n    }\n\n    /**\n     * @constructor\n     * @private\n     */\n    constructor(camera, cfg = {}) {\n\n        super(camera, cfg);\n\n        /**\n         * The Camera this Frustum belongs to.\n         *\n         * @property camera\n         * @type {Camera}\n         * @final\n         */\n        this.camera = camera;\n\n        this._state = new RenderState({\n            matrix: math.mat4(),\n            inverseMatrix: math.mat4(),\n            transposedMatrix: math.mat4(),\n            near: 0.1,\n            far: 10000.0\n        });\n\n        this._left = -1.0;\n        this._right = 1.0;\n        this._bottom = -1.0;\n        this._top = 1.0;\n\n        this._inverseMatrixDirty = true;\n        this._transposedMatrixDirty = true;\n\n        // Set component properties\n\n        this.left = cfg.left;\n        this.right = cfg.right;\n        this.bottom = cfg.bottom;\n        this.top = cfg.top;\n        this.near = cfg.near;\n        this.far = cfg.far;\n    }\n\n    _update() {\n\n        math.frustumMat4(this._left, this._right, this._bottom, this._top, this._state.near, this._state.far, this._state.matrix);\n\n        this._inverseMatrixDirty = true;\n        this._transposedMatrixDirty = true;\n\n        this.glRedraw();\n\n        this.fire(\"matrix\", this._state.matrix);\n    }\n\n    /**\n     * Sets the position of the Frustum's left plane on the View-space X-axis.\n     *\n     * Fires a {@link Frustum#left:emits} emits on change.\n     *\n     * @param {Number} value New left frustum plane position.\n     */\n    set left(value) {\n        this._left = (value !== undefined && value !== null) ? value : -1.0;\n        this._needUpdate(0);\n        this.fire(\"left\", this._left);\n    }\n\n    /**\n     * Gets the position of the Frustum's left plane on the View-space X-axis.\n     *\n     * @return {Number} Left frustum plane position.\n     */\n    get left() {\n        return this._left;\n    }\n\n    /**\n     * Sets the position of the Frustum's right plane on the View-space X-axis.\n     *\n     * Fires a {@link Frustum#right:emits} emits on change.\n     *\n     * @param {Number} value New right frustum plane position.\n     */\n    set right(value) {\n        this._right = (value !== undefined && value !== null) ? value : 1.0;\n        this._needUpdate(0);\n        this.fire(\"right\", this._right);\n    }\n\n    /**\n     * Gets the position of the Frustum's right plane on the View-space X-axis.\n     *\n     * Fires a {@link Frustum#right:emits} emits on change.\n     *\n     * @return {Number} Right frustum plane position.\n     */\n    get right() {\n        return this._right;\n    }\n\n    /**\n     * Sets the position of the Frustum's top plane on the View-space Y-axis.\n     *\n     * Fires a {@link Frustum#top:emits} emits on change.\n     *\n     * @param {Number} value New top frustum plane position.\n     */\n    set top(value) {\n        this._top = (value !== undefined && value !== null) ? value : 1.0;\n        this._needUpdate(0);\n        this.fire(\"top\", this._top);\n    }\n\n    /**\n     * Gets the position of the Frustum's top plane on the View-space Y-axis.\n     *\n     * Fires a {@link Frustum#top:emits} emits on change.\n     *\n     * @return {Number} Top frustum plane position.\n     */\n    get top() {\n        return this._top;\n    }\n\n    /**\n     * Sets the position of the Frustum's bottom plane on the View-space Y-axis.\n     *\n     * Fires a {@link Frustum#bottom:emits} emits on change.\n     *\n     * @emits {\"bottom\"} event with the value of this property whenever it changes.\n     *\n     * @param {Number} value New bottom frustum plane position.\n     */\n    set bottom(value) {\n        this._bottom = (value !== undefined && value !== null) ? value : -1.0;\n        this._needUpdate(0);\n        this.fire(\"bottom\", this._bottom);\n    }\n\n    /**\n     * Gets the position of the Frustum's bottom plane on the View-space Y-axis.\n     *\n     * Fires a {@link Frustum#bottom:emits} emits on change.\n     *\n     * @return {Number} Bottom frustum plane position.\n     */\n    get bottom() {\n        return this._bottom;\n    }\n\n    /**\n     * Sets the position of the Frustum's near plane on the positive View-space Z-axis.\n     *\n     * Fires a {@link Frustum#near:emits} emits on change.\n     *\n     * Default value is ````0.1````.\n     *\n     * @param {Number} value New Frustum near plane position.\n     */\n    set near(value) {\n        this._state.near = (value !== undefined && value !== null) ? value : 0.1;\n        this._needUpdate(0);\n        this.fire(\"near\", this._state.near);\n    }\n\n    /**\n     * Gets the position of the Frustum's near plane on the positive View-space Z-axis.\n     *\n     * Fires a {@link Frustum#near:emits} emits on change.\n     *\n     * Default value is ````0.1````.\n     *\n     * @return {Number} Near frustum plane position.\n     */\n    get near() {\n        return this._state.near;\n    }\n\n    /**\n     * Sets the position of the Frustum's far plane on the positive View-space Z-axis.\n     *\n     * Fires a {@link Frustum#far:emits} emits on change.\n     *\n     * Default value is ````10000.0````.\n     *\n     * @param {Number} value New far frustum plane position.\n     */\n    set far(value) {\n        this._state.far = (value !== undefined && value !== null) ? value : 10000.0;\n        this._needUpdate(0);\n        this.fire(\"far\", this._state.far);\n    }\n\n    /**\n     * Gets the position of the Frustum's far plane on the positive View-space Z-axis.\n     *\n     * Default value is ````10000.0````.\n     *\n     * @return {Number} Far frustum plane position.\n     */\n    get far() {\n        return this._state.far;\n    }\n\n    /**\n     * Gets the Frustum's projection transform matrix.\n     *\n     * Fires a {@link Frustum#matrix:emits} emits on change.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @returns {Number[]} The Frustum's projection matrix matrix.\n     */\n    get matrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        return this._state.matrix;\n    }\n\n    /**\n     * Gets the inverse of {@link Frustum#matrix}.\n     *\n     * @returns {Number[]} The inverse orthographic projection matrix.\n     */\n    get inverseMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        if (this._inverseMatrixDirty) {\n            math.inverseMat4(this._state.matrix, this._state.inverseMatrix);\n            this._inverseMatrixDirty = false;\n        }\n        return this._state.inverseMatrix;\n    }\n\n    /**\n     * Gets the transpose of {@link Frustum#matrix}.\n     *\n     * @returns {Number[]} The transpose of {@link Frustum#matrix}.\n     */\n    get transposedMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        if (this._transposedMatrixDirty) {\n            math.transposeMat4(this._state.matrix, this._state.transposedMatrix);\n            this._transposedMatrixDirty = false;\n        }\n        return this._state.transposedMatrix;\n    }\n\n    /**\n     * Un-projects the given Canvas-space coordinates, using this Frustum projection.\n     *\n     * @param {Number[]} canvasPos Inputs 2D Canvas-space coordinates.\n     * @param {Number} screenZ Inputs Screen-space Z coordinate.\n     * @param {Number[]} screenPos Outputs 3D Screen/Clip-space coordinates.\n     * @param {Number[]} viewPos Outputs un-projected 3D View-space coordinates.\n     * @param {Number[]} worldPos Outputs un-projected 3D World-space coordinates.\n     */\n    unproject(canvasPos, screenZ, screenPos, viewPos, worldPos) {\n\n        const canvas = this.scene.canvas.canvas;\n\n        const halfCanvasWidth = canvas.offsetWidth / 2.0;\n        const halfCanvasHeight = canvas.offsetHeight / 2.0;\n\n        screenPos[0] = (canvasPos[0] - halfCanvasWidth) / halfCanvasWidth;\n        screenPos[1] = (canvasPos[1] - halfCanvasHeight) / halfCanvasHeight;\n        screenPos[2] = screenZ;\n        screenPos[3] = 1.0;\n\n        math.mulMat4v4(this.inverseMatrix, screenPos, viewPos);\n        math.mulVec3Scalar(viewPos, 1.0 / viewPos[3]);\n\n        viewPos[3] = 1.0;\n        viewPos[1] *= -1;\n\n        math.mulMat4v4(this.camera.inverseViewMatrix, viewPos, worldPos);\n\n        return worldPos;\n    }\n\n    /** @private\n     *\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n        super.destroy();\n    }\n}\n\n/**\n * @desc Defines a custom projection for a {@link Camera} as a custom 4x4 matrix..\n *\n * Located at {@link Camera#customProjection}.\n */\nclass CustomProjection extends Component {\n\n    /**\n     * @private\n     */\n    get type() {\n        return \"CustomProjection\";\n    }\n\n    /**\n     * @constructor\n     * @private\n     */\n    constructor(camera, cfg = {}) {\n\n        super(camera, cfg);\n\n        /**\n         * The Camera this CustomProjection belongs to.\n         *\n         * @property camera\n         * @type {Camera}\n         * @final\n         */\n        this.camera = camera;\n\n        this._state = new RenderState({\n            matrix: math.mat4(),\n            inverseMatrix: math.mat4(),\n            transposedMatrix: math.mat4()\n        });\n\n        this._inverseMatrixDirty = true;\n        this._transposedMatrixDirty = false;\n\n        this.matrix = cfg.matrix;\n    }\n\n    /**\n     * Sets the CustomProjection's projection transform matrix.\n     *\n     * Fires a \"matrix\" event on change.\n\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @param {Number[]} matrix New value for the CustomProjection's matrix.\n     */\n    set matrix(matrix) {\n        this._state.matrix.set(matrix || [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\n        this._inverseMatrixDirty = true;\n        this._transposedMatrixDirty = true;\n        this.glRedraw();\n        this.fire(\"matrix\", this._state.matrix);\n    }\n\n    /**\n     * Gets the CustomProjection's projection transform matrix.\n     *\n     * Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.\n     *\n     * @return {Number[]} New value for the CustomProjection's matrix.\n     */\n    get matrix() {\n        return this._state.matrix;\n    }\n\n    /**\n     * Gets the inverse of {@link CustomProjection#matrix}.\n     *\n     * @returns {Number[]} The inverse of {@link CustomProjection#matrix}.\n     */\n    get inverseMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        if (this._inverseMatrixDirty) {\n            math.inverseMat4(this._state.matrix, this._state.inverseMatrix);\n            this._inverseMatrixDirty = false;\n        }\n        return this._state.inverseMatrix;\n    }\n\n    /**\n     * Gets the transpose of {@link CustomProjection#matrix}.\n     *\n     * @returns {Number[]} The transpose of {@link CustomProjection#matrix}.\n     */\n    get transposedMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        if (this._transposedMatrixDirty) {\n            math.transposeMat4(this._state.matrix, this._state.transposedMatrix);\n            this._transposedMatrixDirty = false;\n        }\n        return this._state.transposedMatrix;\n    }\n\n    /**\n     * Un-projects the given Canvas-space coordinates, using this CustomProjection.\n     *\n     * @param {Number[]} canvasPos Inputs 2D Canvas-space coordinates.\n     * @param {Number} screenZ Inputs Screen-space Z coordinate.\n     * @param {Number[]} screenPos Outputs 3D Screen/Clip-space coordinates.\n     * @param {Number[]} viewPos Outputs un-projected 3D View-space coordinates.\n     * @param {Number[]} worldPos Outputs un-projected 3D World-space coordinates.\n     */\n    unproject(canvasPos, screenZ, screenPos, viewPos, worldPos) {\n\n        const canvas = this.scene.canvas.canvas;\n\n        const halfCanvasWidth = canvas.offsetWidth / 2.0;\n        const halfCanvasHeight = canvas.offsetHeight / 2.0;\n\n        screenPos[0] = (canvasPos[0] - halfCanvasWidth) / halfCanvasWidth;\n        screenPos[1] = (canvasPos[1] - halfCanvasHeight) / halfCanvasHeight;\n        screenPos[2] = screenZ;\n        screenPos[3] = 1.0;\n\n        math.mulMat4v4(this.inverseMatrix, screenPos, viewPos);\n        math.mulVec3Scalar(viewPos, 1.0 / viewPos[3]);\n\n        viewPos[3] = 1.0;\n        viewPos[1] *= -1;\n\n        math.mulMat4v4(this.camera.inverseViewMatrix, viewPos, worldPos);\n\n        return worldPos;\n    }\n\n    /** @private\n     *\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\nconst tempVec3$4 = math.vec3();\nconst tempVec3b$7 = math.vec3();\nconst tempVec3c$6 = math.vec3();\nconst tempVec3d$1 = math.vec3();\nconst tempVec3e = math.vec3();\nconst tempVec3f = math.vec3();\nconst tempVec4a$7 = math.vec4();\nconst tempVec4b$7 = math.vec4();\nconst tempVec4c$2 = math.vec4();\nconst tempMat = math.mat4();\nconst tempMatb = math.mat4();\nconst eyeLookVec = math.vec3();\nconst eyeLookVecNorm = math.vec3();\nconst eyeLookOffset = math.vec3();\nconst offsetEye = math.vec3();\n\n/**\n * @desc Manages viewing and projection transforms for its {@link Scene}.\n *\n * * One Camera per {@link Scene}\n * * Scene is located at {@link Viewer#scene} and Camera is located at {@link Scene#camera}\n * * Controls viewing and projection transforms\n * * Has methods to pan, zoom and orbit (or first-person rotation)\n * * Dynamically configurable World-space axis\n * * Has {@link Perspective}, {@link Ortho} and {@link Frustum} and {@link CustomProjection}, which you can dynamically switch it between\n * * Switchable gimbal lock\n * * Can be \"flown\" to look at targets using a {@link CameraFlightAnimation}\n * * Can be animated along a path using a {@link CameraPathAnimation}\n *\n * ## Getting the Camera\n *\n * There is exactly one Camera per {@link Scene}:\n *\n * ````javascript\n * import {Viewer} from \"xeokit-sdk.es.js\";\n *\n * var camera = viewer.scene.camera;\n *\n * ````\n *\n * ## Setting the Camera Position\n *\n * Get and set the Camera's absolute position via {@link Camera#eye}, {@link Camera#look} and {@link Camera#up}:\n *\n * ````javascript\n * camera.eye = [-10,0,0];\n * camera.look = [-10,0,0];\n * camera.up = [0,1,0];\n * ````\n *\n * ## Camera View and Projection Matrices\n *\n * The Camera's view matrix transforms coordinates from World-space to View-space.\n *\n * Getting the view matrix:\n *\n * ````javascript\n * var viewMatrix = camera.viewMatrix;\n * var viewNormalMatrix = camera.normalMatrix;\n * ````\n *\n * The Camera's view normal matrix transforms normal vectors from World-space to View-space.\n *\n * Getting the view normal matrix:\n *\n * ````javascript\n * var viewNormalMatrix = camera.normalMatrix;\n * ````\n *\n * The Camera fires a ````\"viewMatrix\"```` event whenever the {@link Camera#viewMatrix} and {@link Camera#viewNormalMatrix} updates.\n *\n * Listen for view matrix updates:\n *\n * ````javascript\n * camera.on(\"viewMatrix\", function(matrix) { ... });\n * ````\n *\n * ## Rotating the Camera\n *\n * Orbiting the {@link Camera#look} position:\n *\n * ````javascript\n * camera.orbitYaw(20.0);\n * camera.orbitPitch(10.0);\n * ````\n *\n * First-person rotation, rotates {@link Camera#look} and {@link Camera#up} about {@link Camera#eye}:\n *\n * ````javascript\n * camera.yaw(5.0);\n * camera.pitch(-10.0);\n * ````\n *\n * ## Panning the Camera\n *\n * Panning along the Camera's local axis (ie. left/right, up/down, forward/backward):\n *\n * ````javascript\n * camera.pan([-20, 0, 10]);\n * ````\n *\n * ## Zooming the Camera\n *\n * Zoom to vary distance between {@link Camera#eye} and {@link Camera#look}:\n *\n * ````javascript\n * camera.zoom(-5); // Move five units closer\n * ````\n *\n * Get the current distance between {@link Camera#eye} and {@link Camera#look}:\n *\n * ````javascript\n * var distance = camera.eyeLookDist;\n * ````\n *\n * ## Projection\n *\n * The Camera has a Component to manage each projection type, which are: {@link Perspective}, {@link Ortho}\n * and {@link Frustum} and {@link CustomProjection}.\n *\n * You can configure those components at any time, regardless of which is currently active:\n *\n * The Camera has a {@link Perspective} to manage perspective\n * ````javascript\n *\n * // Set some properties on Perspective\n * camera.perspective.near = 0.4;\n * camera.perspective.fov = 45;\n *\n * // Set some properties on Ortho\n * camera.ortho.near = 0.8;\n * camera.ortho.far = 1000;\n *\n * // Set some properties on Frustum\n * camera.frustum.left = -1.0;\n * camera.frustum.right = 1.0;\n * camera.frustum.far = 1000.0;\n *\n * // Set the matrix property on CustomProjection\n * camera.customProjection.matrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];\n *\n * // Switch between the projection types\n * camera.projection = \"perspective\"; // Switch to perspective\n * camera.projection = \"frustum\"; // Switch to frustum\n * camera.projection = \"ortho\"; // Switch to ortho\n * camera.projection = \"customProjection\"; // Switch to custom\n * ````\n *\n * Camera provides the projection matrix for the currently active projection in {@link Camera#projMatrix}.\n *\n * Get the projection matrix:\n *\n * ````javascript\n * var projMatrix = camera.projMatrix;\n * ````\n *\n * Listen for projection matrix updates:\n *\n * ````javascript\n * camera.on(\"projMatrix\", function(matrix) { ... });\n * ````\n *\n * ## Configuring World up direction\n *\n * We can dynamically configure the directions of the World-space coordinate system.\n *\n * Setting the +Y axis as World \"up\", +X as right and -Z as forwards (convention in some modeling software):\n *\n * ````javascript\n * camera.worldAxis = [\n *     1, 0, 0,    // Right\n *     0, 1, 0,    // Up\n *     0, 0,-1     // Forward\n * ];\n * ````\n *\n * Setting the +Z axis as World \"up\", +X as right and -Y as \"up\" (convention in most CAD and BIM viewers):\n *\n * ````javascript\n * camera.worldAxis = [\n *     1, 0, 0, // Right\n *     0, 0, 1, // Up\n *     0,-1, 0  // Forward\n * ];\n * ````\n *\n * The Camera has read-only convenience properties that provide each axis individually:\n *\n * ````javascript\n * var worldRight = camera.worldRight;\n * var worldForward = camera.worldForward;\n * var worldUp = camera.worldUp;\n * ````\n *\n * ### Gimbal locking\n *\n * By default, the Camera locks yaw rotation to pivot about the World-space \"up\" axis. We can dynamically lock and unlock that at any time:\n *\n * ````javascript\n * camera.gimbalLock = false; // Yaw rotation now happens about Camera's local Y-axis\n * camera.gimbalLock = true; // Yaw rotation now happens about World's \"up\" axis\n * ````\n *\n * See: <a href=\"https://en.wikipedia.org/wiki/Gimbal_lock\">https://en.wikipedia.org/wiki/Gimbal_lock</a>\n */\nclass Camera extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Camera\";\n    }\n\n    /**\n     * @constructor\n     * @private\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            offsetEyeFromLook: true, // TODO: treat as legacy and get rid of at some later point\n            deviceMatrix: math.mat4(),\n            hasDeviceMatrix: false, // True when deviceMatrix set to other than identity\n            matrix: math.mat4(),\n            normalMatrix: math.mat4(),\n            inverseMatrix: math.mat4()\n        });\n\n        this._perspective = new Perspective(this);\n        this._ortho = new Ortho(this);\n        this._frustum = new Frustum(this);\n        this._customProjection = new CustomProjection(this);\n        this._project = this._perspective;\n\n        this._eye = math.vec3([0, 0, 10.0]);\n        this._look = math.vec3([0, 0, 0]);\n        this._up = math.vec3([0, 1, 0]);\n\n        this._worldUp = math.vec3([0, 1, 0]);\n        this._worldRight = math.vec3([1, 0, 0]);\n        this._worldForward = math.vec3([0, 0, -1]);\n\n        this.deviceMatrix = cfg.deviceMatrix;\n        this.eye = cfg.eye;\n        this.look = cfg.look;\n        this.up = cfg.up;\n        this.worldAxis = cfg.worldAxis;\n        this.gimbalLock = cfg.gimbalLock;\n        this.constrainPitch = cfg.constrainPitch;\n\n        this.projection = cfg.projection;\n\n        this._perspective.on(\"matrix\", () => {\n            if (this._projectionType === \"perspective\") {\n                this.fire(\"projMatrix\", this._perspective.matrix);\n            }\n        });\n        this._ortho.on(\"matrix\", () => {\n            if (this._projectionType === \"ortho\") {\n                this.fire(\"projMatrix\", this._ortho.matrix);\n            }\n        });\n        this._frustum.on(\"matrix\", () => {\n            if (this._projectionType === \"frustum\") {\n                this.fire(\"projMatrix\", this._frustum.matrix);\n            }\n        });\n        this._customProjection.on(\"matrix\", () => {\n            if (this._projectionType === \"customProjection\") {\n                this.fire(\"projMatrix\", this._customProjection.matrix);\n            }\n        });\n    }\n\n    _update() {\n        const state = this._state;\n        // In ortho mode, build the view matrix with an eye position that's translated\n        // well back from look, so that the front sectionPlane plane doesn't unexpectedly cut\n        // the front off the view (not a problem with perspective, since objects close enough\n        // to be clipped by the front plane are usually too big to see anything of their cross-sections).\n        let eye;\n        if (this.projection === \"ortho\" && this._state.offsetEyeFromLook) {\n            math.subVec3(this._eye, this._look, eyeLookVec);\n            math.normalizeVec3(eyeLookVec, eyeLookVecNorm);\n            math.mulVec3Scalar(eyeLookVecNorm, 1000.0, eyeLookOffset);\n            math.addVec3(this._look, eyeLookOffset, offsetEye);\n            eye = offsetEye;\n        } else {\n            eye = this._eye;\n        }\n        if (state.hasDeviceMatrix) {\n            math.lookAtMat4v(eye, this._look, this._up, tempMatb);\n            math.mulMat4(state.deviceMatrix, tempMatb, state.matrix);\n            //state.matrix.set(state.deviceMatrix);\n        } else {\n            math.lookAtMat4v(eye, this._look, this._up, state.matrix);\n        }\n        math.inverseMat4(this._state.matrix, this._state.inverseMatrix);\n        math.transposeMat4(this._state.inverseMatrix, this._state.normalMatrix);\n        this.glRedraw();\n        this.fire(\"matrix\", this._state.matrix);\n        this.fire(\"viewMatrix\", this._state.matrix);\n    }\n\n    /**\n     * Rotates {@link Camera#eye} about {@link Camera#look}, around the {@link Camera#up} vector\n     *\n     * @param {Number} angleInc Angle of rotation in degrees\n     */\n    orbitYaw(angleInc) {\n        let lookEyeVec = math.subVec3(this._eye, this._look, tempVec3$4);\n        math.rotationMat4v(angleInc * 0.0174532925, this._gimbalLock ? this._worldUp : this._up, tempMat);\n        lookEyeVec = math.transformPoint3(tempMat, lookEyeVec, tempVec3b$7);\n        this.eye = math.addVec3(this._look, lookEyeVec, tempVec3c$6); // Set eye position as 'look' plus 'eye' vector\n        this.up = math.transformPoint3(tempMat, this._up, tempVec3d$1); // Rotate 'up' vector\n    }\n\n    /**\n     * Rotates {@link Camera#eye} about {@link Camera#look} around the right axis (orthogonal to {@link Camera#up} and \"look\").\n     *\n     * @param {Number} angleInc Angle of rotation in degrees\n     */\n    orbitPitch(angleInc) {\n        if (this._constrainPitch) {\n            angleInc = math.dotVec3(this._up, this._worldUp) / math.DEGTORAD;\n            if (angleInc < 1) {\n                return;\n            }\n        }\n        let eye2 = math.subVec3(this._eye, this._look, tempVec3$4);\n        const left = math.cross3Vec3(math.normalizeVec3(eye2, tempVec3b$7), math.normalizeVec3(this._up, tempVec3c$6));\n        math.rotationMat4v(angleInc * 0.0174532925, left, tempMat);\n        eye2 = math.transformPoint3(tempMat, eye2, tempVec3d$1);\n        this.up = math.transformPoint3(tempMat, this._up, tempVec3e);\n        this.eye = math.addVec3(eye2, this._look, tempVec3f);\n    }\n\n    /**\n     * Rotates {@link Camera#look} about {@link Camera#eye}, around the {@link Camera#up} vector.\n     *\n     * @param {Number} angleInc Angle of rotation in degrees\n     */\n    yaw(angleInc) {\n        let look2 = math.subVec3(this._look, this._eye, tempVec3$4);\n        math.rotationMat4v(angleInc * 0.0174532925, this._gimbalLock ? this._worldUp : this._up, tempMat);\n        look2 = math.transformPoint3(tempMat, look2, tempVec3b$7);\n        this.look = math.addVec3(look2, this._eye, tempVec3c$6);\n        if (this._gimbalLock) {\n            this.up = math.transformPoint3(tempMat, this._up, tempVec3d$1);\n        }\n    }\n\n    /**\n     * Rotates {@link Camera#look} about {@link Camera#eye}, around the right axis (orthogonal to {@link Camera#up} and \"look\").\n\n     * @param {Number} angleInc Angle of rotation in degrees\n     */\n    pitch(angleInc) {\n        if (this._constrainPitch) {\n            angleInc = math.dotVec3(this._up, this._worldUp) / math.DEGTORAD;\n            if (angleInc < 1) {\n                return;\n            }\n        }\n        let look2 = math.subVec3(this._look, this._eye, tempVec3$4);\n        const left = math.cross3Vec3(math.normalizeVec3(look2, tempVec3b$7), math.normalizeVec3(this._up, tempVec3c$6));\n        math.rotationMat4v(angleInc * 0.0174532925, left, tempMat);\n        this.up = math.transformPoint3(tempMat, this._up, tempVec3f);\n        look2 = math.transformPoint3(tempMat, look2, tempVec3d$1);\n        this.look = math.addVec3(look2, this._eye, tempVec3e);\n    }\n\n    /**\n     * Pans the Camera along its local X, Y and Z axis.\n     *\n     * @param pan The pan vector\n     */\n    pan(pan) {\n        const eye2 = math.subVec3(this._eye, this._look, tempVec3$4);\n        const vec = [0, 0, 0];\n        let v;\n        if (pan[0] !== 0) {\n            const left = math.cross3Vec3(math.normalizeVec3(eye2, []), math.normalizeVec3(this._up, tempVec3b$7));\n            v = math.mulVec3Scalar(left, pan[0]);\n            vec[0] += v[0];\n            vec[1] += v[1];\n            vec[2] += v[2];\n        }\n        if (pan[1] !== 0) {\n            v = math.mulVec3Scalar(math.normalizeVec3(this._up, tempVec3c$6), pan[1]);\n            vec[0] += v[0];\n            vec[1] += v[1];\n            vec[2] += v[2];\n        }\n        if (pan[2] !== 0) {\n            v = math.mulVec3Scalar(math.normalizeVec3(eye2, tempVec3d$1), pan[2]);\n            vec[0] += v[0];\n            vec[1] += v[1];\n            vec[2] += v[2];\n        }\n        this.eye = math.addVec3(this._eye, vec, tempVec3e);\n        this.look = math.addVec3(this._look, vec, tempVec3f);\n    }\n\n    /**\n     * Increments/decrements the Camera's zoom factor, which is the distance between {@link Camera#eye} and {@link Camera#look}.\n     *\n     * @param {Number} delta Zoom factor increment.\n     */\n    zoom(delta) {\n        const vec = math.subVec3(this._eye, this._look, tempVec3$4);\n        const lenLook = Math.abs(math.lenVec3(vec, tempVec3b$7));\n        const newLenLook = Math.abs(lenLook + delta);\n        if (newLenLook < 0.5) {\n            return;\n        }\n        const dir = math.normalizeVec3(vec, tempVec3c$6);\n        this.eye = math.addVec3(this._look, math.mulVec3Scalar(dir, newLenLook), tempVec3d$1);\n    }\n\n    /**\n     * Sets the position of the Camera's eye.\n     *\n     * Default value is ````[0,0,10]````.\n     *\n     * @emits \"eye\" event on change, with the value of this property.\n     * @type {Number[]} New eye position.\n     */\n    set eye(eye) {\n        this._eye.set(eye || [0, 0, 10]);\n        this._needUpdate(0); // Ensure matrix built on next \"tick\"\n        this.fire(\"eye\", this._eye);\n    }\n\n    /**\n     * Gets the position of the Camera's eye.\n     *\n     * Default vale is ````[0,0,10]````.\n     *\n     * @type {Number[]} New eye position.\n     */\n    get eye() {\n        return this._eye;\n    }\n\n    /**\n     * Sets the position of this Camera's point-of-interest.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @emits \"look\" event on change, with the value of this property.\n     *\n     * @param {Number[]} look Camera look position.\n     */\n    set look(look) {\n        this._look.set(look || [0, 0, 0]);\n        this._needUpdate(0); // Ensure matrix built on next \"tick\"\n        this.fire(\"look\", this._look);\n    }\n\n    /**\n     * Gets the position of this Camera's point-of-interest.\n     *\n     * Default value is ````[0,0,0]````.\n     *\n     * @returns {Number[]} Camera look position.\n     */\n    get look() {\n        return this._look;\n    }\n\n    /**\n     * Sets the direction of this Camera's {@link Camera#up} vector.\n     *\n     * @emits \"up\" event on change, with the value of this property.\n     *\n     * @param {Number[]} up Direction of \"up\".\n     */\n    set up(up) {\n        this._up.set(up || [0, 1, 0]);\n        this._needUpdate(0);\n        this.fire(\"up\", this._up);\n    }\n\n    /**\n     * Gets the direction of this Camera's {@link Camera#up} vector.\n     *\n     * @returns {Number[]} Direction of \"up\".\n     */\n    get up() {\n        return this._up;\n    }\n\n    /**\n     * Sets an optional matrix to premultiply into {@link Camera#matrix} matrix.\n     *\n     * This is intended to be used for stereo rendering with WebVR etc.\n     *\n     * @param {Number[]} matrix The matrix.\n     */\n    set deviceMatrix(matrix) {\n        this._state.deviceMatrix.set(matrix || [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\n        this._state.hasDeviceMatrix = !!matrix;\n        this._needUpdate(0);\n        this.fire(\"deviceMatrix\", this._state.deviceMatrix);\n    }\n\n    /**\n     * Gets an optional matrix to premultiply into {@link Camera#matrix} matrix.\n     *\n     * @returns {Number[]} The matrix.\n     */\n    get deviceMatrix() {\n        return this._state.deviceMatrix;\n    }\n\n    /**\n     * Sets the up, right and forward axis of the World coordinate system.\n     *\n     * Has format: ````[rightX, rightY, rightZ, upX, upY, upZ, forwardX, forwardY, forwardZ]````\n     *\n     * Default axis is ````[1, 0, 0, 0, 1, 0, 0, 0, 1]````\n     *\n     * @param {Number[]} axis The new Wworld coordinate axis.\n     */\n    set worldAxis(axis) {\n        axis = axis || [1, 0, 0, 0, 1, 0, 0, 0, 1];\n        if (!this._worldAxis) {\n            this._worldAxis = math.vec3(axis);\n        } else {\n            this._worldAxis.set(axis);\n        }\n        this._worldRight[0] = this._worldAxis[0];\n        this._worldRight[1] = this._worldAxis[1];\n        this._worldRight[2] = this._worldAxis[2];\n        this._worldUp[0] = this._worldAxis[3];\n        this._worldUp[1] = this._worldAxis[4];\n        this._worldUp[2] = this._worldAxis[5];\n        this._worldForward[0] = this._worldAxis[6];\n        this._worldForward[1] = this._worldAxis[7];\n        this._worldForward[2] = this._worldAxis[8];\n        this.fire(\"worldAxis\", this._worldAxis);\n    }\n\n    /**\n     * Gets the up, right and forward axis of the World coordinate system.\n     *\n     * Has format: ````[rightX, rightY, rightZ, upX, upY, upZ, forwardX, forwardY, forwardZ]````\n     *\n     * Default axis is ````[1, 0, 0, 0, 1, 0, 0, 0, 1]````\n     *\n     * @returns {Number[]} The current World coordinate axis.\n     */\n    get worldAxis() {\n        return this._worldAxis;\n    }\n\n    /**\n     * Gets the direction of World-space \"up\".\n     *\n     * This is set by {@link Camera#worldAxis}.\n     *\n     * Default value is ````[0,1,0]````.\n     *\n     * @returns {Number[]} The \"up\" vector.\n     */\n    get worldUp() {\n        return this._worldUp;\n    }\n\n    /**\n     * Gets if the World-space X-axis is \"up\".\n     * @returns {Boolean}\n     */\n    get xUp() {\n        return this._worldUp[0] > this._worldUp[1] && this._worldUp[0] > this._worldUp[2];\n    }\n\n    /**\n     * Gets if the World-space Y-axis is \"up\".\n     * @returns {Boolean}\n     */\n    get yUp() {\n        return this._worldUp[1] > this._worldUp[0] && this._worldUp[1] > this._worldUp[2];\n    }\n\n    /**\n     * Gets if the World-space Z-axis is \"up\".\n     * @returns {Boolean}\n     */\n    get zUp() {\n        return this._worldUp[2] > this._worldUp[0] && this._worldUp[2] > this._worldUp[1];\n    }\n\n    /**\n     * Gets the direction of World-space \"right\".\n     *\n     * This is set by {@link Camera#worldAxis}.\n     *\n     * Default value is ````[1,0,0]````.\n     *\n     * @returns {Number[]} The \"up\" vector.\n     */\n    get worldRight() {\n        return this._worldRight;\n    }\n\n    /**\n     * Gets the direction of World-space \"forwards\".\n     *\n     * This is set by {@link Camera#worldAxis}.\n     *\n     * Default value is ````[0,0,1]````.\n     *\n     * @returns {Number[]} The \"up\" vector.\n     */\n    get worldForward() {\n        return this._worldForward;\n    }\n\n    /**\n     * Sets whether to lock yaw rotation to pivot about the World-space \"up\" axis.\n     *\n     * Fires a {@link Camera#gimbalLock:event} event on change.\n     *\n     * @params {Boolean} gimbalLock Set true to lock gimbal.\n     */\n    set gimbalLock(value) {\n        this._gimbalLock = value !== false;\n        this.fire(\"gimbalLock\", this._gimbalLock);\n    }\n\n    /**\n     * Gets whether to lock yaw rotation to pivot about the World-space \"up\" axis.\n     *\n     * @returns {Boolean} Returns ````true```` if gimbal is locked.\n     */\n    get gimbalLock() {\n        return this._gimbalLock;\n    }\n\n    /**\n     * Sets whether to prevent camera from being pitched upside down.\n     *\n     * The camera is upside down when the angle between {@link Camera#up} and {@link Camera#worldUp} is less than one degree.\n     *\n     * Fires a {@link Camera#constrainPitch:event} event on change.\n     *\n     * Default value is ````false````.\n     *\n     * @param {Boolean} value Set ````true```` to contrain pitch rotation.\n     */\n    set constrainPitch(value) {\n        this._constrainPitch = !!value;\n        this.fire(\"constrainPitch\", this._constrainPitch);\n    }\n\n    /**\n     * Gets whether to prevent camera from being pitched upside down.\n     *\n     * The camera is upside down when the angle between {@link Camera#up} and {@link Camera#worldUp} is less than one degree.\n     *\n     * Default value is ````false````.\n     *\n     * @returns {Boolean} ````true```` if pitch rotation is currently constrained.\n     get constrainPitch() {\n        return this._constrainPitch;\n    }\n\n     /**\n     * Gets distance from {@link Camera#look} to {@link Camera#eye}.\n     *\n     * @returns {Number} The distance.\n     */\n    get eyeLookDist() {\n        return math.lenVec3(math.subVec3(this._look, this._eye, tempVec3$4));\n    }\n\n    /**\n     * Gets the Camera's viewing transformation matrix.\n     *\n     * Fires a {@link Camera#matrix:event} event on change.\n     *\n     * @returns {Number[]} The viewing transform matrix.\n     */\n    get matrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        return this._state.matrix;\n    }\n\n    /**\n     * Gets the Camera's viewing transformation matrix.\n     *\n     * Fires a {@link Camera#matrix:event} event on change.\n     *\n     * @returns {Number[]} The viewing transform matrix.\n     */\n    get viewMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        return this._state.matrix;\n    }\n\n    /**\n     * The Camera's viewing normal transformation matrix.\n     *\n     * Fires a {@link Camera#matrix:event} event on change.\n     *\n     * @returns {Number[]} The viewing normal transform matrix.\n     */\n    get normalMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        return this._state.normalMatrix;\n    }\n\n    /**\n     * The Camera's viewing normal transformation matrix.\n     *\n     * Fires a {@link Camera#matrix:event} event on change.\n     *\n     * @returns {Number[]} The viewing normal transform matrix.\n     */\n    get viewNormalMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        return this._state.normalMatrix;\n    }\n\n    /**\n     * Gets the inverse of the Camera's viewing transform matrix.\n     *\n     * This has the same value as {@link Camera#normalMatrix}.\n     *\n     * @returns {Number[]} The inverse viewing transform matrix.\n     */\n    get inverseViewMatrix() {\n        if (this._updateScheduled) {\n            this._doUpdate();\n        }\n        return this._state.inverseMatrix;\n    }\n\n    /**\n     * Gets the Camera's projection transformation projMatrix.\n     *\n     * Fires a {@link Camera#projMatrix:event} event on change.\n     *\n     * @returns {Number[]} The projection matrix.\n     */\n    get projMatrix() {\n        return this[this.projection].matrix;\n    }\n\n    /**\n     * Gets the Camera's perspective projection.\n     *\n     * The Camera uses this while {@link Camera#projection} equals ````perspective````.\n     *\n     * @returns {Perspective} The Perspective component.\n     */\n    get perspective() {\n        return this._perspective;\n    }\n\n    /**\n     * Gets the Camera's orthographic projection.\n     *\n     * The Camera uses this while {@link Camera#projection} equals ````ortho````.\n     *\n     * @returns {Ortho} The Ortho component.\n     */\n    get ortho() {\n        return this._ortho;\n    }\n\n    /**\n     * Gets the Camera's frustum projection.\n     *\n     * The Camera uses this while {@link Camera#projection} equals ````frustum````.\n     *\n     * @returns {Frustum} The Ortho component.\n     */\n    get frustum() {\n        return this._frustum;\n    }\n\n    /**\n     * Gets the Camera's custom projection.\n     *\n     * This is used while {@link Camera#projection} equals \"customProjection\".\n     *\n     * @returns {CustomProjection} The custom projection.\n     */\n    get customProjection() {\n        return this._customProjection;\n    }\n\n    /**\n     * Sets the active projection type.\n     *\n     * Accepted values are ````\"perspective\"````, ````\"ortho\"````, ````\"frustum\"```` and ````\"customProjection\"````.\n     *\n     * Default value is ````\"perspective\"````.\n     *\n     * @param {String} value Identifies the active projection type.\n     */\n    set projection(value) {\n        value = value || \"perspective\";\n        if (this._projectionType === value) {\n            return;\n        }\n        if (value === \"perspective\") {\n            this._project = this._perspective;\n        } else if (value === \"ortho\") {\n            this._project = this._ortho;\n        } else if (value === \"frustum\") {\n            this._project = this._frustum;\n        } else if (value === \"customProjection\") {\n            this._project = this._customProjection;\n        } else {\n            this.error(\"Unsupported value for 'projection': \" + value + \" defaulting to 'perspective'\");\n            this._project = this._perspective;\n            value = \"perspective\";\n        }\n        this._project._update();\n        this._projectionType = value;\n        this.glRedraw();\n        this._update(); // Need to rebuild lookat matrix with full eye, look & up\n        this.fire(\"dirty\");\n        this.fire(\"projection\", this._projectionType);\n        this.fire(\"projMatrix\", this._project.matrix);\n    }\n\n    /**\n     * Gets the active projection type.\n     *\n     * Possible values are ````\"perspective\"````, ````\"ortho\"````, ````\"frustum\"```` and ````\"customProjection\"````.\n     *\n     * Default value is ````\"perspective\"````.\n     *\n     * @returns {String} Identifies the active projection type.\n     */\n    get projection() {\n        return this._projectionType;\n    }\n\n    /**\n     * Gets the currently active projection for this Camera.\n     *\n     * The currently active project is selected with {@link Camera#projection}.\n     *\n     * @returns {Perspective|Ortho|Frustum|CustomProjection} The currently active projection is active.\n     */\n    get project() {\n        return this._project;\n    }\n\n    /**\n     * Gets whether to offset the ortho camera's effective eye from its look\n     *\n     * Default value for legacy reasons is ````true````.\n     */\n    get offsetEyeFromLook() {\n        return this._state.offsetEyeFromLook;\n    }\n\n    /**\n     * Offsets the ortho camera's effective eye from its look\n     *\n     * Default value for legacy reasons is ````true````.\n     */\n    set offsetEyeFromLook(v) {\n        this._state.offsetEyeFromLook = v;\n        this._needUpdate(0); // Ensure matrix built on next \"tick\"\n    }\n\n    /**\n     * Get the 2D canvas position of a 3D world position.\n     *\n     * @param {[number, number, number]} worldPos\n     * @returns {[number, number]} the canvas position\n     */\n    projectWorldPos(worldPos) {\n        const _worldPos = tempVec4a$7;\n        const viewPos = tempVec4b$7;\n        const screenPos = tempVec4c$2;\n        _worldPos[0] = worldPos[0];\n        _worldPos[1] = worldPos[1];\n        _worldPos[2] = worldPos[2];\n        _worldPos[3] = 1;\n        math.mulMat4v4(this.viewMatrix, _worldPos, viewPos);\n        math.mulMat4v4(this.projMatrix, viewPos, screenPos);\n        math.mulVec3Scalar(screenPos, 1.0 / screenPos[3]);\n        screenPos[3] = 1.0;\n        screenPos[1] *= -1;\n        const canvas = this.scene.canvas.canvas;\n        const halfCanvasWidth = canvas.offsetWidth / 2.0;\n        const halfCanvasHeight = canvas.offsetHeight / 2.0;\n        const canvasPos = [\n            screenPos[0] * halfCanvasWidth + halfCanvasWidth,\n            screenPos[1] * halfCanvasHeight + halfCanvasHeight,\n        ];\n        return canvasPos;\n    }\n\n    /**\n     * Destroys this Camera.\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\n//----------------------------------------------------------------------------------------------------------------------\n\nconst unitsInfo = {\n    meters: {\n        abbrev: \"m\"\n    },\n    metres: {\n        abbrev: \"m\"\n    },\n    centimeters: {\n        abbrev: \"cm\"\n    },\n    centimetres: {\n        abbrev: \"cm\"\n    },\n    millimeters: {\n        abbrev: \"mm\"\n    },\n    millimetres: {\n        abbrev: \"mm\"\n    },\n    yards: {\n        abbrev: \"yd\"\n    },\n    feet: {\n        abbrev: \"ft\"\n    },\n    inches: {\n        abbrev: \"in\"\n    }\n};\n\n/**\n * @desc Configures its {@link Scene}'s measurement unit and mapping between the Real-space and World-space 3D Cartesian coordinate systems.\n *\n *\n * ## Overview\n *\n * * Located at {@link Scene#metrics}.\n * * {@link Metrics#units} configures the Real-space unit type, which is ````\"meters\"```` by default.\n * * {@link Metrics#scale} configures the number of Real-space units represented by each unit within the World-space 3D coordinate system. This is ````1.0```` by default.\n * * {@link Metrics#origin} configures the 3D Real-space origin, in current Real-space units, at which this {@link Scene}'s World-space coordinate origin sits, This is ````[0,0,0]```` by default.\n *\n * ## Usage\n *\n * Let's load a model using an {@link XKTLoaderPlugin}, then configure the Real-space unit type and the coordinate\n * mapping between the Real-space and World-space 3D coordinate systems.\n *\n * ````JavaScript\n * import {Viewer, XKTLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [-2.37, 18.97, -26.12];\n * viewer.scene.camera.look = [10.97, 5.82, -11.22];\n * viewer.scene.camera.up = [0.36, 0.83, 0.40];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *     src: \"./models/xkt/duplex/duplex.xkt\"\n * });\n *\n * const metrics = viewer.scene.metrics;\n *\n * metrics.units = \"meters\";\n * metrics.scale = 10.0;\n * metrics.origin = [100.0, 0.0, 200.0];\n * ````\n */\nclass Metrics extends Component {\n\n    /**\n     * @constructor\n     * @private\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._units = \"meters\";\n        this._scale = 1.0;\n        this._origin = math.vec3([0, 0, 0]);\n\n        this.units = cfg.units;\n        this.scale = cfg.scale;\n        this.origin = cfg.origin;\n    }\n\n    /**\n     * Gets info about the supported Real-space unit types.\n     *\n     * This will be:\n     *\n     * ````javascript\n     * {\n     *      {\n     *          meters: {\n     *              abbrev: \"m\"\n     *          },\n     *          metres: {\n     *              abbrev: \"m\"\n     *          },\n     *          centimeters: {\n     *              abbrev: \"cm\"\n     *          },\n     *          centimetres: {\n     *              abbrev: \"cm\"\n     *          },\n     *          millimeters: {\n     *              abbrev: \"mm\"\n     *          },\n     *          millimetres: {\n     *              abbrev: \"mm\"\n     *          },\n     *          yards: {\n     *              abbrev: \"yd\"\n     *          },\n     *          feet: {\n     *              abbrev: \"ft\"\n     *          },\n     *          inches: {\n     *              abbrev: \"in\"\n     *          }\n     *      }\n     * }\n     * ````\n     *\n     * @type {*}\n     */\n    get unitsInfo() {\n        return unitsInfo;\n    }\n\n    /**\n     * Sets the {@link Scene}'s Real-space unit type.\n     *\n     * Accepted values are ````\"meters\"````, ````\"centimeters\"````, ````\"millimeters\"````, ````\"metres\"````, ````\"centimetres\"````, ````\"millimetres\"````, ````\"yards\"````, ````\"feet\"```` and ````\"inches\"````.\n     *\n     * @emits ````\"units\"```` event on change, with the value of this property.\n     * @type {String}\n     */\n    set units(value) {\n        if (!value) {\n            value = \"meters\";\n        }\n        const info = unitsInfo[value];\n        if (!info) {\n            this.error(\"Unsupported value for 'units': \" + value + \" defaulting to 'meters'\");\n            value = \"meters\";\n        }\n        this._units = value;\n        this.fire(\"units\", this._units);\n    }\n\n    /**\n     * Gets the {@link Scene}'s Real-space unit type.\n     *\n     * @type {String}\n     */\n    get units() {\n        return this._units;\n    }\n\n    /**\n     * Sets the number of Real-space units represented by each unit of the {@link Scene}'s World-space coordinate system.\n     *\n     * For example, if {@link Metrics#units} is ````\"meters\"````, and there are ten meters per World-space coordinate system unit, then ````scale```` would have a value of ````10.0````.\n     *\n     * @emits ````\"scale\"```` event on change, with the value of this property.\n     * @type {Number}\n     */\n    set scale(value) {\n        value = value || 1;\n        if (value <= 0) {\n            this.error(\"scale value should be larger than zero\");\n            return;\n        }\n        this._scale = value;\n        this.fire(\"scale\", this._scale);\n    }\n\n    /**\n     * Gets the number of Real-space units represented by each unit of the {@link Scene}'s World-space coordinate system.\n     *\n     * @type {Number}\n     */\n    get scale() {\n        return this._scale;\n    }\n\n    /**\n     * Sets the Real-space 3D origin, in Real-space units, at which this {@link Scene}'s World-space coordinate origin ````[0,0,0]```` sits.\n     *\n     * @emits \"origin\" event on change, with the value of this property.\n     * @type {Number[]}\n     */\n    set origin(value) {\n        if (!value) {\n            this._origin[0] = 0;\n            this._origin[1] = 0;\n            this._origin[2] = 0;\n            return;\n        }\n        this._origin[0] = value[0];\n        this._origin[1] = value[1];\n        this._origin[2] = value[2];\n        this.fire(\"origin\", this._origin);\n    }\n\n    /**\n     * Gets the 3D Real-space origin, in Real-space units, at which this {@link Scene}'s World-space coordinate origin ````[0,0,0]```` sits.\n     *\n     * @type {Number[]}\n     */\n    get origin() {\n        return this._origin;\n    }\n\n    /**\n     * Converts a 3D position from World-space to Real-space.\n     *\n     * This is equivalent to ````realPos = #origin + (worldPos * #scale)````.\n     *\n     * @param {Number[]} worldPos World-space 3D position, in World coordinate system units.\n     * @param {Number[]} [realPos] Destination for Real-space 3D position.\n     * @returns {Number[]} Real-space 3D position, in units indicated by {@link Metrics#units}.\n     */\n    worldToRealPos(worldPos, realPos = math.vec3(3)) {\n        realPos[0] = this._origin[0] + (this._scale * worldPos[0]);\n        realPos[1] = this._origin[1] + (this._scale * worldPos[1]);\n        realPos[2] = this._origin[2] + (this._scale * worldPos[2]);\n    }\n\n    /**\n     * Converts a 3D position from Real-space to World-space.\n     *\n     * This is equivalent to ````worldPos = (worldPos - #origin) / #scale````.\n     *\n     * @param {Number[]} realPos Real-space 3D position.\n     * @param {Number[]} [worldPos] Destination for World-space 3D position.\n     * @returns {Number[]} World-space 3D position.\n     */\n    realToWorldPos(realPos, worldPos = math.vec3(3)) {\n        worldPos[0] = (realPos[0] - this._origin[0]) / this._scale;\n        worldPos[1] = (realPos[1] - this._origin[1]) / this._scale;\n        worldPos[2] = (realPos[2] - this._origin[2]) / this._scale;\n        return worldPos;\n    }\n}\n\n/**\n * @desc Configures Scalable Ambient Obscurance (SAO) for a {@link Scene}.\n *\n *  <a href=\"https://xeokit.github.io/xeokit-sdk/examples/index.html#postEffects_SAO_OTCConferenceCenter\"><img src=\"http://xeokit.io/img/docs/SAO/saoEnabledDisabled.gif\"></a>\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/viewer/#sao_ConferenceCenter)]\n *\n * ## Overview\n *\n * SAO approximates [Ambient Occlusion](https://en.wikipedia.org/wiki/Ambient_occlusion) in realtime. It darkens creases, cavities and surfaces\n * that are close to each other, which tend to be occluded from ambient light and appear darker.\n *\n * The animated GIF above shows the effect as we repeatedly enable and disable SAO. When SAO is enabled, we can see darkening\n * in regions such as the corners, and the crevices between stairs. This increases the amount of detail we can see when ambient\n * light is high, or when objects have uniform colors across their surfaces. Run the example to experiment with the various\n * SAO configurations.\n *\n * xeokit's implementation of SAO is based on the paper [Scalable Ambient Obscurance](https://research.nvidia.com/sites/default/files/pubs/2012-06_Scalable-Ambient-Obscurance/McGuire12SAO.pdf).\n *\n * ## Caveats\n *\n * Currently, SAO only works with perspective and orthographic projections. Therefore, to use SAO, make sure {@link Camera#projection} is\n * either \"perspective\" or \"ortho\".\n *\n * {@link SAO#scale} and {@link SAO#intensity} must be tuned to the distance\n * between {@link Perspective#near} and {@link Perspective#far}, or the distance\n * between {@link Ortho#near} and {@link Ortho#far}, depending on which of those two projections the {@link Camera} is currently\n * using. Use the [live example](https://xeokit.github.io/xeokit-sdk/examples/viewer/#sao_ConferenceCenter) to get a\n * feel for that.\n *\n * ## Usage\n *\n * In the example below, we'll start by logging a warning message to the console if SAO is not supported by the\n * system.\n *\n *Then we'll enable and configure SAO, position the camera, and configure the near and far perspective and orthographic\n * clipping planes. Finally, we'll use {@link XKTLoaderPlugin} to load the OTC Conference Center model.\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * const sao = viewer.scene.sao;\n *\n * if (!sao.supported) {\n *     sao.warn(\"SAO is not supported on this system - ignoring SAO configs\")\n * }\n *\n * sao.enabled = true; // Enable SAO - only works if supported (see above)\n * sao.intensity = 0.15;\n * sao.bias = 0.5;\n * sao.scale = 1.0;\n * sao.minResolution = 0.0;\n * sao.numSamples = 10;\n * sao.kernelRadius = 100;\n * sao.blendCutoff = 0.1;\n *\n * const camera = viewer.scene.camera;\n *\n * camera.eye = [3.69, 5.83, -23.98];\n * camera.look = [84.31, -29.88, -116.21];\n * camera.up = [0.18, 0.96, -0.21];\n *\n * camera.perspective.near = 0.1;\n * camera.perspective.far = 2000.0;\n *\n * camera.ortho.near = 0.1;\n * camera.ortho.far = 2000.0;\n * camera.projection = \"perspective\";\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/xkt/OTCConferenceCenter.xkt\"\n *     edges: true\n * });\n * ````\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/viewer/#sao_ConferenceCenter)]\n *\n * ## Efficiency\n *\n * SAO can incur some rendering overhead, especially on objects that are viewed close to the camera. For this reason,\n * it's recommended to use a low value for {@link SAO#kernelRadius}.  A low radius will sample pixels that are close\n * to the source pixel, which will allow the GPU to efficiently cache those pixels. When {@link Camera#projection} is \"perspective\",\n * objects near to the viewpoint will use larger radii than farther pixels. Therefore, computing  SAO for close objects\n * is more expensive than for objects far away, that occupy fewer pixels on the canvas.\n *\n * ## Selectively enabling SAO for models\n *\n * When loading multiple models into a Scene, we sometimes only want SAO on the models that are actually going to\n * show it, such as the architecture or structure, and not show SAO on models that won't show it well, such as the\n * electrical wiring, or plumbing.\n *\n * To illustrate, lets load some of the models for the West Riverside Hospital. We'll enable SAO on the structure model,\n * but disable it on the electrical and plumbing.\n *\n * This will only apply SAO to those models if {@link SAO#supported} and {@link SAO#enabled} are both true.\n *\n * Note, by the way, how we load the models in sequence. Since XKTLoaderPlugin uses scratch memory as part of its loading\n * process, this allows the plugin to reuse that same memory across multiple loads, instead of having to create multiple\n * pools of scratch memory.\n *\n * ````javascript\n * const structure = xktLoader.load({\n *      id: \"structure\",\n *      src: \"./models/xkt/WestRiverSideHospital/structure.xkt\"\n *      edges: true,\n *      saoEnabled: true\n *  });\n *\n *  structure.on(\"loaded\", () => {\n *\n *      const electrical = xktLoader.load({\n *          id: \"electrical\",\n *          src: \"./models/xkt/WestRiverSideHospital/electrical.xkt\",\n *          edges: true\n *      });\n *\n *      electrical.on(\"loaded\", () => {\n *\n *          const plumbing = xktLoader.load({\n *              id: \"plumbing\",\n *              src: \"./models/xkt/WestRiverSideHospital/plumbing.xkt\",\n *              edges: true\n *          });\n *      });\n * });\n * ````\n *\n * ## Disabling SAO while camera is moving\n *\n * For smoother interaction with large models on low-power hardware, we can disable SAO while the {@link Camera} is moving:\n *\n * ````javascript\n * const timeoutDuration = 150; // Milliseconds\n * var timer = timeoutDuration;\n * var saoDisabled = false;\n *\n * const onCameraMatrix = scene.camera.on(\"matrix\", () => {\n *     timer = timeoutDuration;\n *     if (!saoDisabled) {\n *         scene.sao.enabled = false;\n *         saoDisabled = true;\n *     }\n * });\n *\n * const onSceneTick = scene.on(\"tick\", (tickEvent) => {\n *     if (!saoDisabled) {\n *         return;\n *     }\n *     timer -= tickEvent.deltaTime; // Milliseconds\n *     if (timer <= 0) {\n *         if (saoDisabled) {\n *             scene.sao.enabled = true;\n *             saoDisabled = false;\n *         }\n *     }\n * });\n * ````\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#techniques_nonInteractiveQuality)]\n */\nclass SAO extends Component {\n\n    /** @private */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._supported = WEBGL_INFO.SUPPORTED_EXTENSIONS[\"OES_standard_derivatives\"]; // For computing normals in SAO fragment shader\n\n        this.enabled = cfg.enabled;\n        this.kernelRadius = cfg.kernelRadius;\n        this.intensity = cfg.intensity;\n        this.bias = cfg.bias;\n        this.scale = cfg.scale;\n        this.minResolution = cfg.minResolution;\n        this.numSamples = cfg.numSamples;\n        this.blur = cfg.blur;\n        this.blendCutoff = cfg.blendCutoff;\n        this.blendFactor = cfg.blendFactor;\n    }\n\n    /**\n     * Gets whether or not SAO is supported by this browser and GPU.\n     *\n     * Even when enabled, SAO will only work if supported.\n     *\n     * @type {Boolean}\n     */\n    get supported() {\n        return this._supported;\n    }\n\n    /**\n     * Sets whether SAO is enabled for the {@link Scene}.\n     *\n     * Even when enabled, SAO will only work if supported.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set enabled(value) {\n        value = !!value;\n        if (this._enabled === value) {\n            return;\n        }\n        this._enabled = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether SAO is enabled for the {@link Scene}.\n     *\n     * Even when enabled, SAO will only apply if supported.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get enabled() {\n        return this._enabled;\n    }\n\n    /**\n     * Returns true if SAO is currently possible, where it is supported, enabled, and the current scene state is compatible.\n     * Called internally by renderer logic.\n     * @private\n     * @returns {Boolean}\n     */\n    get possible() {\n        if (!this._supported) {\n            return false;\n        }\n        if (!this._enabled) {\n            return false;\n        }\n        const projection = this.scene.camera.projection;\n        if (projection === \"customProjection\") {\n            return false;\n        }\n        if (projection === \"frustum\") {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * @private\n     * @returns {boolean|*}\n     */\n    get active() {\n        return this._active;\n    }\n\n    /**\n     * Sets the maximum area that SAO takes into account when checking for possible occlusion for each fragment.\n     *\n     * Default value is ````100.0````.\n     *\n     * @type {Number}\n     */\n    set kernelRadius(value) {\n        if (value === undefined || value === null) {\n            value = 100.0;\n        }\n        if (this._kernelRadius === value) {\n            return;\n        }\n        this._kernelRadius = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the maximum area that SAO takes into account when checking for possible occlusion for each fragment.\n     *\n     * Default value is ````100.0````.\n     *\n     * @type {Number}\n     */\n    get kernelRadius() {\n        return this._kernelRadius;\n    }\n\n    /**\n     * Sets the degree of darkening (ambient obscurance) produced by the SAO effect.\n     *\n     * Default value is ````0.15````.\n     *\n     * @type {Number}\n     */\n    set intensity(value) {\n        if (value === undefined || value === null) {\n            value = 0.15;\n        }\n        if (this._intensity === value) {\n            return;\n        }\n        this._intensity = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the degree of darkening (ambient obscurance) produced by the SAO effect.\n     *\n     * Default value is ````0.15````.\n     *\n     * @type {Number}\n     */\n    get intensity() {\n        return this._intensity;\n    }\n\n    /**\n     * Sets the SAO bias.\n     *\n     * Default value is ````0.5````.\n     *\n     * @type {Number}\n     */\n    set bias(value) {\n        if (value === undefined || value === null) {\n            value = 0.5;\n        }\n        if (this._bias === value) {\n            return;\n        }\n        this._bias = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the SAO bias.\n     *\n     * Default value is ````0.5````.\n     *\n     * @type {Number}\n     */\n    get bias() {\n        return this._bias;\n    }\n\n    /**\n     * Sets the SAO occlusion scale.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    set scale(value) {\n        if (value === undefined || value === null) {\n            value = 1.0;\n        }\n        if (this._scale === value) {\n            return;\n        }\n        this._scale = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the SAO occlusion scale.\n     *\n     * Default value is ````1.0````.\n     *\n     * @type {Number}\n     */\n    get scale() {\n        return this._scale;\n    }\n\n    /**\n     * Sets the SAO minimum resolution.\n     *\n     * Default value is ````0.0````.\n     *\n     * @type {Number}\n     */\n    set minResolution(value) {\n        if (value === undefined || value === null) {\n            value = 0.0;\n        }\n        if (this._minResolution === value) {\n            return;\n        }\n        this._minResolution = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the SAO minimum resolution.\n     *\n     * Default value is ````0.0````.\n     *\n     * @type {Number}\n     */\n    get minResolution() {\n        return this._minResolution;\n    }\n\n    /**\n     * Sets the number of SAO samples.\n     *\n     * Default value is ````10````.\n     *\n     * Update this sparingly, since it causes a shader recompile.\n     *\n     * @type {Number}\n     */\n    set numSamples(value) {\n        if (value === undefined || value === null) {\n            value = 10;\n        }\n        if (this._numSamples === value) {\n            return;\n        }\n        this._numSamples = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the number of SAO samples.\n     *\n     * Default value is ````10````.\n     *\n     * @type {Number}\n     */\n    get numSamples() {\n        return this._numSamples;\n    }\n\n    /**\n     * Sets whether Guassian blur is enabled.\n     *\n     * Default value is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set blur(value) {\n        value = (value !== false);\n        if (this._blur === value) {\n            return;\n        }\n        this._blur = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether Guassian blur is enabled.\n     *\n     * Default value is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get blur() {\n        return this._blur;\n    }\n\n    /**\n     * Sets the SAO blend cutoff.\n     *\n     * Default value is ````0.3````.\n     *\n     * Normally you don't need to alter this.\n     *\n     * @type {Number}\n     */\n    set blendCutoff(value) {\n        if (value === undefined || value === null) {\n            value = 0.3;\n        }\n        if (this._blendCutoff === value) {\n            return;\n        }\n        this._blendCutoff = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the SAO blend cutoff.\n     *\n     * Default value is ````0.3````.\n     *\n     * Normally you don't need to alter this.\n     *\n     * @type {Number}\n     */\n    get blendCutoff() {\n        return this._blendCutoff;\n    }\n\n    /**\n     * Sets the SAO blend factor.\n     *\n     * Default value is ````1.0````.\n     *\n     * Normally you don't need to alter this.\n     *\n     * @type {Number}\n     */\n    set blendFactor(value) {\n        if (value === undefined || value === null) {\n            value = 1.0;\n        }\n        if (this._blendFactor === value) {\n            return;\n        }\n        this._blendFactor = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the SAO blend scale.\n     *\n     * Default value is ````1.0````.\n     *\n     * Normally you don't need to alter this.\n     *\n     * @type {Number}\n     */\n    get blendFactor() {\n        return this._blendFactor;\n    }\n\n    /**\n     * Destroys this component.\n     */\n    destroy() {\n        super.destroy();\n    }\n}\n\n/**\n * @desc Configures cross-section slices for a {@link Scene}.\n *\n * ## Overview\n *\n * Cross-sections allow to create an additional colored slice for used clipping planes. It is only a visual effect\n * calculated by shaders. It makes it easier to see the intersection between the model and the clipping plane this way.\n *\n * ## Usage\n *\n * In the example below, we'll configure CrossSections to manipulate the slice representation.\n *\n * ````javascript\n * //------------------------------------------------------------------------------------------------------------------\n * // Import the modules we need for this example\n * //------------------------------------------------------------------------------------------------------------------\n *\n * import {PhongMaterial, Viewer, math, SectionPlanesPlugin, XKTLoaderPlugin, Mesh, ReadableGeometry, buildPolylineGeometryFromCurve, SplineCurve} from \"../../dist/xeokit-sdk.es.js\";\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // Create a Viewer and arrange the camera\n * //------------------------------------------------------------------------------------------------------------------\n *\n * const viewer = new Viewer({\n *   canvasId: \"myCanvas\",\n *   transparent: true\n * });\n *\n * viewer.camera.eye = [-2.341298674548419, 22.43987089731119, 7.236688436028655];\n * viewer.camera.look = [4.399999999999963, 3.7240000000000606, 8.899000000000006];\n * viewer.camera.up = [0.9102954845584759, 0.34781746407929504, 0.22446635042673466];\n *\n * const cameraControl = viewer.cameraControl;\n * cameraControl.navMode = \"orbit\";\n * cameraControl.followPointer = true;\n *\n * //----------------------------------------------------------------------------------------------------------------------\n * // Create a xeokit loader plugin, load a model, fit to view\n * //----------------------------------------------------------------------------------------------------------------------\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * var t0 = performance.now();\n *\n * document.getElementById(\"time\").innerHTML = \"Loading model...\";\n *\n * const sceneModel = xktLoader.load({\n *   id: \"myModel\",\n *   src: \"../../assets/models/xkt/v10/glTF-Embedded/Duplex_A_20110505.glTFEmbedded.xkt\",\n *   edges: true\n * });\n *\n * sceneModel.on(\"loaded\", () => {\n *   var t1 = performance.now();\n *   document.getElementById(\"time\").innerHTML = \"Model loaded in \" + Math.floor(t1 - t0) / 1000.0 + \" seconds<br>Objects: \" + sceneModel.numEntities;\n *\n *   let path = new SplineCurve(viewer.scene, {\n *     points: [\n *       [0, 0, -10],\n *       [0, 0, -3],\n *       [10, 0, 10],\n *       [10, 0, 30],\n *     ],\n *   });\n *\n *   new Mesh(viewer.scene, {\n *     geometry: new ReadableGeometry(viewer.scene, buildPolylineGeometryFromCurve({\n *       id: \"SplineCurve\",\n *       curve: path,\n *       divisions: 50,\n *     })),\n *     material: new PhongMaterial(viewer.scene, {\n *       emissive: [1, 0, 0]\n *     })\n *   });\n *\n *   //------------------------------------------------------------------------------------------------------------------\n *   // Create a moving SectionPlane, that moves through the table models\n *   //------------------------------------------------------------------------------------------------------------------\n *\n *   const sectionPlanes = new SectionPlanesPlugin(viewer, {\n *     overviewCanvasId: \"mySectionPlanesOverviewCanvas\",\n *     overviewVisible: true\n *   });\n *\n *   let currentPoint = path.getPoint(0);\n *   let currentDirection = path.getTangent(0);\n *\n *   const sectionPlane = sectionPlanes.createSectionPlane({\n *     id: \"mySectionPlane\",\n *     pos: currentPoint,\n *     dir: currentDirection\n *   });\n *\n *   sectionPlanes.showControl(sectionPlane.id);\n *\n *   //------------------------------------------------------------------------------------------------------------------\n *   // Controlling SectionPlane position and direction\n *   //------------------------------------------------------------------------------------------------------------------\n *\n *   let currentT = 0.0;\n *   document.getElementById(\"section_path\").oninput = function() {\n *     currentT = Number(document.getElementById(\"section_path\").value);\n *     currentPoint = path.getPoint(currentT);\n *     currentDirection = path.getTangent(currentT);\n *     sectionPlane.pos = currentPoint;\n *     sectionPlane.dir = currentDirection;\n *   };\n *\n *   window.viewer = viewer;\n *\n *   //------------------------------------------------------------------------------------------------------------------\n *   // Controlling CrossSections settings\n *   //------------------------------------------------------------------------------------------------------------------\n *\n *   viewer.scene.crossSections.sliceThickness = 0.05;\n *   viewer.scene.crossSections.sliceColor = [0.0, 0.0, 0.0, 1.0];\n * });\n * ````\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/slicing/#SectionPlanesPlugin_Duplex_SectionPath_CrossSections)]\n *\n */\nclass CrossSections extends Component {\n\n    /** @private */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this.sliceColor = cfg.sliceColor;\n        this.sliceThickness  = cfg.sliceThickness;\n    }\n\n    /**\n     * Sets the thickness of a slice created by a section.\n     *\n     * Default value is ````0.0````.\n     *\n     * @type {Number}\n     */\n    set sliceThickness(value) {\n        if (value === undefined || value === null) {\n            value = 0.0;\n        }\n        if (this._sliceThickness === value) {\n            return;\n        }\n        this._sliceThickness = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the thickness of a slice created by a section.\n     *\n     * Default value is ````0.0````.\n     *\n     * @type {Number}\n     */\n    get sliceThickness() {\n        return this._sliceThickness;\n    }\n\n    /**\n     * Sets the color of a slice created by a section.\n     *\n     * Default value is ````[0.0, 0.0, 0.0, 1.0]````.\n     *\n     * @type {Number}\n     */\n    set sliceColor(value) {\n        if (value === undefined || value === null) {\n            value = [0.0, 0.0, 0.0, 1.0];\n        }\n        if (this._sliceColor === value) {\n            return;\n        }\n        this._sliceColor = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the color of a slice created by a section.\n     *\n     * Default value is ````[0.0, 0.0, 0.0, 1.0]````.\n     *\n     * @type {Number}\n     */\n    get sliceColor() {\n        return this._sliceColor;\n    }\n\n    /**\n     * Destroys this component.\n     */\n    destroy() {\n        super.destroy();\n    }\n}\n\nconst PRESETS$1 = {\n    \"default\": {\n        pointSize: 4,\n        roundPoints: true,\n        perspectivePoints: true\n    },\n    \"square\": {\n        pointSize: 4,\n        roundPoints: false,\n        perspectivePoints: true\n    },\n    \"round\": {\n        pointSize: 4,\n        roundPoints: true,\n        perspectivePoints: true\n    }\n};\n\n/**\n * @desc Configures the size and shape of \"points\" geometry primitives.\n *\n * * Located at {@link Scene#pointsMaterial}.\n * * Supports round and square points.\n * * Optional perspective point scaling.\n * * Globally configures \"points\" primitives for all {@link VBOSceneModel}s.\n *\n * ## Usage\n *\n * In the example below, we'll customize the {@link Scene}'s global ````PointsMaterial````, then use\n * an {@link XKTLoaderPlugin} to load a model containing a point cloud.\n *\n * [[Run this example](/examples/index.html#materials_PointsMaterial)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * viewer.scene.pointsMaterial.pointSize = 2;\n * viewer.scene.pointsMaterial.roundPoints = true;\n * viewer.scene.pointsMaterial.perspectivePoints = true;\n * viewer.scene.pointsMaterial.minPerspectivePointSize = 1;\n * viewer.scene.pointsMaterial.maxPerspectivePointSize = 6;\n * viewer.scene.pointsMaterial.filterIntensity = true;\n * viewer.scene.pointsMaterial.minIntensity = 0.0;\n * viewer.scene.pointsMaterial.maxIntensity = 1.0;\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *      id: \"myModel\",\n *      src: \"../assets/models/xkt/MAP-PointCloud.xkt\"\n * });\n * ````\n */\nclass PointsMaterial extends Material {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"PointsMaterial\";\n    }\n\n    /**\n     * Gets available PointsMaterial presets.\n     *\n     * @type {Object}\n     */\n    get presets() {\n        return PRESETS$1;\n    };\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] The PointsMaterial configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number} [cfg.pointSize=2] Point size in pixels.\n     * @param {Boolean} [cfg.roundPoints=true] Whether points are round (````true````) or square (````false````).\n     * @param {Boolean} [cfg.perspectivePoints=true] Whether apparent point size reduces with distance when {@link Camera#projection} is set to \"perspective\".\n     * @param {Number} [cfg.minPerspectivePointSize=1] When ````perspectivePoints```` is ````true````, this is the minimum rendered size of each point in pixels.\n     * @param {Number} [cfg.maxPerspectivePointSize=6] When ````perspectivePoints```` is ````true````, this is the maximum rendered size of each point in pixels.\n     * @param {Boolean} [cfg.filterIntensity=false] When this is true, points are only rendered when their intensity value falls within the range given in {@link }\n     * @param {Number} [cfg.minIntensity=0] When ````filterIntensity```` is ````true````, points with intensity below this value will not be rendered.\n     * @param {Number} [cfg.maxIntensity=1] When ````filterIntensity```` is ````true````, points with intensity above this value will not be rendered.\n     * @param {String} [cfg.preset] Selects a preset PointsMaterial configuration - see {@link PointsMaterial#presets}.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            type: \"PointsMaterial\",\n            pointSize: null,\n            roundPoints: null,\n            perspectivePoints: null,\n            minPerspectivePointSize: null,\n            maxPerspectivePointSize: null,\n            filterIntensity: null,\n            minIntensity: null,\n            maxIntensity: null\n        });\n\n        if (cfg.preset) { // Apply preset then override with configs where provided\n            this.preset = cfg.preset;\n            if (cfg.pointSize !== undefined) {\n                this.pointSize = cfg.pointSize;\n            }\n            if (cfg.roundPoints !== undefined) {\n                this.roundPoints = cfg.roundPoints;\n            }\n            if (cfg.perspectivePoints !== undefined) {\n                this.perspectivePoints = cfg.perspectivePoints;\n            }\n            if (cfg.minPerspectivePointSize !== undefined) {\n                this.minPerspectivePointSize = cfg.minPerspectivePointSize;\n            }\n            if (cfg.maxPerspectivePointSize !== undefined) {\n                this.maxPerspectivePointSize = cfg.minPerspectivePointSize;\n            }\n        } else {\n            this._preset = \"default\";\n            this.pointSize = cfg.pointSize;\n            this.roundPoints = cfg.roundPoints;\n\n            this.perspectivePoints = cfg.perspectivePoints;\n            this.minPerspectivePointSize = cfg.minPerspectivePointSize;\n            this.maxPerspectivePointSize = cfg.maxPerspectivePointSize;\n        }\n\n        this.filterIntensity = cfg.filterIntensity;\n        this.minIntensity = cfg.minIntensity;\n        this.maxIntensity = cfg.maxIntensity;\n    }\n\n    /**\n     * Sets point size.\n     *\n     * Default value is ````2.0```` pixels.\n     *\n     * @type {Number}\n     */\n    set pointSize(value) {\n        this._state.pointSize = value || 2.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets point size.\n     *\n     * Default value is ````2.0```` pixels.\n     *\n     * @type {Number}\n     */\n    get pointSize() {\n        return this._state.pointSize;\n    }\n\n\n    /**\n     * Sets if points are round or square.\n     *\n     * Default is ````true```` to set points round.\n     *\n     * @type {Boolean}\n     */\n    set roundPoints(value) {\n        value = (value !== false);\n        if (this._state.roundPoints === value) {\n            return;\n        }\n        this._state.roundPoints = value;\n        this.scene._needRecompile = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if points are round or square.\n     *\n     * Default is ````true```` to set points round.\n     *\n     * @type {Boolean}\n     */\n    get roundPoints() {\n        return this._state.roundPoints;\n    }\n\n    /**\n     * Sets if rendered point size reduces with distance when {@link Camera#projection} is set to ````\"perspective\"````.\n     *\n     * Default is ````true````.\n     *\n     * @type {Boolean}\n     */\n    set perspectivePoints(value) {\n        value = (value !== false);\n        if (this._state.perspectivePoints === value) {\n            return;\n        }\n        this._state.perspectivePoints = value;\n        this.scene._needRecompile = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if rendered point size reduces with distance when {@link Camera#projection} is set to \"perspective\".\n     *\n     * Default is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get perspectivePoints() {\n        return this._state.perspectivePoints;\n    }\n\n    /**\n     * Sets the minimum rendered size of points when {@link PointsMaterial#perspectivePoints} is ````true````.\n     *\n     * Default value is ````1.0```` pixels.\n     *\n     * @type {Number}\n     */\n    set minPerspectivePointSize(value) {\n        this._state.minPerspectivePointSize = value || 1.0;\n        this.scene._needRecompile = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the minimum rendered size of points when {@link PointsMaterial#perspectivePoints} is ````true````.\n     *\n     * Default value is ````1.0```` pixels.\n     *\n     * @type {Number}\n     */\n    get minPerspectivePointSize() {\n        return this._state.minPerspectivePointSize;\n    }\n\n    /**\n     * Sets the maximum rendered size of points when {@link PointsMaterial#perspectivePoints} is ````true````.\n     *\n     * Default value is ````6```` pixels.\n     *\n     * @type {Number}\n     */\n    set maxPerspectivePointSize(value) {\n        this._state.maxPerspectivePointSize = value || 6;\n        this.scene._needRecompile = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the maximum rendered size of points when {@link PointsMaterial#perspectivePoints} is ````true````.\n     *\n     * Default value is ````6```` pixels.\n     *\n     * @type {Number}\n     */\n    get maxPerspectivePointSize() {\n        return this._state.maxPerspectivePointSize;\n    }\n\n    /**\n     * Sets if rendered point size reduces with distance when {@link Camera#projection} is set to ````\"perspective\"````.\n     *\n     * Default is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set filterIntensity(value) {\n        value = (value !== false);\n        if (this._state.filterIntensity === value) {\n            return;\n        }\n        this._state.filterIntensity = value;\n        this.scene._needRecompile = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets if rendered point size reduces with distance when {@link Camera#projection} is set to \"perspective\".\n     *\n     * Default is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get filterIntensity() {\n        return this._state.filterIntensity;\n    }\n\n    /**\n     * Sets the minimum rendered size of points when {@link PointsMaterial#perspectivePoints} is ````true````.\n     *\n     * Default value is ````0````.\n     *\n     * @type {Number}\n     */\n    set minIntensity(value) {\n        this._state.minIntensity = (value !== undefined && value !== null) ? value: 0.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the minimum rendered size of points when {@link PointsMaterial#filterIntensity} is ````true````.\n     *\n     * Default value is ````0````.\n     *\n     * @type {Number}\n     */\n    get minIntensity() {\n        return this._state.minIntensity;\n    }\n\n    /**\n     * Sets the maximum rendered size of points when {@link PointsMaterial#filterIntensity} is ````true````.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    set maxIntensity(value) {\n        this._state.maxIntensity = (value !== undefined && value !== null) ? value: 1.0;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the maximum rendered size of points when {@link PointsMaterial#filterIntensity} is ````true````.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    get maxIntensity() {\n        return this._state.maxIntensity;\n    }\n\n    /**\n     * Selects a preset ````PointsMaterial```` configuration.\n     *\n     * Default value is ````\"default\"````.\n     *\n     * @type {String}\n     */\n    set preset(value) {\n        value = value || \"default\";\n        if (this._preset === value) {\n            return;\n        }\n        const preset = PRESETS$1[value];\n        if (!preset) {\n            this.error(\"unsupported preset: '\" + value + \"' - supported values are \" + Object.keys(PRESETS$1).join(\", \"));\n            return;\n        }\n        this.pointSize = preset.pointSize;\n        this.roundPoints = preset.roundPoints;\n        this.perspectivePoints = preset.perspectivePoints;\n        this.minPerspectivePointSize = preset.minPerspectivePointSize;\n        this.maxPerspectivePointSize = preset.maxPerspectivePointSize;\n        this._preset = value;\n    }\n\n    /**\n     * The current preset ````PointsMaterial```` configuration.\n     *\n     * Default value is ````\"default\"````.\n     *\n     * @type {String}\n     */\n    get preset() {\n        return this._preset;\n    }\n\n    /**\n     * @private\n     * @return {string}\n     */\n    get hash() {\n        return [\n            this.pointSize,\n            this.roundPoints,\n            this.perspectivePoints,\n            this.minPerspectivePointSize,\n            this.maxPerspectivePointSize,\n            this.filterIntensity\n        ].join((\";\"));\n    }\n\n    /**\n     * Destroys this ````PointsMaterial````.\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\nconst PRESETS = {\n    \"default\": {\n        lineWidth: 1\n    },\n    \"thick\": {\n        lineWidth: 2\n    },\n    \"thicker\": {\n        lineWidth: 4\n    }\n};\n\n/**\n * @desc Configures the shape of \"lines\" geometry primitives.\n *\n * * Located at {@link Scene#linesMaterial}.\n * * Globally configures \"lines\" primitives for all {@link VBOSceneModel}s.\n *\n * ## Usage\n *\n * In the example below, we'll customize the {@link Scene}'s global ````LinesMaterial````, then use\n * an {@link XKTLoaderPlugin} to load a model containing line segments.\n *\n * [[Run this example](/examples/index.html#materials_LinesMaterial)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [0, 0, 5];\n * viewer.scene.camera.look = [0, 0, 0];\n * viewer.scene.camera.up = [0, 1, 0];\n *\n * viewer.scene.linesMaterial.lineWidth = 3;\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *      id: \"myModel\",\n *      src: \"./models/xkt/Duplex.ifc.xkt\"\n * });\n * ````\n */\nclass LinesMaterial extends Material {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"LinesMaterial\";\n    }\n\n    /**\n     * Gets available LinesMaterial presets.\n     *\n     * @type {Object}\n     */\n    get presets() {\n        return PRESETS;\n    };\n\n    /**\n     * @constructor\n     * @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.\n     * @param {*} [cfg] The LinesMaterial configuration\n     * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.\n     * @param {Number} [cfg.lineWidth=1] Line width in pixels.\n     * @param {String} [cfg.preset] Selects a preset LinesMaterial configuration - see {@link LinesMaterial#presets}.\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        this._state = new RenderState({\n            type: \"LinesMaterial\",\n            lineWidth: null\n        });\n\n        if (cfg.preset) { // Apply preset then override with configs where provided\n            this.preset = cfg.preset;\n            if (cfg.lineWidth !== undefined) {\n                this.lineWidth = cfg.lineWidth;\n            }\n        } else {\n            this._preset = \"default\";\n            this.lineWidth = cfg.lineWidth;\n        }\n    }\n\n    /**\n     * Sets line width.\n     *\n     * Default value is ````1```` pixels.\n     *\n     * @type {Number}\n     */\n    set lineWidth(value) {\n        this._state.lineWidth = value || 1;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the line width.\n     *\n     * Default value is ````1```` pixels.\n     *\n     * @type {Number}\n     */\n    get lineWidth() {\n        return this._state.lineWidth;\n    }\n\n    /**\n     * Selects a preset LinesMaterial configuration.\n     *\n     * Default value is ````\"default\"````.\n     *\n     * @type {String}\n     */\n    set preset(value) {\n        value = value || \"default\";\n        if (this._preset === value) {\n            return;\n        }\n        const preset = PRESETS[value];\n        if (!preset) {\n            this.error(\"unsupported preset: '\" + value + \"' - supported values are \" + Object.keys(PRESETS).join(\", \"));\n            return;\n        }\n        this.lineWidth = preset.lineWidth;\n        this._preset = value;\n    }\n\n    /**\n     * The current preset LinesMaterial configuration.\n     *\n     * Default value is ````\"default\"````.\n     *\n     * @type {String}\n     */\n    get preset() {\n        return this._preset;\n    }\n\n    /**\n     * @private\n     * @return {string}\n     */\n    get hash() {\n        return [\"\" + this.lineWidth].join((\";\"));\n    }\n\n    /**\n     * Destroys this LinesMaterial.\n     */\n    destroy() {\n        super.destroy();\n        this._state.destroy();\n    }\n}\n\nconst tempVec3a$a = math.vec3();\n\n/**\n * @desc Implements hatching for Solid objects on a {@link Scene}.\n * \n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/slicing/SectionPlanesPlugin_Duplex_SectionCaps.html)]\n * \n * ##Overview\n * \n * The WebGL implementation for capping sliced 3D objects works by first calculating intersection segments where a cutting \n * plane meets the object's edges. These segments form a contour that is triangulated using the Earcut algorithm, which \n * handles any internal holes efficiently. The resulting triangulated cap is then integrated into the original mesh with \n * appropriate normals and UVs.\n * \n * ##Usage\n * \n * In the example, we'll start by enabling readable geometry on the viewer.\n * \n * Then we'll position the camera, and configure the near and far perspective and orthographic\n * clipping planes. Finally, we'll use {@link XKTLoaderPlugin} to load the Duplex model.\n * \n * ````javascript\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true,\n *     readableGeometryEnabled: true\n * });\n * \n * viewer.camera.eye = [-2.341298674548419, 22.43987089731119, 7.236688436028655];\n * viewer.camera.look = [4.399999999999963, 3.7240000000000606, 8.899000000000006];\n * viewer.camera.up = [0.9102954845584759, 0.34781746407929504, 0.22446635042673466];\n * \n * const cameraControl = viewer.cameraControl;\n * cameraControl.navMode = \"orbit\";\n * cameraControl.followPointer = true;\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n * \n * var t0 = performance.now();\n * \n * document.getElementById(\"time\").innerHTML = \"Loading model...\";\n * \n * const sceneModel = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"../../assets/models/xkt/v10/glTF-Embedded/Duplex_A_20110505.glTFEmbedded.xkt\",\n *     edges: true\n * });\n * \n * sceneModel.on(\"loaded\", () => {\n * \n *     var t1 = performance.now();\n *     document.getElementById(\"time\").innerHTML = \"Model loaded in \" + Math.floor(t1 - t0) / 1000.0 + \" seconds<br>Objects: \" + sceneModel.numEntities;\n * \n *     //------------------------------------------------------------------------------------------------------------------\n *     // Add caps materials to all objects inside the loaded model that have an opacity equal to or above 0.7\n *     //------------------------------------------------------------------------------------------------------------------        \n *     const opacityThreshold = 0.7;\n *     const material = new PhongMaterial(viewer.scene,{\n *         diffuse: [1.0, 0.0, 0.0],\n *         backfaces: true\n *     });\n *     addCapsMaterialsToAllObjects(sceneModel, opacityThreshold, material);\n * \n *     //------------------------------------------------------------------------------------------------------------------\n *     // Create a moving SectionPlane, that moves through the table models\n *     //------------------------------------------------------------------------------------------------------------------\n * \n *     const sectionPlanes = new SectionPlanesPlugin(viewer, {\n *         overviewCanvasId: \"mySectionPlanesOverviewCanvas\",\n *         overviewVisible: true,\n *     });\n * \n *     const sectionPlane = sectionPlanes.createSectionPlane({\n *         id: \"mySectionPlane\",\n *         pos: [0.5, 2.5, 5.0],\n *         dir: math.normalizeVec3([1.0, 0.01, 1])\n *     });\n * \n *     sectionPlanes.showControl(sectionPlane.id);\n * \n *     window.viewer = viewer;\n * \n * });\n * \n * function addCapsMaterialsToAllObjects(sceneModel, opacityThreshold, material) {\n *     const allObjects = sceneModel.objects;\n *     for(const key in allObjects){\n *         const object = allObjects[key];\n *         if(object.opacity >= opacityThreshold)\n *             object.capMaterial = material;\n *     }\n * }\n * ````\n */\n\nclass SectionCaps {\n    /**\n     * @constructor\n     */\n    constructor(scene) {\n        let destroy = null;\n        const modelCaches = { };\n        const sectionPlanes = [ ];\n\n        this.destroy = () => destroy && destroy();\n\n        let updateTimeout = null;\n\n        const update = () => {\n            clearTimeout(updateTimeout);\n            updateTimeout = setTimeout(() => {\n                const visibleSceneModels = Object.values(scene.models).filter(sceneModel => (sceneModel.id in modelCaches) && sceneModel.visible);\n                sectionPlanes.forEach((plane) => {\n                    if (plane.active) {\n                        const sliceMesh = math.makeSectionPlaneSlicer(plane);\n                        visibleSceneModels.forEach(sceneModel => {\n                            const modelAABB = sceneModel.aabb;\n                            if (math.planeIntersectsAABB3(plane, modelAABB)) {\n                                // modelCenter is critical to use when handling models with large coordinates.\n                                // See XCD-306 and examples/slicing/SectionCaps_at_distance.html for more details.\n                                const modelCenter = math.getAABB3Center(modelAABB, math.vec3());\n\n                                modelCaches[sceneModel.id].entityCaches.forEach((entityCache, entityId) => {\n                                    const entity = sceneModel.objects[entityId];\n                                    if (entityCache.generateCaps && entity.capMaterial && math.planeIntersectsAABB3(plane, entity.aabb)) {\n                                        entityCache.meshCaches ||= entity.meshes.filter(mesh => mesh.isSolid()).map(mesh => {\n                                            const meshIndices  = [ ];\n                                            const meshVertices = [ ];\n                                            mesh.getEachIndex(i  => meshIndices.push(i));\n                                            mesh.getEachVertex(v => meshVertices.push(...math.subVec3(v, modelCenter, tempVec3a$a)));\n                                            return { mesh: mesh, meshIndices: meshIndices, meshVertices: meshVertices };\n                                        });\n\n                                        entityCache.meshCaches.filter(meshCache => math.planeIntersectsAABB3(plane, meshCache.mesh.aabb)).forEach((meshCache, meshIdx) => {\n                                            const geo = sliceMesh({ origin: modelCenter, indices: meshCache.meshIndices, positions: meshCache.meshVertices }, { onlyPosSliceWithUV: true }).pos;\n                                            if (geo) {\n                                                entityCache.capMeshes.push(new Mesh(scene, {\n                                                    isObject: true,\n                                                    id:       `${plane.id}-${entityId}-${meshIdx}`,\n                                                    material: entity.capMaterial,\n                                                    origin:   math.addVec3(modelCenter, math.mulVec3Scalar(plane.dir, 0.001, tempVec3a$a), tempVec3a$a),\n                                                    geometry: new ReadableGeometry(scene, {\n                                                        primitive: \"triangles\",\n                                                        indices:   geo.indices,\n                                                        positions: geo.positions,\n                                                        normals:   geo.normals,\n                                                        uv:        geo.uv\n                                                    })\n                                                }));\n                                            }\n                                        });\n                                    }\n                                });\n                            }\n                        });\n                    }\n                });\n                visibleSceneModels.forEach(sceneModel => modelCaches[sceneModel.id].entityCaches.forEach(entityCache => entityCache.generateCaps = false));\n            }, 100);\n        };\n\n        this._onCapMaterialUpdated = (entity) => {\n            if (! destroy) {\n                updateTimeout = null;\n\n                const handleSectionPlane = (sectionPlane) => {\n                    const onSectionPlaneUpdated = () => {\n                        Object.values(modelCaches).forEach(modelCache => modelCache.entityCaches.forEach(entityCache => {\n                            entityCache.destroyCaps();\n                            entityCache.generateCaps = true;\n                        }));\n                        update();\n                    };\n                    sectionPlanes.push(sectionPlane);\n                    sectionPlane.on('pos',    onSectionPlaneUpdated);\n                    sectionPlane.on('dir',    onSectionPlaneUpdated);\n                    sectionPlane.on('active', onSectionPlaneUpdated);\n                    sectionPlane.once('destroyed', () => {\n                        const idx = sectionPlanes.indexOf(sectionPlane);\n                        if (idx >= 0) {\n                            sectionPlanes.splice(idx, 1);\n                            onSectionPlaneUpdated();\n                        }\n                    });\n                };\n\n                for (const key in scene.sectionPlanes){\n                    handleSectionPlane(scene.sectionPlanes[key]);\n                }\n\n                const onSectionPlaneCreated = scene.on('sectionPlaneCreated', handleSectionPlane);\n\n                const onTick = scene.on(\"tick\", () => {\n                    //on ticks we only check if there is a model that we have saved vertices for,\n                    //but it's no more available on the scene, or if its visibility changed\n                    let doUpdate = false;\n                    for (const sceneModelId in modelCaches) {\n                        const sceneModel = scene.models[sceneModelId];\n                        if (! sceneModel) {\n                            modelCaches[sceneModelId].entityCaches.forEach(entityCache => entityCache.destroyCaps());\n                            delete modelCaches[sceneModelId];\n                            doUpdate = true;\n                        } else if (modelCaches[sceneModelId].modelVisible != sceneModel.visible) {\n                            const modelCache = modelCaches[sceneModelId];\n                            modelCache.modelVisible = !!sceneModel.visible;\n                            modelCache.entityCaches.forEach(entityCache => {\n                                entityCache.destroyCaps();\n                                entityCache.generateCaps = true;\n                            });\n                            doUpdate = true;\n                        }\n                    }\n                    if (doUpdate) {\n                        update();\n                    }\n                });\n                destroy = () => {\n                    for (const sceneModelId in modelCaches) {\n                        modelCaches[sceneModelId].entityCaches.forEach(entityCache => entityCache.destroyCaps());\n                    }\n                    scene.off(onSectionPlaneCreated);\n                    scene.off(onTick);\n                };\n            }\n\n            const model = entity.model;\n            const modelId = model.id;\n            modelCaches[modelId] ||= { modelVisible: model.visible, entityCaches: new Map() };\n            const entityCaches = modelCaches[modelId].entityCaches;\n            const entityId = entity.id;\n            if (! entityCaches.has(entityId)) {\n                const entityCache = {\n                    capMeshes: [ ],\n                    meshCaches: null,\n                    generateCaps: false,\n                    destroyCaps: () => {\n                        entityCache.capMeshes.forEach(capMesh => capMesh.destroy());\n                        entityCache.capMeshes.length = 0;\n                    }\n                };\n                entityCaches.set(entityId, entityCache);\n            }\n            const entityCache = entityCaches.get(entityId);\n            entityCache.destroyCaps();\n            entityCache.generateCaps = true;\n            update();\n        };\n    }\n}\n\n// Cached vars to avoid garbage collection\n\nfunction getEntityIDMap(scene, entityIds) {\n    const map = {};\n    let entityId;\n    let entity;\n    for (let i = 0, len = entityIds.length; i < len; i++) {\n        entityId = entityIds[i];\n        entity = scene.components[entityId];\n        if (!entity) {\n            scene.warn(\"pick(): Component not found: \" + entityId);\n            continue;\n        }\n        if (!entity.isEntity) {\n            scene.warn(\"pick(): Component is not an Entity: \" + entityId);\n            continue;\n        }\n        map[entityId] = true;\n    }\n    return map;\n}\n\n/**\n * Fired whenever a debug message is logged on a component within this Scene.\n * @event log\n * @param {String} value The debug message\n */\n\n/**\n * Fired whenever an error is logged on a component within this Scene.\n * @event error\n * @param {String} value The error message\n */\n\n/**\n * Fired whenever a warning is logged on a component within this Scene.\n * @event warn\n * @param {String} value The warning message\n */\n\n/**\n * @desc Contains the components that comprise a 3D scene.\n *\n * * A {@link Viewer} has a single Scene, which it provides in {@link Viewer#scene}.\n * * Plugins like {@link AxisGizmoPlugin} also have their own private Scenes.\n * * Each Scene has a corresponding {@link MetaScene}, which the Viewer provides in {@link Viewer#metaScene}.\n *\n * ## Getting a Viewer's Scene\n *\n * ````javascript\n * var scene = viewer.scene;\n * ````\n *\n * ## Creating and accessing Scene components\n *\n * As a brief introduction to creating Scene components, we'll create a {@link Mesh} that has a\n * {@link buildTorusGeometry} and a {@link PhongMaterial}:\n *\n * ````javascript\n * var teapotMesh = new Mesh(scene, {\n *     id: \"myMesh\",                               // <<---------- ID automatically generated if not provided\n *     geometry: new TorusGeometry(scene),\n *     material: new PhongMaterial(scene, {\n *         id: \"myMaterial\",\n *         diffuse: [0.2, 0.2, 1.0]\n *     })\n * });\n *\n * teapotMesh.scene.camera.eye = [45, 45, 45];\n * ````\n *\n * Find components by ID in their Scene's {@link Scene#components} map:\n *\n * ````javascript\n * var teapotMesh = scene.components[\"myMesh\"];\n * teapotMesh.visible = false;\n *\n * var teapotMaterial = scene.components[\"myMaterial\"];\n * teapotMaterial.diffuse = [1,0,0]; // Change to red\n * ````\n *\n * A Scene also has a map of component instances for each {@link Component} subtype:\n *\n * ````javascript\n * var meshes = scene.types[\"Mesh\"];\n * var teapotMesh = meshes[\"myMesh\"];\n * teapotMesh.xrayed = true;\n *\n * var phongMaterials = scene.types[\"PhongMaterial\"];\n * var teapotMaterial = phongMaterials[\"myMaterial\"];\n * teapotMaterial.diffuse = [0,1,0]; // Change to green\n * ````\n *\n * See {@link Node}, {@link Node} and {@link Model} for how to create and access more sophisticated content.\n *\n * ## Controlling the camera\n *\n * Use the Scene's {@link Camera} to control the current viewpoint and projection:\n *\n * ````javascript\n * var camera = myScene.camera;\n *\n * camera.eye = [-10,0,0];\n * camera.look = [-10,0,0];\n * camera.up = [0,1,0];\n *\n * camera.projection = \"perspective\";\n * camera.perspective.fov = 45;\n * //...\n * ````\n *\n * ## Managing the canvas\n *\n * The Scene's {@link Canvas} component provides various conveniences relevant to the WebGL canvas, such\n * as firing resize events etc:\n *\n * ````javascript\n * var canvas = scene.canvas;\n *\n * canvas.on(\"boundary\", function(boundary) {\n *     //...\n * });\n * ````\n *\n * ## Picking\n *\n * Use {@link Scene#pick} to pick and raycast entites.\n *\n * For example, to pick a point on the surface of the closest entity at the given canvas coordinates:\n *\n * ````javascript\n * var pickResult = scene.pick({\n *      pickSurface: true,\n *      canvasPos: [23, 131]\n * });\n *\n * if (pickResult) { // Picked an entity\n *\n *     var entity = pickResult.entity;\n *\n *     var primitive = pickResult.primitive; // Type of primitive that was picked, usually \"triangles\"\n *     var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Mesh's Geometry's indices array\n *     var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\n *     var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\n *     var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\n *     var viewPos = pickResult.viewPos; // Float64Array containing the picked View-space position on the triangle\n *     var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\n *     var normal = pickResult.normal; // Float64Array containing the interpolated normal vector at the picked position on the triangle\n *     var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\n * }\n * ````\n *\n * ## Pick masking\n *\n * We can use {@link Scene#pick}'s ````includeEntities```` and ````excludeEntities````  options to mask which {@link Mesh}es we attempt to pick.\n *\n * This is useful for picking through things, to pick only the Entities of interest.\n *\n * To pick only Entities ````\"gearbox#77.0\"```` and ````\"gearbox#79.0\"````, picking through any other Entities that are\n * in the way, as if they weren't there:\n *\n * ````javascript\n * var pickResult = scene.pick({\n *      canvasPos: [23, 131],\n *      includeEntities: [\"gearbox#77.0\", \"gearbox#79.0\"]\n * });\n *\n * if (pickResult) {\n *       // Entity will always be either \"gearbox#77.0\" or \"gearbox#79.0\"\n *       var entity = pickResult.entity;\n * }\n * ````\n *\n * To pick any pickable Entity, except for ````\"gearbox#77.0\"```` and ````\"gearbox#79.0\"````, picking through those\n * Entities if they happen to be in the way:\n *\n * ````javascript\n * var pickResult = scene.pick({\n *      canvasPos: [23, 131],\n *      excludeEntities: [\"gearbox#77.0\", \"gearbox#79.0\"]\n * });\n *\n * if (pickResult) {\n *       // Entity will never be \"gearbox#77.0\" or \"gearbox#79.0\"\n *       var entity = pickResult.entity;\n * }\n * ````\n *\n * See {@link Scene#pick} for more info on picking.\n *\n * ## Querying and tracking boundaries\n *\n * Getting a Scene's World-space axis-aligned boundary (AABB):\n *\n * ````javascript\n * var aabb = scene.aabb; // [xmin, ymin, zmin, xmax, ymax, zmax]\n * ````\n *\n * Subscribing to updates to the AABB, which occur whenever {@link Entity}s are transformed, their\n * {@link ReadableGeometry}s have been updated, or the {@link Camera} has moved:\n *\n * ````javascript\n * scene.on(\"boundary\", function() {\n *      var aabb = scene.aabb;\n * });\n * ````\n *\n * Getting the AABB of the {@link Entity}s with the given IDs:\n *\n * ````JavaScript\n * scene.getAABB(); // Gets collective boundary of all Entities in the scene\n * scene.getAABB(\"saw\"); // Gets boundary of an Object\n * scene.getAABB([\"saw\", \"gearbox\"]); // Gets collective boundary of two Objects\n * ````\n *\n * See {@link Scene#getAABB} and {@link Entity} for more info on querying and tracking boundaries.\n *\n * ## Managing the viewport\n *\n * The Scene's {@link Viewport} component manages the WebGL viewport:\n *\n * ````javascript\n * var viewport = scene.viewport\n * viewport.boundary = [0, 0, 500, 400];;\n * ````\n *\n * ## Controlling rendering\n *\n * You can configure a Scene to perform multiple \"passes\" (renders) per frame. This is useful when we want to render the\n * scene to multiple viewports, such as for stereo effects.\n *\n * In the example, below, we'll configure the Scene to render twice on each frame, each time to different viewport. We'll do this\n * with a callback that intercepts the Scene before each render and sets its {@link Viewport} to a\n * different portion of the canvas. By default, the Scene will clear the canvas only before the first render, allowing the\n * two views to be shown on the canvas at the same time.\n *\n * ````Javascript\n * var viewport = scene.viewport;\n *\n * // Configure Scene to render twice for each frame\n * scene.passes = 2; // Default is 1\n * scene.clearEachPass = false; // Default is false\n *\n * // Render to a separate viewport on each render\n *\n * var viewport = scene.viewport;\n * viewport.autoBoundary = false;\n *\n * scene.on(\"rendering\", function (e) {\n *      switch (e.pass) {\n *          case 0:\n *              viewport.boundary = [0, 0, 200, 200]; // xmin, ymin, width, height\n *              break;\n *\n *          case 1:\n *              viewport.boundary = [200, 0, 200, 200];\n *              break;\n *      }\n * });\n *\n * // We can also intercept the Scene after each render,\n * // (though we're not using this for anything here)\n * scene.on(\"rendered\", function (e) {\n *      switch (e.pass) {\n *          case 0:\n *              break;\n *\n *          case 1:\n *              break;\n *      }\n * });\n * ````\n *\n * ## Gamma correction\n *\n * Within its shaders, xeokit performs shading calculations in linear space.\n *\n * By default, the Scene expects color textures (eg. {@link PhongMaterial#diffuseMap},\n * {@link MetallicMaterial#baseColorMap} and {@link SpecularMaterial#diffuseMap}) to\n * be in pre-multipled gamma space, so will convert those to linear space before they are used in shaders. Other textures are\n * always expected to be in linear space.\n *\n * By default, the Scene will also gamma-correct its rendered output.\n *\n * You can configure the Scene to expect all those color textures to be linear space, so that it does not gamma-correct them:\n *\n * ````javascript\n * scene.gammaInput = false;\n * ````\n *\n * You would still need to gamma-correct the output, though, if it's going straight to the canvas, so normally we would\n * leave that enabled:\n *\n * ````javascript\n * scene.gammaOutput = true;\n * ````\n *\n * See {@link Texture} for more information on texture encoding and gamma.\n *\n * @class Scene\n */\nclass Scene extends Component {\n\n    /**\n     @private\n     */\n    get type() {\n        return \"Scene\";\n    }\n\n    /**\n     * @private\n     * @constructor\n     * @param {Viewer} viewer The Viewer this Scene belongs to.\n     * @param {Object} cfg Scene configuration.\n     * @param {String} [cfg.canvasId]  ID of an existing HTML canvas for the {@link Scene#canvas} - either this or canvasElement is mandatory. When both values are given, the element reference is always preferred to the ID.\n     * @param {HTMLCanvasElement} [cfg.canvasElement] Reference of an existing HTML canvas for the {@link Scene#canvas} - either this or canvasId is mandatory. When both values are given, the element reference is always preferred to the ID.\n     * @param {HTMLElement} [cfg.keyboardEventsElement] Optional reference to HTML element on which key events should be handled. Defaults to the HTML Document.\n     * @param {number} [cfg.numCachedSectionPlanes=0] Enhances the efficiency of SectionPlane creation by proactively allocating Viewer resources for a specified quantity\n     * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\n     * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing\n     * responsiveness. It is important to consider that each SectionPlane imposes rendering performance, so it is recommended to set this value to a quantity that aligns with\n     * your expected usage.\n     * @throws {String} Throws an exception when  canvasId or canvasElement are missing or they aren't pointing to a valid HTMLCanvasElement.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(null, cfg);\n        const canvas = cfg.canvasElement || document.querySelector(`#${cfg.canvasId}`);\n\n        if (!(canvas instanceof HTMLCanvasElement)) {\n            throw \"Mandatory config expected: valid canvasId or canvasElement\";\n        }\n\n        /**\n         * @type {{[key: string]: {wrapperFunc: Function, tickSubId: string}}}\n         */\n        this._tickifiedFunctions = {};\n\n        const transparent = (!!cfg.transparent);\n        const alphaDepthMask = (!!cfg.alphaDepthMask);\n\n        this._aabbDirty = true;\n\n        this._readableGeometry = !!cfg.readableGeometryEnabled;\n\n        /**\n         * The {@link Viewer} this Scene belongs to.\n         * @type {Viewer}\n         */\n        this.viewer = viewer;\n\n        /** Decremented each frame, triggers occlusion test for occludable {@link Marker}s when zero.\n         * @private\n         * @type {number}\n         */\n        this.occlusionTestCountdown = 0;\n\n        /**\n         The number of models currently loading.\n\n         @property loading\n         @final\n         @type {Number}\n         */\n        this.loading = 0;\n\n        /**\n         The epoch time (in milliseconds since 1970) when this Scene was instantiated.\n\n         @property timeCreated\n         @final\n         @type {Number}\n         */\n        this.startTime = (new Date()).getTime();\n\n        /**\n         * Map of {@link Entity}s that represent models.\n         *\n         * Each {@link Entity} is mapped here by {@link Entity#id} when {@link Entity#isModel} is ````true````.\n         *\n         * @property models\n         * @final\n         * @type {{String:Entity}}\n         */\n        this.models = {};\n\n        /**\n         * Map of {@link Entity}s that represents objects.\n         *\n         * Each {@link Entity} is mapped here by {@link Entity#id} when {@link Entity#isObject} is ````true````.\n         *\n         * @property objects\n         * @final\n         * @type {{String:Entity}}\n         */\n        this.objects = {};\n        this._numObjects = 0;\n\n        /**\n         * Map of currently visible {@link Entity}s that represent objects.\n         *\n         * An Entity represents an object if {@link Entity#isObject} is ````true````, and is visible when {@link Entity#visible} is true.\n         *\n         * @property visibleObjects\n         * @final\n         * @type {{String:Object}}\n         */\n        this.visibleObjects = {};\n        this._numVisibleObjects = 0;\n\n        /**\n         * Map of currently xrayed {@link Entity}s that represent objects.\n         *\n         * An Entity represents an object if {@link Entity#isObject} is ````true````, and is xrayed when {@link Entity#xrayed} is true.\n         *\n         * Each {@link Entity} is mapped here by {@link Entity#id}.\n         *\n         * @property xrayedObjects\n         * @final\n         * @type {{String:Object}}\n         */\n        this.xrayedObjects = {};\n        this._numXRayedObjects = 0;\n\n        /**\n         * Map of currently highlighted {@link Entity}s that represent objects.\n         *\n         * An Entity represents an object if {@link Entity#isObject} is ````true```` is true, and is highlighted when {@link Entity#highlighted} is true.\n         *\n         * Each {@link Entity} is mapped here by {@link Entity#id}.\n         *\n         * @property highlightedObjects\n         * @final\n         * @type {{String:Object}}\n         */\n        this.highlightedObjects = {};\n        this._numHighlightedObjects = 0;\n\n        /**\n         * Map of currently selected {@link Entity}s that represent objects.\n         *\n         * An Entity represents an object if {@link Entity#isObject} is true, and is selected while {@link Entity#selected} is true.\n         *\n         * Each {@link Entity} is mapped here by {@link Entity#id}.\n         *\n         * @property selectedObjects\n         * @final\n         * @type {{String:Object}}\n         */\n        this.selectedObjects = {};\n        this._numSelectedObjects = 0;\n\n        /**\n         * Map of currently colorized {@link Entity}s that represent objects.\n         *\n         * An Entity represents an object if {@link Entity#isObject} is ````true````.\n         *\n         * Each {@link Entity} is mapped here by {@link Entity#id}.\n         *\n         * @property colorizedObjects\n         * @final\n         * @type {{String:Object}}\n         */\n        this.colorizedObjects = {};\n        this._numColorizedObjects = 0;\n\n        /**\n         * Map of {@link Entity}s that represent objects whose opacity was updated.\n         *\n         * An Entity represents an object if {@link Entity#isObject} is ````true````.\n         *\n         * Each {@link Entity} is mapped here by {@link Entity#id}.\n         *\n         * @property opacityObjects\n         * @final\n         * @type {{String:Object}}\n         */\n        this.opacityObjects = {};\n        this._numOpacityObjects = 0;\n\n        /**\n         * Map of {@link Entity}s that represent objects whose {@link Entity#offset}s were updated.\n         *\n         * An Entity represents an object if {@link Entity#isObject} is ````true````.\n         *\n         * Each {@link Entity} is mapped here by {@link Entity#id}.\n         *\n         * @property offsetObjects\n         * @final\n         * @type {{String:Object}}\n         */\n        this.offsetObjects = {};\n        this._numOffsetObjects = 0;\n\n        // Cached ID arrays, lazy-rebuilt as needed when stale after map updates\n\n        /**\n         Lazy-regenerated ID lists.\n         */\n        this._modelIds = null;\n        this._objectIds = null;\n        this._visibleObjectIds = null;\n        this._xrayedObjectIds = null;\n        this._highlightedObjectIds = null;\n        this._selectedObjectIds = null;\n        this._colorizedObjectIds = null;\n        this._opacityObjectIds = null;\n        this._offsetObjectIds = null;\n\n        this._collidables = {}; // Components that contribute to the Scene AABB\n        this._compilables = {}; // Components that require shader compilation\n\n        this._needRecompile = false;\n\n        /**\n         * For each {@link Component} type, a map of IDs to {@link Component} instances of that type.\n         *\n         * @type {{String:{String:Component}}}\n         */\n        this.types = {};\n\n        /**\n         * The {@link Component}s within this Scene, each mapped to its {@link Component#id}.\n         *\n         * *@type {{String:Component}}\n         */\n        this.components = {};\n\n        /**\n         * The {@link SectionPlane}s in this Scene, each mapped to its {@link SectionPlane#id}.\n         *\n         * @type {{String:SectionPlane}}\n         */\n        this.sectionPlanes = {};\n\n        /**\n         * The {@link Light}s in this Scene, each mapped to its {@link Light#id}.\n         *\n         * @type {{String:Light}}\n         */\n        this.lights = {};\n\n        /**\n         * The {@link LightMap}s in this Scene, each mapped to its {@link LightMap#id}.\n         *\n         * @type {{String:LightMap}}\n         */\n        this.lightMaps = {};\n\n        /**\n         * The {@link ReflectionMap}s in this Scene, each mapped to its {@link ReflectionMap#id}.\n         *\n         * @type {{String:ReflectionMap}}\n         */\n        this.reflectionMaps = {};\n\n        /**\n         * The {@link Bitmap}s in this Scene, each mapped to its {@link Bitmap#id}.\n         *\n         * @type {{String:Bitmap}}\n         */\n        this.bitmaps = {};\n\n        /**\n         * The {@link LineSet}s in this Scene, each mapped to its {@link LineSet#id}.\n         *\n         * @type {{String:LineSet}}\n         */\n        this.lineSets = {};\n\n        /**\n         * The real world offset for this Scene\n         *\n         * @type {Number[]}\n         */\n        this.realWorldOffset = cfg.realWorldOffset || new Float64Array([0, 0, 0]);\n\n        /**\n         * Manages the HTML5 canvas for this Scene.\n         *\n         * @type {Canvas}\n         */\n        this.canvas = new Canvas(this, {\n            dontClear: true, // Never destroy this component with Scene#clear();\n            canvas: canvas,\n            spinnerElementId: cfg.spinnerElementId,\n            transparent: transparent,\n            webgl2: cfg.webgl2 !== false,\n            contextAttr: cfg.contextAttr || {},\n            backgroundColor: cfg.backgroundColor,\n            backgroundColorFromAmbientLight: cfg.backgroundColorFromAmbientLight,\n            premultipliedAlpha: cfg.premultipliedAlpha\n        });\n\n        const onContextLost = (event) => this.viewer.destroy();\n        canvas.addEventListener(\"webglcontextlost\", onContextLost, false);\n        this._removeWebglcontextlostListener = () => canvas.removeEventListener(\"webglcontextlost\", onContextLost, false);\n\n        this.canvas.on(\"boundary\", () => {\n            this.glRedraw();\n        });\n\n        this.canvas.on(\"webglContextFailed\", () => {\n            alert(\"xeokit failed to find WebGL!\");\n        });\n\n        this._renderer = new Renderer$1(this, {\n            transparent: transparent,\n            alphaDepthMask: alphaDepthMask\n        });\n\n        this._sectionPlanesState = new (function () {\n\n            this.sectionPlanes = [];\n\n            this.clippingCaps = false;\n\n            this._numCachedSectionPlanes = 0;\n\n            let hash = null;\n\n            this.getHash = function () {\n                if (hash) {\n                    return hash;\n                }\n                const numAllocatedSectionPlanes = this.getNumAllocatedSectionPlanes();\n                this.sectionPlanes;\n                if (numAllocatedSectionPlanes === 0) {\n                    return this.hash = \";\";\n                }\n\n                const hashParts = [];\n                for (let i = 0, len = numAllocatedSectionPlanes; i < len; i++) {\n                    hashParts.push(\"cp\");\n                }\n                hashParts.push(\";\");\n                hash = hashParts.join(\"\");\n                return hash;\n            };\n\n            this.addSectionPlane = function (sectionPlane) {\n                this.sectionPlanes.push(sectionPlane);\n                hash = null;\n            };\n\n            this.removeSectionPlane = function (sectionPlane) {\n                for (let i = 0, len = this.sectionPlanes.length; i < len; i++) {\n                    if (this.sectionPlanes[i].id === sectionPlane.id) {\n                        this.sectionPlanes.splice(i, 1);\n                        hash = null;\n                        return;\n                    }\n                }\n            };\n\n            this.setNumCachedSectionPlanes = function (numCachedSectionPlanes) {\n                this._numCachedSectionPlanes = numCachedSectionPlanes;\n                hash = null;\n            };\n\n            this.getNumCachedSectionPlanes = function () {\n                return this._numCachedSectionPlanes;\n            };\n\n            this.getNumAllocatedSectionPlanes = function () {\n                const num = this.sectionPlanes.length;\n                return (num > this._numCachedSectionPlanes) ? num : this._numCachedSectionPlanes;\n            };\n        })();\n\n        this._sectionPlanesState.setNumCachedSectionPlanes(cfg.numCachedSectionPlanes || 0);\n\n        this._lightsState = new (function () {\n\n            const DEFAULT_AMBIENT = math.vec4([0, 0, 0, 0]);\n            const ambientColorIntensity = math.vec4();\n\n            this.lights = [];\n            this.reflectionMaps = [];\n            this.lightMaps = [];\n\n            let hash = null;\n            let ambientLight = null;\n\n            this.getHash = function () {\n                if (hash) {\n                    return hash;\n                }\n                const hashParts = [];\n                const lights = this.lights;\n                let light;\n                for (let i = 0, len = lights.length; i < len; i++) {\n                    light = lights[i];\n                    hashParts.push(\"/\");\n                    hashParts.push(light.type);\n                    hashParts.push((light.space === \"world\") ? \"w\" : \"v\");\n                    if (light.castsShadow) {\n                        hashParts.push(\"sh\");\n                    }\n                }\n                if (this.lightMaps.length > 0) {\n                    hashParts.push(\"/lm\");\n                }\n                if (this.reflectionMaps.length > 0) {\n                    hashParts.push(\"/rm\");\n                }\n                hashParts.push(\";\");\n                hash = hashParts.join(\"\");\n                return hash;\n            };\n\n            this.addLight = function (state) {\n                this.lights.push(state);\n                ambientLight = null;\n                hash = null;\n            };\n\n            this.removeLight = function (state) {\n                for (let i = 0, len = this.lights.length; i < len; i++) {\n                    const light = this.lights[i];\n                    if (light.id === state.id) {\n                        this.lights.splice(i, 1);\n                        if (ambientLight && ambientLight.id === state.id) {\n                            ambientLight = null;\n                        }\n                        hash = null;\n                        return;\n                    }\n                }\n            };\n\n            this.addReflectionMap = function (state) {\n                this.reflectionMaps.push(state);\n                hash = null;\n            };\n\n            this.removeReflectionMap = function (state) {\n                for (let i = 0, len = this.reflectionMaps.length; i < len; i++) {\n                    if (this.reflectionMaps[i].id === state.id) {\n                        this.reflectionMaps.splice(i, 1);\n                        hash = null;\n                        return;\n                    }\n                }\n            };\n\n            this.addLightMap = function (state) {\n                this.lightMaps.push(state);\n                hash = null;\n            };\n\n            this.removeLightMap = function (state) {\n                for (let i = 0, len = this.lightMaps.length; i < len; i++) {\n                    if (this.lightMaps[i].id === state.id) {\n                        this.lightMaps.splice(i, 1);\n                        hash = null;\n                        return;\n                    }\n                }\n            };\n\n            this.getAmbientColorAndIntensity = function () {\n                if (!ambientLight) {\n                    for (let i = 0, len = this.lights.length; i < len; i++) {\n                        const light = this.lights[i];\n                        if (light.type === \"ambient\") {\n                            ambientLight = light;\n                            break;\n                        }\n                    }\n                }\n                if (ambientLight) {\n                    const color = ambientLight.color;\n                    const intensity = ambientLight.intensity;\n                    ambientColorIntensity[0] = color[0];\n                    ambientColorIntensity[1] = color[1];\n                    ambientColorIntensity[2] = color[2];\n                    ambientColorIntensity[3] = intensity;\n                    return ambientColorIntensity;\n                } else {\n                    return DEFAULT_AMBIENT;\n                }\n            };\n\n        })();\n\n        /**\n         * Publishes input events that occur on this Scene's canvas.\n         *\n         * @property input\n         * @type {Input}\n         * @final\n         */\n        this.input = new Input(this, {\n            dontClear: true, // Never destroy this component with Scene#clear();\n            element: this.canvas.canvas,\n            keyboardEventsElement: cfg.keyboardEventsElement\n        });\n\n        /**\n         * Configures this Scene's units of measurement and coordinate mapping between Real-space and World-space 3D coordinate systems.\n         *\n         * @property metrics\n         * @type {Metrics}\n         * @final\n         */\n        this.metrics = new Metrics(this, {\n            units: cfg.units,\n            scale: cfg.scale,\n            origin: cfg.origin\n        });\n\n        /** Configures Scalable Ambient Obscurance (SAO) for this Scene.\n         * @type {SAO}\n         * @final\n         */\n        this.sao = new SAO(this, {\n            enabled: cfg.saoEnabled\n        });\n\n        /** Configures Cross Sections for this Scene.\n         * @type {CrossSections}\n         * @final\n         */\n        this.crossSections = new CrossSections(this, {\n\n        });\n\n        this.ticksPerRender = cfg.ticksPerRender;\n        this.ticksPerOcclusionTest = cfg.ticksPerOcclusionTest;\n        this.passes = cfg.passes;\n        this.clearEachPass = cfg.clearEachPass;\n        this.gammaInput = cfg.gammaInput;\n        this.gammaOutput = cfg.gammaOutput;\n        this.gammaFactor = cfg.gammaFactor;\n\n        this._entityOffsetsEnabled = !!cfg.entityOffsetsEnabled;\n        this._logarithmicDepthBufferEnabled = !!cfg.logarithmicDepthBufferEnabled;\n\n        this._dtxEnabled = (cfg.dtxEnabled !== false);\n        this._pbrEnabled = !!cfg.pbrEnabled;\n        this._colorTextureEnabled = (cfg.colorTextureEnabled !== false);\n        this._dtxEnabled = !!cfg.dtxEnabled;\n        this._markerZOffset = cfg.markerZOffset;\n\n        // Register Scene on xeokit\n        // Do this BEFORE we add components below\n        core._addScene(this);\n\n        this._initDefaults();\n\n        // Global components\n\n        this._viewport = new Viewport(this, {\n            id: \"default.viewport\",\n            autoBoundary: true,\n            dontClear: true // Never destroy this component with Scene#clear();\n        });\n\n        this._camera = new Camera(this, {\n            id: \"default.camera\",\n            dontClear: true // Never destroy this component with Scene#clear();\n        });\n\n        this._sectionCaps = new SectionCaps(this);\n\n        // Default lights\n\n        new AmbientLight(this, {\n            color: [1.0, 1.0, 1.0],\n            intensity: 0.7\n        });\n\n        new DirLight(this, {\n            dir: [0.8, -.5, -0.5],\n            color: [0.67, 0.67, 1.0],\n            intensity: 0.7,\n            space: \"world\"\n        });\n\n        new DirLight(this, {\n            dir: [-0.8, -1.0, 0.5],\n            color: [1, 1, .9],\n            intensity: 0.9,\n            space: \"world\"\n        });\n\n        this._camera.on(\"dirty\", () => {\n            this._renderer.imageDirty();\n        });\n    }\n\n    _initDefaults() {\n    }\n\n    _addComponent(component) {\n        if (component.id) { // Manual ID\n            if (this.components[component.id]) {\n                this.error(\"Component \" + utils.inQuotes(component.id) + \" already exists in Scene - ignoring ID, will randomly-generate instead\");\n                component.id = null;\n            }\n        }\n        if (!component.id) { // Auto ID\n            if (window.nextID === undefined) {\n                window.nextID = 0;\n            }\n            //component.id = math.createUUID();\n            component.id = \"__\" + window.nextID++;\n            while (this.components[component.id]) {\n                component.id = math.createUUID();\n            }\n        }\n        this.components[component.id] = component;\n\n        // Register for class type\n        const type = component.type;\n        let types = this.types[component.type];\n        if (!types) {\n            types = this.types[type] = {};\n        }\n        types[component.id] = component;\n\n        if (component.compile) {\n            this._compilables[component.id] = component;\n        }\n        if (component.isDrawable) {\n            this._renderer.addDrawable(component.id, component);\n            this._collidables[component.id] = component;\n        }\n    }\n\n    _removeComponent(component) {\n        var id = component.id;\n        var type = component.type;\n        delete this.components[id];\n        // Unregister for types\n        const types = this.types[type];\n        if (types) {\n            delete types[id];\n            if (utils.isEmptyObject(types)) {\n                delete this.types[type];\n            }\n        }\n        if (component.compile) {\n            delete this._compilables[component.id];\n        }\n        if (component.isDrawable) {\n            this._renderer.removeDrawable(component.id);\n            delete this._collidables[component.id];\n        }\n    }\n\n    // Methods below are called by various component types to register themselves on their\n    // Scene. Violates Hollywood Principle, where we could just filter on type in _addComponent,\n    // but this is faster than checking the type of each component in such a filter.\n\n    _sectionPlaneCreated(sectionPlane) {\n        this.sectionPlanes[sectionPlane.id] = sectionPlane;\n        this.scene._sectionPlanesState.addSectionPlane(sectionPlane._state);\n        this.scene.fire(\"sectionPlaneCreated\", sectionPlane, true /* Don't retain event */);\n        this._needRecompile = true;\n    }\n\n    _bitmapCreated(bitmap) {\n        this.bitmaps[bitmap.id] = bitmap;\n        this.scene.fire(\"bitmapCreated\", bitmap, true /* Don't retain event */);\n    }\n\n    _lineSetCreated(lineSet) {\n        this.lineSets[lineSet.id] = lineSet;\n        this.scene.fire(\"lineSetCreated\", lineSet, true /* Don't retain event */);\n    }\n\n    _lightCreated(light) {\n        this.lights[light.id] = light;\n        this.scene._lightsState.addLight(light._state);\n        this._needRecompile = true;\n    }\n\n    _lightMapCreated(lightMap) {\n        this.lightMaps[lightMap.id] = lightMap;\n        this.scene._lightsState.addLightMap(lightMap._state);\n        this._needRecompile = true;\n    }\n\n    _reflectionMapCreated(reflectionMap) {\n        this.reflectionMaps[reflectionMap.id] = reflectionMap;\n        this.scene._lightsState.addReflectionMap(reflectionMap._state);\n        this._needRecompile = true;\n    }\n\n    _sectionPlaneDestroyed(sectionPlane) {\n        delete this.sectionPlanes[sectionPlane.id];\n        this.scene._sectionPlanesState.removeSectionPlane(sectionPlane._state);\n        this.scene.fire(\"sectionPlaneDestroyed\", sectionPlane, true /* Don't retain event */);\n        this._needRecompile = true;\n    }\n\n    _bitmapDestroyed(bitmap) {\n        delete this.bitmaps[bitmap.id];\n        this.scene.fire(\"bitmapDestroyed\", bitmap, true /* Don't retain event */);\n    }\n\n    _lineSetDestroyed(lineSet) {\n        delete this.lineSets[lineSet.id];\n        this.scene.fire(\"lineSetDestroyed\", lineSet, true /* Don't retain event */);\n    }\n\n    _lightDestroyed(light) {\n        delete this.lights[light.id];\n        this.scene._lightsState.removeLight(light._state);\n        this._needRecompile = true;\n    }\n\n    _lightMapDestroyed(lightMap) {\n        delete this.lightMaps[lightMap.id];\n        this.scene._lightsState.removeLightMap(lightMap._state);\n        this._needRecompile = true;\n    }\n\n    _reflectionMapDestroyed(reflectionMap) {\n        delete this.reflectionMaps[reflectionMap.id];\n        this.scene._lightsState.removeReflectionMap(reflectionMap._state);\n        this._needRecompile = true;\n    }\n\n    _registerModel(entity) {\n        this.models[entity.id] = entity;\n        this._modelIds = null; // Lazy regenerate\n    }\n\n    _deregisterModel(entity) {\n        const modelId = entity.id;\n        delete this.models[modelId];\n        this._modelIds = null; // Lazy regenerate\n        this.fire(\"modelUnloaded\", modelId);\n    }\n\n    _registerObject(entity) {\n        this.objects[entity.id] = entity;\n        this._numObjects++;\n        this._objectIds = null; // Lazy regenerate\n    }\n\n    _deregisterObject(entity) {\n        delete this.objects[entity.id];\n        this._numObjects--;\n        this._objectIds = null; // Lazy regenerate\n    }\n\n    _objectVisibilityUpdated(entity, notify = true) {\n        if (entity.visible) {\n            this.visibleObjects[entity.id] = entity;\n            this._numVisibleObjects++;\n        } else {\n            delete this.visibleObjects[entity.id];\n            this._numVisibleObjects--;\n        }\n        this._visibleObjectIds = null; // Lazy regenerate\n        if (notify) {\n            this.fire(\"objectVisibility\", entity, true);\n        }\n    }\n\n    _deRegisterVisibleObject(entity) {\n        delete this.visibleObjects[entity.id];\n        this._numVisibleObjects--;\n        this._visibleObjectIds = null; // Lazy regenerate\n    }\n\n    _objectXRayedUpdated(entity, notify = true) {\n        if (entity.xrayed) {\n            this.xrayedObjects[entity.id] = entity;\n            this._numXRayedObjects++;\n        } else {\n            delete this.xrayedObjects[entity.id];\n            this._numXRayedObjects--;\n        }\n        this._xrayedObjectIds = null; // Lazy regenerate\n        if (notify) {\n            this.fire(\"objectXRayed\", entity, true);\n        }\n    }\n\n    _deRegisterXRayedObject(entity) {\n        delete this.xrayedObjects[entity.id];\n        this._numXRayedObjects--;\n        this._xrayedObjectIds = null; // Lazy regenerate\n    }\n\n    _objectHighlightedUpdated(entity) {\n        if (entity.highlighted) {\n            this.highlightedObjects[entity.id] = entity;\n            this._numHighlightedObjects++;\n        } else {\n            delete this.highlightedObjects[entity.id];\n            this._numHighlightedObjects--;\n        }\n        this._highlightedObjectIds = null; // Lazy regenerate\n    }\n\n    _deRegisterHighlightedObject(entity) {\n        delete this.highlightedObjects[entity.id];\n        this._numHighlightedObjects--;\n        this._highlightedObjectIds = null; // Lazy regenerate\n    }\n\n    _objectSelectedUpdated(entity, notify = true) {\n        if (entity.selected) {\n            this.selectedObjects[entity.id] = entity;\n            this._numSelectedObjects++;\n        } else {\n            delete this.selectedObjects[entity.id];\n            this._numSelectedObjects--;\n        }\n        this._selectedObjectIds = null; // Lazy regenerate\n        if (notify) {\n            this.fire(\"objectSelected\", entity, true);\n        }\n    }\n\n    _deRegisterSelectedObject(entity) {\n        delete this.selectedObjects[entity.id];\n        this._numSelectedObjects--;\n        this._selectedObjectIds = null; // Lazy regenerate\n    }\n\n\n    _objectColorizeUpdated(entity, colorized) {\n        if (colorized) {\n            this.colorizedObjects[entity.id] = entity;\n            this._numColorizedObjects++;\n        } else {\n            delete this.colorizedObjects[entity.id];\n            this._numColorizedObjects--;\n        }\n        this._colorizedObjectIds = null; // Lazy regenerate\n    }\n\n    _deRegisterColorizedObject(entity) {\n        delete this.colorizedObjects[entity.id];\n        this._numColorizedObjects--;\n        this._colorizedObjectIds = null; // Lazy regenerate\n    }\n\n    _objectOpacityUpdated(entity, opacityUpdated) {\n        if (opacityUpdated) {\n            this.opacityObjects[entity.id] = entity;\n            this._numOpacityObjects++;\n        } else {\n            delete this.opacityObjects[entity.id];\n            this._numOpacityObjects--;\n        }\n        this._opacityObjectIds = null; // Lazy regenerate\n    }\n\n    _deRegisterOpacityObject(entity) {\n        delete this.opacityObjects[entity.id];\n        this._numOpacityObjects--;\n        this._opacityObjectIds = null; // Lazy regenerate\n    }\n\n    _objectOffsetUpdated(entity, offset) {\n        if (!offset || offset[0] === 0 && offset[1] === 0 && offset[2] === 0) {\n            this.offsetObjects[entity.id] = entity;\n            this._numOffsetObjects++;\n        } else {\n            delete this.offsetObjects[entity.id];\n            this._numOffsetObjects--;\n        }\n        this._offsetObjectIds = null; // Lazy regenerate\n    }\n\n    _deRegisterOffsetObject(entity) {\n        delete this.offsetObjects[entity.id];\n        this._numOffsetObjects--;\n        this._offsetObjectIds = null; // Lazy regenerate\n    }\n\n    /**\n     * Returns the capabilities of this Scene.\n     *\n     * @private\n     * @returns {{astcSupported: boolean, etc1Supported: boolean, pvrtcSupported: boolean, etc2Supported: boolean, dxtSupported: boolean, bptcSupported: boolean}}\n     */\n    get capabilities() {\n        return this._renderer.capabilities;\n    }\n\n    /**\n     * Whether {@link Entity#offset} is enabled.\n     *\n     * This is set via the {@link Viewer} constructor and is ````false```` by default.\n     *\n     * @returns {Boolean} True if {@link Entity#offset} is enabled.\n     */\n    get entityOffsetsEnabled() {\n        return this._entityOffsetsEnabled;\n    }\n\n    /**\n     * Whether geometry is readable.\n     *\n     * This is set via the {@link Viewer} constructor and is ````false```` by default.\n     *\n     * The ````readableGeometryEnabled```` option for ````Scene#pick```` only works if this is set ````true````.\n     *\n     * Note that when ````true````, this configuration will increase the amount of browser memory used by the Viewer.\n     *\n     * @returns {Boolean} True if geometry is readable.\n     */\n    get readableGeometryEnabled() {\n        return this._readableGeometry;\n    }\n\n    /**\n     * Whether precision surface picking is enabled.\n     * @deprecated\n     * @returns {*|boolean}\n     */\n    get pickSurfacePrecisionEnabled() {\n        return this._readableGeometry;\n    }\n\n    /**\n     * Whether logarithmic depth buffer is enabled.\n     *\n     * This is set via the {@link Viewer} constructor and is ````false```` by default.\n     *\n     * @returns {Boolean} True if logarithmic depth buffer is enabled.\n     */\n    get logarithmicDepthBufferEnabled() {\n        return this._logarithmicDepthBufferEnabled;\n    }\n\n    /**\n     * Sets the number of {@link SectionPlane}s for which this Scene pre-caches resources.\n     *\n     * This property enhances the efficiency of SectionPlane creation by proactively allocating and caching Viewer resources for a specified quantity\n     * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\n     * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing\n     * responsiveness. It is important to consider that each SectionPlane impacts rendering performance, so it is recommended to set this value to a quantity that aligns with\n     * your expected usage.\n     *\n     * Default is ````0````.\n     */\n    set numCachedSectionPlanes(numCachedSectionPlanes) {\n        numCachedSectionPlanes = numCachedSectionPlanes || 0;\n        if (this._sectionPlanesState.getNumCachedSectionPlanes() !== numCachedSectionPlanes) {\n            this._sectionPlanesState.setNumCachedSectionPlanes(numCachedSectionPlanes);\n            this._needRecompile = true;\n            this.glRedraw();\n        }\n    }\n\n    /**\n     * Gets the number of {@link SectionPlane}s for which this Scene pre-caches resources.\n     *\n     * This property enhances the efficiency of SectionPlane creation by proactively allocating and caching Viewer resources for a specified quantity\n     * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\n     * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing\n     * responsiveness. It is important to consider that each SectionPlane impacts rendering performance, so it is recommended to set this value to a quantity that aligns with\n     * your expected usage.\n     *\n     * Default is ````0````.\n     *\n     * @returns {number} The number of {@link SectionPlane}s for which this Scene pre-caches resources.\n     */\n    get numCachedSectionPlanes() {\n        return this._sectionPlanesState.getNumCachedSectionPlanes();\n    }\n\n    /**\n     * Sets whether physically-based rendering is enabled.\n     *\n     * Default is ````false````.\n     */\n    set pbrEnabled(pbrEnabled) {\n        this._pbrEnabled = !!pbrEnabled;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether physically-based rendering is enabled.\n     *\n     * Default is ````false````.\n     *\n     * @returns {Boolean} True if quality rendering is enabled.\n     */\n    get pbrEnabled() {\n        return this._pbrEnabled;\n    }\n\n    /**\n     * Sets whether data texture scene representation (DTX) is enabled for the {@link Scene}.\n     *\n     * Even when enabled, DTX will only work if supported.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set dtxEnabled(value) {\n        value = !!value;\n        if (this._dtxEnabled === value) {\n            return;\n        }\n        this._dtxEnabled = value;\n    }\n\n    /**\n     * Gets whether data texture-based scene representation (DTX) is enabled for the {@link Scene}.\n     *\n     * Even when enabled, DTX will only apply if supported.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get dtxEnabled() {\n        return this._dtxEnabled;\n    }\n\n    /**\n     * Sets whether basic color texture rendering is enabled.\n     *\n     * Default is ````true````.\n     *\n     * @returns {Boolean} True if basic color texture rendering is enabled.\n     */\n    set colorTextureEnabled(colorTextureEnabled) {\n        this._colorTextureEnabled = !!colorTextureEnabled;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether basic color texture rendering is enabled.\n     *\n     * Default is ````true````.\n     *\n     * @returns {Boolean} True if basic color texture rendering is enabled.\n     */\n    get colorTextureEnabled() {\n        return this._colorTextureEnabled;\n    }\n\n    /**\n     * Gets the Z value of offset for Marker's OcclusionTester.\n     * The closest the value is to 0.000 the more precise OcclusionTester will be, but at the same time the less\n     * precise it will behave for Markers that are located exactly on the Surface.\n     *\n     * Default is ````-0.001````.\n     *\n     * @returns {Number} Z offset for Marker\n     */\n    get markerZOffset() {\n        if (this._markerZOffset == null) {\n            return -0.001;\n        }\n        return this._markerZOffset;\n    }\n\n    /**\n     * Performs an occlusion test on all {@link Marker}s in this {@link Scene}.\n     *\n     * Sets each {@link Marker#visible} ````true```` if the Marker is currently not occluded by any opaque {@link Entity}s\n     * in the Scene, or ````false```` if an Entity is occluding it.\n     */\n    doOcclusionTest() {\n        if (this._needRecompile) {\n            this._recompile();\n            this._needRecompile = false;\n        }\n        this._renderer.doOcclusionTest();\n    }\n\n    /**\n     * Renders a single frame of this Scene.\n     *\n     * The Scene will periodically render itself after any updates, but you can call this method to force a render\n     * if required.\n     *\n     * @param {Boolean} [forceRender=false] Forces a render when true, otherwise only renders if something has changed in this Scene\n     * since the last render.\n     */\n    render(forceRender) {\n\n        if (forceRender) {\n            core.runTasks();\n        }\n\n        const renderEvent = {\n            sceneId: null,\n            pass: 0\n        };\n\n        if (this._needRecompile) {\n            this._recompile();\n            this._renderer.imageDirty();\n            this._needRecompile = false;\n        }\n\n        if (!forceRender && !this._renderer.needsRender()) {\n            return;\n        }\n\n        renderEvent.sceneId = this.id;\n\n        for (let pass = 0; pass < this._passes; pass++) {\n\n            renderEvent.pass = pass;\n\n            /**\n             * Fired when about to render a frame for a Scene.\n             *\n             * @event rendering\n             * @param {String} sceneID The ID of this Scene.\n             * @param {Number} pass Index of the pass we are about to render (see {@link Scene#passes}).\n             */\n            this.fire(\"rendering\", renderEvent, true);\n\n            if (forceRender) {\n                this._renderer.imageDirty();\n            }\n            this._renderer.render(pass, this._clearEachPass || (pass === 0));\n\n            /**\n             * Fired when we have just rendered a frame for a Scene.\n             *\n             * @event rendering\n             * @param {String} sceneID The ID of this Scene.\n             * @param {Number} pass Index of the pass we rendered (see {@link Scene#passes}).\n             */\n            this.fire(\"rendered\", renderEvent, true);\n        }\n\n        this._saveAmbientColor();\n    }\n\n\n    /**\n     * @private\n     */\n    compile() {\n        if (this._needRecompile) {\n            this._recompile();\n            this._renderer.imageDirty();\n            this._needRecompile = false;\n        }\n    }\n\n    _recompile() {\n        for (const id in this._compilables) {\n            if (this._compilables.hasOwnProperty(id)) {\n                this._compilables[id].compile();\n            }\n        }\n        this._renderer.shadowsDirty();\n        this.fire(\"compile\", this, true);\n    }\n\n    _saveAmbientColor() {\n        const canvas = this.canvas;\n        if (!canvas.transparent && !canvas.backgroundImage && !canvas.backgroundColor) {\n            const ambientColorIntensity = this._lightsState.getAmbientColorAndIntensity();\n            if (!this._lastAmbientColor ||\n                this._lastAmbientColor[0] !== ambientColorIntensity[0] ||\n                this._lastAmbientColor[1] !== ambientColorIntensity[1] ||\n                this._lastAmbientColor[2] !== ambientColorIntensity[2] ||\n                this._lastAmbientColor[3] !== ambientColorIntensity[3]) {\n                canvas.backgroundColor = ambientColorIntensity;\n                if (!this._lastAmbientColor) {\n                    this._lastAmbientColor = math.vec4([0, 0, 0, 1]);\n                }\n                this._lastAmbientColor.set(ambientColorIntensity);\n            }\n        } else {\n            this._lastAmbientColor = null;\n        }\n    }\n\n    /**\n     * Gets the IDs of the {@link Entity}s in {@link Scene#models}.\n     *\n     * @type {String[]}\n     */\n    get modelIds() {\n        if (!this._modelIds) {\n            this._modelIds = Object.keys(this.models);\n        }\n        return this._modelIds;\n    }\n\n    /**\n     * Gets the number of {@link Entity}s in {@link Scene#objects}.\n     *\n     * @type {Number}\n     */\n    get numObjects() {\n        return this._numObjects;\n    }\n\n    /**\n     * Gets the IDs of the {@link Entity}s in {@link Scene#objects}.\n     *\n     * @type {String[]}\n     */\n    get objectIds() {\n        if (!this._objectIds) {\n            this._objectIds = Object.keys(this.objects);\n        }\n        return this._objectIds;\n    }\n\n    /**\n     * Gets the number of {@link Entity}s in {@link Scene#visibleObjects}.\n     *\n     * @type {Number}\n     */\n    get numVisibleObjects() {\n        return this._numVisibleObjects;\n    }\n\n    /**\n     * Gets the IDs of the {@link Entity}s in {@link Scene#visibleObjects}.\n     *\n     * @type {String[]}\n     */\n    get visibleObjectIds() {\n        if (!this._visibleObjectIds) {\n            this._visibleObjectIds = Object.keys(this.visibleObjects);\n        }\n        return this._visibleObjectIds;\n    }\n\n    /**\n     * Gets the number of {@link Entity}s in {@link Scene#xrayedObjects}.\n     *\n     * @type {Number}\n     */\n    get numXRayedObjects() {\n        return this._numXRayedObjects;\n    }\n\n    /**\n     * Gets the IDs of the {@link Entity}s in {@link Scene#xrayedObjects}.\n     *\n     * @type {String[]}\n     */\n    get xrayedObjectIds() {\n        if (!this._xrayedObjectIds) {\n            this._xrayedObjectIds = Object.keys(this.xrayedObjects);\n        }\n        return this._xrayedObjectIds;\n    }\n\n    /**\n     * Gets the number of {@link Entity}s in {@link Scene#highlightedObjects}.\n     *\n     * @type {Number}\n     */\n    get numHighlightedObjects() {\n        return this._numHighlightedObjects;\n    }\n\n    /**\n     * Gets the IDs of the {@link Entity}s in {@link Scene#highlightedObjects}.\n     *\n     * @type {String[]}\n     */\n    get highlightedObjectIds() {\n        if (!this._highlightedObjectIds) {\n            this._highlightedObjectIds = Object.keys(this.highlightedObjects);\n        }\n        return this._highlightedObjectIds;\n    }\n\n    /**\n     * Gets the number of {@link Entity}s in {@link Scene#selectedObjects}.\n     *\n     * @type {Number}\n     */\n    get numSelectedObjects() {\n        return this._numSelectedObjects;\n    }\n\n    /**\n     * Gets the IDs of the {@link Entity}s in {@link Scene#selectedObjects}.\n     *\n     * @type {String[]}\n     */\n    get selectedObjectIds() {\n        if (!this._selectedObjectIds) {\n            this._selectedObjectIds = Object.keys(this.selectedObjects);\n        }\n        return this._selectedObjectIds;\n    }\n\n    /**\n     * Gets the number of {@link Entity}s in {@link Scene#colorizedObjects}.\n     *\n     * @type {Number}\n     */\n    get numColorizedObjects() {\n        return this._numColorizedObjects;\n    }\n\n    /**\n     * Gets the IDs of the {@link Entity}s in {@link Scene#colorizedObjects}.\n     *\n     * @type {String[]}\n     */\n    get colorizedObjectIds() {\n        if (!this._colorizedObjectIds) {\n            this._colorizedObjectIds = Object.keys(this.colorizedObjects);\n        }\n        return this._colorizedObjectIds;\n    }\n\n    /**\n     * Gets the IDs of the {@link Entity}s in {@link Scene#opacityObjects}.\n     *\n     * @type {String[]}\n     */\n    get opacityObjectIds() {\n        if (!this._opacityObjectIds) {\n            this._opacityObjectIds = Object.keys(this.opacityObjects);\n        }\n        return this._opacityObjectIds;\n    }\n\n    /**\n     * Gets the IDs of the {@link Entity}s in {@link Scene#offsetObjects}.\n     *\n     * @type {String[]}\n     */\n    get offsetObjectIds() {\n        if (!this._offsetObjectIds) {\n            this._offsetObjectIds = Object.keys(this.offsetObjects);\n        }\n        return this._offsetObjectIds;\n    }\n\n    /**\n     * Sets the number of \"ticks\" that happen between each render or this Scene.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    set ticksPerRender(value) {\n        if (value === undefined || value === null) {\n            value = 1;\n        } else if (!utils.isNumeric(value) || value <= 0) {\n            this.error(\"Unsupported value for 'ticksPerRender': '\" + value +\n                \"' - should be an integer greater than zero.\");\n            value = 1;\n        }\n        if (value === this._ticksPerRender) {\n            return;\n        }\n        this._ticksPerRender = value;\n    }\n\n    /**\n     * Gets the number of \"ticks\" that happen between each render or this Scene.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    get ticksPerRender() {\n        return this._ticksPerRender;\n    }\n\n    /**\n     * Sets the number of \"ticks\" that happen between occlusion testing for {@link Marker}s.\n     *\n     * Default value is ````20````.\n     *\n     * @type {Number}\n     */\n    set ticksPerOcclusionTest(value) {\n        if (value === undefined || value === null) {\n            value = 20;\n        } else if (!utils.isNumeric(value) || value <= 0) {\n            this.error(\"Unsupported value for 'ticksPerOcclusionTest': '\" + value +\n                \"' - should be an integer greater than zero.\");\n            value = 20;\n        }\n        if (value === this._ticksPerOcclusionTest) {\n            return;\n        }\n        this._ticksPerOcclusionTest = value;\n    }\n\n    /**\n     * Gets the number of \"ticks\" that happen between each render of this Scene.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    get ticksPerOcclusionTest() {\n        return this._ticksPerOcclusionTest;\n    }\n\n    /**\n     * Sets the number of times this Scene renders per frame.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    set passes(value) {\n        if (value === undefined || value === null) {\n            value = 1;\n        } else if (!utils.isNumeric(value) || value <= 0) {\n            this.error(\"Unsupported value for 'passes': '\" + value +\n                \"' - should be an integer greater than zero.\");\n            value = 1;\n        }\n        if (value === this._passes) {\n            return;\n        }\n        this._passes = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the number of times this Scene renders per frame.\n     *\n     * Default value is ````1````.\n     *\n     * @type {Number}\n     */\n    get passes() {\n        return this._passes;\n    }\n\n    /**\n     * When {@link Scene#passes} is greater than ````1````, indicates whether or not to clear the canvas before each pass (````true````) or just before the first pass (````false````).\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set clearEachPass(value) {\n        value = !!value;\n        if (value === this._clearEachPass) {\n            return;\n        }\n        this._clearEachPass = value;\n        this.glRedraw();\n    }\n\n    /**\n     * When {@link Scene#passes} is greater than ````1````, indicates whether or not to clear the canvas before each pass (````true````) or just before the first pass (````false````).\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get clearEachPass() {\n        return this._clearEachPass;\n    }\n\n    /**\n     * Sets whether or not {@link Scene} should expect all {@link Texture}s and colors to have pre-multiplied gamma.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set gammaInput(value) {\n        value = value !== false;\n        if (value === this._renderer.gammaInput) {\n            return;\n        }\n        this._renderer.gammaInput = value;\n        this._needRecompile = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether or not {@link Scene} should expect all {@link Texture}s and colors to have pre-multiplied gamma.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get gammaInput() {\n        return this._renderer.gammaInput;\n    }\n\n    /**\n     * Sets whether or not to render pixels with pre-multiplied gama.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set gammaOutput(value) {\n        value = !!value;\n        if (value === this._renderer.gammaOutput) {\n            return;\n        }\n        this._renderer.gammaOutput = value;\n        this._needRecompile = true;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets whether or not to render pixels with pre-multiplied gama.\n     *\n     * Default value is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get gammaOutput() {\n        return this._renderer.gammaOutput;\n    }\n\n    /**\n     * Sets the gamma factor to use when {@link Scene#gammaOutput} is set true.\n     *\n     * Default value is ````2.2````.\n     *\n     * @type {Number}\n     */\n    set gammaFactor(value) {\n        value = (value === undefined || value === null) ? 2.2 : value;\n        if (value === this._renderer.gammaFactor) {\n            return;\n        }\n        this._renderer.gammaFactor = value;\n        this.glRedraw();\n    }\n\n    /**\n     * Gets the gamma factor to use when {@link Scene#gammaOutput} is set true.\n     *\n     * Default value is ````2.2````.\n     *\n     * @type {Number}\n     */\n    get gammaFactor() {\n        return this._renderer.gammaFactor;\n    }\n\n    /**\n     * Gets the default {@link Geometry} for this Scene, which is a {@link ReadableGeometry} with a unit-sized box shape.\n     *\n     * Has {@link ReadableGeometry#id} set to \"default.geometry\".\n     *\n     * {@link Mesh}s in this Scene have {@link Mesh#geometry} set to this {@link ReadableGeometry} by default.\n     *\n     * @type {ReadableGeometry}\n     */\n    get geometry() {\n        return this.components[\"default.geometry\"] || buildBoxGeometry(ReadableGeometry);\n    }\n\n    /**\n     * Gets the default {@link Material} for this Scene, which is a {@link PhongMaterial}.\n     *\n     * Has {@link PhongMaterial#id} set to \"default.material\".\n     *\n     * {@link Mesh}s in this Scene have {@link Mesh#material} set to this {@link PhongMaterial} by default.\n     *\n     * @type {PhongMaterial}\n     */\n    get material() {\n        return this.components[\"default.material\"] || new PhongMaterial(this, {\n            id: \"default.material\",\n            emissive: [0.4, 0.4, 0.4], // Visible by default on geometry without normals\n            dontClear: true\n        });\n    }\n\n    /**\n     * Gets the default xraying {@link EmphasisMaterial} for this Scene.\n     *\n     * Has {@link EmphasisMaterial#id} set to \"default.xrayMaterial\".\n     *\n     * {@link Mesh}s in this Scene have {@link Mesh#xrayMaterial} set to this {@link EmphasisMaterial} by default.\n     *\n     * {@link Mesh}s are xrayed while {@link Mesh#xrayed} is ````true````.\n     *\n     * @type {EmphasisMaterial}\n     */\n    get xrayMaterial() {\n        return this.components[\"default.xrayMaterial\"] || new EmphasisMaterial(this, {\n            id: \"default.xrayMaterial\",\n            fill: true,\n            fillColor: [0.970588207244873, 0.7965892553329468, 0.6660899519920349],\n            fillAlpha: 0.4,\n            edges: true,\n            edgeColor: [0.529411792755127, 0.4577854573726654, 0.4100345969200134],\n            edgeAlpha: 1.0,\n            edgeWidth: 1,\n            dontClear: true\n        });\n    }\n\n    /**\n     * Gets the default highlight {@link EmphasisMaterial} for this Scene.\n     *\n     * Has {@link EmphasisMaterial#id} set to \"default.highlightMaterial\".\n     *\n     * {@link Mesh}s in this Scene have {@link Mesh#highlightMaterial} set to this {@link EmphasisMaterial} by default.\n     *\n     * {@link Mesh}s are highlighted while {@link Mesh#highlighted} is ````true````.\n     *\n     * @type {EmphasisMaterial}\n     */\n    get highlightMaterial() {\n        return this.components[\"default.highlightMaterial\"] || new EmphasisMaterial(this, {\n            id: \"default.highlightMaterial\",\n            fill: true,\n            fillColor: [1.0, 1.0, 0.0],\n            fillAlpha: 0.5,\n            edges: true,\n            edgeColor: [1.0, 1.0, 1.0],\n            edgeAlpha: 1.0,\n            edgeWidth: 1,\n            dontClear: true\n        });\n    }\n\n    /**\n     * Gets the default selection {@link EmphasisMaterial} for this Scene.\n     *\n     * Has {@link EmphasisMaterial#id} set to \"default.selectedMaterial\".\n     *\n     * {@link Mesh}s in this Scene have {@link Mesh#highlightMaterial} set to this {@link EmphasisMaterial} by default.\n     *\n     * {@link Mesh}s are highlighted while {@link Mesh#highlighted} is ````true````.\n     *\n     * @type {EmphasisMaterial}\n     */\n    get selectedMaterial() {\n        return this.components[\"default.selectedMaterial\"] || new EmphasisMaterial(this, {\n            id: \"default.selectedMaterial\",\n            fill: true,\n            fillColor: [0.0, 1.0, 0.0],\n            fillAlpha: 0.5,\n            edges: true,\n            edgeColor: [1.0, 1.0, 1.0],\n            edgeAlpha: 1.0,\n            edgeWidth: 1,\n            dontClear: true\n        });\n    }\n\n    /**\n     * Gets the default {@link EdgeMaterial} for this Scene.\n     *\n     * Has {@link EdgeMaterial#id} set to \"default.edgeMaterial\".\n     *\n     * {@link Mesh}s in this Scene have {@link Mesh#edgeMaterial} set to this {@link EdgeMaterial} by default.\n     *\n     * {@link Mesh}s have their edges emphasized while {@link Mesh#edges} is ````true````.\n     *\n     * @type {EdgeMaterial}\n     */\n    get edgeMaterial() {\n        return this.components[\"default.edgeMaterial\"] || new EdgeMaterial(this, {\n            id: \"default.edgeMaterial\",\n            fill: true,\n            fillColor: [0.4, 0.4, 0.4],\n            fillAlpha: 0.2,\n            edges: true,\n            edgeColor: [0.0, 0.0, 0.0],\n            edgeAlpha: 1.0,\n            edgeWidth: 1,\n            dontClear: true\n        });\n    }\n\n    /**\n     * Gets the {@link PointsMaterial} for this Scene.\n     *\n     * @type {PointsMaterial}\n     */\n    get pointsMaterial() {\n        return this.components[\"default.pointsMaterial\"] || new PointsMaterial(this, {\n            id: \"default.pointsMaterial\",\n            fill: true,\n            fillColor: [0.4, 0.4, 0.4],\n            fillAlpha: 0.2,\n            edges: true,\n            edgeColor: [0.2, 0.2, 0.2],\n            edgeAlpha: 0.5,\n            edgeWidth: 1,\n            dontClear: true\n        });\n    }\n\n    /**\n     * Gets the {@link LinesMaterial} for this Scene.\n     *\n     * @type {LinesMaterial}\n     */\n    get linesMaterial() {\n        return this.components[\"default.linesMaterial\"] || new LinesMaterial(this, {\n            id: \"default.linesMaterial\",\n            fill: true,\n            fillColor: [0.4, 0.4, 0.4],\n            fillAlpha: 0.2,\n            edges: true,\n            edgeColor: [0.2, 0.2, 0.2],\n            edgeAlpha: 0.5,\n            edgeWidth: 1,\n            dontClear: true\n        });\n    }\n\n    /**\n     * Gets the {@link Viewport} for this Scene.\n     *\n     * @type Viewport\n     */\n    get viewport() {\n        return this._viewport;\n    }\n\n    /**\n     * Gets the {@link Camera} for this Scene.\n     *\n     * @type {Camera}\n     */\n    get camera() {\n        return this._camera;\n    }\n\n    /**\n     * Gets the World-space 3D center of this Scene.\n     *\n     *@type {Number[]}\n     */\n    get center() {\n        if (this._aabbDirty || !this._center) {\n            const aabb = this.aabb;\n            if (!this._center) {\n                this._center = math.vec3();\n            }\n            this._center[0] = (aabb[0] + aabb[3]) / 2;\n            this._center[1] = (aabb[1] + aabb[4]) / 2;\n            this._center[2] = (aabb[2] + aabb[5]) / 2;\n        }\n        return this._center;\n    }\n\n    /**\n     * Gets the World-space axis-aligned 3D boundary (AABB) of this Scene.\n     *\n     * The AABB is represented by a six-element Float64Array containing the min/max extents of the axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.\n     *\n     * When the Scene has no content, will be ````[-100,-100,-100,100,100,100]````.\n     *\n     * @type {Number[]}\n     */\n    get aabb() {\n        if (this._aabbDirty) {\n            if (!this._aabb) {\n                this._aabb = math.AABB3();\n            }\n            let xmin = math.MAX_DOUBLE;\n            let ymin = math.MAX_DOUBLE;\n            let zmin = math.MAX_DOUBLE;\n            let xmax = math.MIN_DOUBLE;\n            let ymax = math.MIN_DOUBLE;\n            let zmax = math.MIN_DOUBLE;\n            let aabb;\n            const collidables = this._collidables;\n            let collidable;\n            let valid = false;\n            for (const collidableId in collidables) {\n                if (collidables.hasOwnProperty(collidableId)) {\n                    collidable = collidables[collidableId];\n                    if (collidable.collidable === false) {\n                        continue;\n                    }\n                    aabb = collidable.aabb;\n                    if (aabb[0] < xmin) {\n                        xmin = aabb[0];\n                    }\n                    if (aabb[1] < ymin) {\n                        ymin = aabb[1];\n                    }\n                    if (aabb[2] < zmin) {\n                        zmin = aabb[2];\n                    }\n                    if (aabb[3] > xmax) {\n                        xmax = aabb[3];\n                    }\n                    if (aabb[4] > ymax) {\n                        ymax = aabb[4];\n                    }\n                    if (aabb[5] > zmax) {\n                        zmax = aabb[5];\n                    }\n                    valid = true;\n                }\n            }\n            if (!valid) {\n                xmin = -100;\n                ymin = -100;\n                zmin = -100;\n                xmax = 100;\n                ymax = 100;\n                zmax = 100;\n            }\n            this._aabb[0] = xmin;\n            this._aabb[1] = ymin;\n            this._aabb[2] = zmin;\n            this._aabb[3] = xmax;\n            this._aabb[4] = ymax;\n            this._aabb[5] = zmax;\n            this._aabbDirty = false;\n            this._center = null;\n        }\n        return this._aabb;\n    }\n\n    _setAABBDirty() {\n        //if (!this._aabbDirty) {\n        this._aabbDirty = true;\n        this.fire(\"boundary\");\n        // }\n    }\n\n    /**\n     * Attempts to pick an {@link Entity} in this Scene.\n     *\n     * Ignores {@link Entity}s with {@link Entity#pickable} set ````false````.\n     *\n     * When an {@link Entity} is picked, fires a \"pick\" event on the {@link Entity} with the pick result as parameters.\n     *\n     * Picking the {@link Entity} at the given canvas coordinates:\n\n     * ````javascript\n     * var pickResult = scene.pick({\n     *          canvasPos: [23, 131]\n     *       });\n     *\n     * if (pickResult) { // Picked an Entity\n     *         var entity = pickResult.entity;\n     *     }\n     * ````\n     *\n     * Picking, with a ray cast through the canvas, hits an {@link Entity}:\n     *\n     * ````javascript\n     * var pickResult = scene.pick({\n     *         pickSurface: true,\n     *         canvasPos: [23, 131]\n     *      });\n     *\n     * if (pickResult) { // Picked an Entity\n     *\n     *     var entity = pickResult.entity;\n     *\n     *     if (pickResult.primitive === \"triangle\") {\n     *\n     *         // Picked a triangle on the entity surface\n     *\n     *         var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Entity's Geometry's indices array\n     *         var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\n     *         var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\n     *         var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\n     *         var viewPos = pickResult.viewPos; // Float64Array containing the picked View-space position on the triangle\n     *         var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\n     *         var worldNormal = pickResult.worldNormal; // Float64Array containing the interpolated World-space normal vector at the picked position on the triangle\n     *         var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\n     *\n     *     } else if (pickResult.worldPos && pickResult.worldNormal) {\n     *\n     *         // Picked a point and normal on the entity surface\n     *\n     *         var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the Entity surface\n     *         var worldNormal = pickResult.worldNormal; // Float64Array containing the picked World-space normal vector on the Entity Surface\n     *     }\n     * }\n     * ````\n     *\n     * Picking the {@link Entity} that intersects an arbitrarily-aligned World-space ray:\n     *\n     * ````javascript\n     * var pickResult = scene.pick({\n     *       pickSurface: true,   // Picking with arbitrarily-positioned ray\n     *       origin: [0,0,-5],    // Ray origin\n     *       direction: [0,0,1]   // Ray direction\n     * });\n     *\n     * if (pickResult) { // Picked an Entity with the ray\n     *\n     *       var entity = pickResult.entity;\n     *\n     *       if (pickResult.primitive == \"triangle\") {\n     *\n     *          // Picked a triangle on the entity surface\n     *\n     *           var primitive = pickResult.primitive; // Type of primitive that was picked, usually \"triangles\"\n     *           var primIndex = pickResult.primIndex; // Position of triangle's first index in the picked Entity's Geometry's indices array\n     *           var indices = pickResult.indices; // UInt32Array containing the triangle's vertex indices\n     *           var localPos = pickResult.localPos; // Float64Array containing the picked Local-space position on the triangle\n     *           var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the triangle\n     *           var viewPos = pickResult.viewPos; // Float64Array containing the picked View-space position on the triangle\n     *           var bary = pickResult.bary; // Float64Array containing the picked barycentric position within the triangle\n     *           var worldNormal = pickResult.worldNormal; // Float64Array containing the interpolated World-space normal vector at the picked position on the triangle\n     *           var uv = pickResult.uv; // Float64Array containing the interpolated UV coordinates at the picked position on the triangle\n     *           var origin = pickResult.origin; // Float64Array containing the World-space ray origin\n     *           var direction = pickResult.direction; // Float64Array containing the World-space ray direction\n     *\n     *     } else if (pickResult.worldPos && pickResult.worldNormal) {\n     *\n     *         // Picked a point and normal on the entity surface\n     *\n     *         var worldPos = pickResult.worldPos; // Float64Array containing the picked World-space position on the Entity surface\n     *         var worldNormal = pickResult.worldNormal; // Float64Array containing the picked World-space normal vector on the Entity Surface\n     *     }\n     * }\n     *  ````\n     *\n     * @param {*} params Picking parameters.\n     * @param {Boolean} [params.pickSurface=false] Whether to find the picked position on the surface of the Entity.\n     * @param {Boolean} [params.pickSurfacePrecision=false] When picking an Entity surface position, indicates whether or not we want full-precision {@link PickResult#worldPos}. Only works when {@link Scene#readableGeometryEnabled} is ````true````. If pick succeeds, the returned {@link PickResult} will have {@link PickResult#precision} set ````true````, to indicate that it contains full-precision surface pick results.\n     * @param {Boolean} [params.pickSurfaceNormal=false] Whether to find the picked normal on the surface of the Entity. Only works if ````pickSurface```` is given.\n     * @param {Number[]} [params.canvasPos] Canvas-space coordinates. When ray-picking, this will override the **origin** and ** direction** parameters and will cause the ray to be fired through the canvas at this position, directly along the negative View-space Z-axis.\n     * @param {Number[]} [params.origin] World-space ray origin when ray-picking. Ignored when canvasPos given.\n     * @param {Number[]} [params.direction] World-space ray direction when ray-picking. Also indicates the length of the ray. Ignored when canvasPos given.\n     * @param {Number[]} [params.matrix] 4x4 transformation matrix to define the World-space ray origin and direction, as an alternative to ````origin```` and ````direction````.\n     * @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels.\n     * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex. Only works when `canvasPos` given.\n     * @param {boolean} [params.snapToEdge=true] Whether to snap to edge. Only works when `canvasPos` given.\n     * @param {PickResult} [pickResult] Holds the results of the pick attempt. Will use the Scene's singleton PickResult if you don't supply your own.\n     * @returns {PickResult} Holds results of the pick attempt, returned when an {@link Entity} is picked, else null. See method comments for description.\n     */\n    pick(params, pickResult) {\n\n        if (! this.canvas) {\n            this.error(\"Picking not allowed on a destroyed Scene\");\n            return null;\n        }\n\n        if (this.canvas.boundary[2] === 0 || this.canvas.boundary[3] === 0) {\n            this.error(\"Picking not allowed while canvas has zero width or height\");\n            return null;\n        }\n\n        params = params || {};\n\n        params.pickSurface = params.pickSurface || params.rayPick; // Backwards compatibility\n\n        if (!params.canvasPos && !params.matrix && (!params.origin || !params.direction)) {\n            this.warn(\"picking without canvasPos, matrix, or ray origin and direction\");\n        }\n\n        const includeEntities = params.includeEntities || params.include; // Backwards compat\n        if (includeEntities) {\n            params.includeEntityIds = getEntityIDMap(this, includeEntities);\n        }\n\n        const excludeEntities = params.excludeEntities || params.exclude; // Backwards compat\n        if (excludeEntities) {\n            params.excludeEntityIds = getEntityIDMap(this, excludeEntities);\n        }\n\n        if (this._needRecompile) {\n            this._recompile();\n            this._renderer.imageDirty();\n            this._needRecompile = false;\n        }\n\n        if (params.snapToEdge || params.snapToVertex) {\n            pickResult = this._renderer.snapPick(params, pickResult);\n        } else {\n            pickResult = this._renderer.pick(params, pickResult);\n        }\n\n        if (pickResult) {\n            if (pickResult.entity && pickResult.entity.fire) {\n                pickResult.entity.fire(\"picked\", pickResult); // TODO: SceneModelEntity doesn't fire events\n            }\n        }\n\n        return pickResult;\n    }\n\n    /**\n     * @param {Object} params Picking parameters.\n     * @param {Number[]} params.canvasPos Canvas-space coordinates.\n     * @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels\n     * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.\n     * @param {boolean} [params.snapToEdge=true] Whether to snap to edge.\n     * @deprecated\n     */\n    snapPick(params) {\n        if (! this.canvas) {\n            this.error(\"Picking not allowed on a destroyed Scene\");\n            return null;\n        }\n        if (undefined === this._warnSnapPickDeprecated) {\n            this._warnSnapPickDeprecated = true;\n            this.warn(\"Scene.snapPick() is deprecated since v2.4.2 - use Scene.pick() instead\");\n        }\n        if (!params.canvasPos) {\n            this.error(\"Scene.snapPick() canvasPos parameter expected\");\n            return;\n        }\n        return this._renderer.snapPick(params);\n    }\n\n    /**\n     * Destroys all non-default {@link Component}s in this Scene.\n     */\n    clear() {\n        var component;\n        for (const id in this.components) {\n            if (this.components.hasOwnProperty(id)) {\n                component = this.components[id];\n                if (!component._dontClear) { // Don't destroy components like Camera, Input, Viewport etc.\n                    component.destroy();\n                }\n            }\n        }\n    }\n\n    /**\n     * Destroys all {@link Light}s in this Scene..\n     */\n    clearLights() {\n        const ids = Object.keys(this.lights);\n        for (let i = 0, len = ids.length; i < len; i++) {\n            this.lights[ids[i]].destroy();\n        }\n    }\n\n    /**\n     * Destroys all {@link SectionPlane}s in this Scene.\n     */\n    clearSectionPlanes() {\n        const ids = Object.keys(this.sectionPlanes);\n        for (let i = 0, len = ids.length; i < len; i++) {\n            this.sectionPlanes[ids[i]].destroy();\n        }\n    }\n\n    /**\n     * Destroys all {@link Line}s in this Scene.\n     */\n    clearBitmaps() {\n        const ids = Object.keys(this.bitmaps);\n        for (let i = 0, len = ids.length; i < len; i++) {\n            this.bitmaps[ids[i]].destroy();\n        }\n    }\n\n\n    /**\n     * Destroys all {@link Line}s in this Scene.\n     */\n    clearLines() {\n        const ids = Object.keys(this.lineSets);\n        for (let i = 0, len = ids.length; i < len; i++) {\n            this.lineSets[ids[i]].destroy();\n        }\n    }\n\n    /**\n     * Gets the collective axis-aligned boundary (AABB) of a batch of {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * Each {@link Entity} on which {@link Entity#isObject} is registered by {@link Entity#id} in {@link Scene#visibleObjects}.\n     *\n     * Each {@link Entity} is only included in the AABB when {@link Entity#collidable} is ````true````.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @returns {[Number, Number, Number, Number, Number, Number]} An axis-aligned World-space bounding box, given as elements ````[xmin, ymin, zmin, xmax, ymax, zmax]````.\n     */\n    getAABB(ids) {\n        if (ids === undefined) {\n            return this.aabb;\n        }\n        if (utils.isString(ids)) {\n            const entity = this.objects[ids];\n            if (entity && entity.aabb) { // A Component subclass with an AABB\n                return entity.aabb;\n            }\n            ids = [ids]; // Must be an entity type\n        }\n        if (ids.length === 0) {\n            return this.aabb;\n        }\n        let xmin = math.MAX_DOUBLE;\n        let ymin = math.MAX_DOUBLE;\n        let zmin = math.MAX_DOUBLE;\n        let xmax = math.MIN_DOUBLE;\n        let ymax = math.MIN_DOUBLE;\n        let zmax = math.MIN_DOUBLE;\n        let valid;\n        this.withObjects(ids, entity => {\n                if (entity.collidable) {\n                    const aabb = entity.aabb;\n                    if (aabb[0] < xmin) {\n                        xmin = aabb[0];\n                    }\n                    if (aabb[1] < ymin) {\n                        ymin = aabb[1];\n                    }\n                    if (aabb[2] < zmin) {\n                        zmin = aabb[2];\n                    }\n                    if (aabb[3] > xmax) {\n                        xmax = aabb[3];\n                    }\n                    if (aabb[4] > ymax) {\n                        ymax = aabb[4];\n                    }\n                    if (aabb[5] > zmax) {\n                        zmax = aabb[5];\n                    }\n                    valid = true;\n                }\n            }\n        );\n        if (valid) {\n            const aabb2 = math.AABB3();\n            aabb2[0] = xmin;\n            aabb2[1] = ymin;\n            aabb2[2] = zmin;\n            aabb2[3] = xmax;\n            aabb2[4] = ymax;\n            aabb2[5] = zmax;\n            return aabb2;\n        } else {\n            return this.aabb; // Scene AABB\n        }\n    }\n\n    /**\n     * Batch-updates {@link Entity#visible} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#visible} are ````true```` is\n     * registered by {@link Entity#id} in {@link Scene#visibleObjects}.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Boolean} visible Whether or not to set visible.\n     * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n     */\n    setObjectsVisible(ids, visible) {\n        return this.withObjects(ids, entity => {\n            const changed = (entity.visible !== visible);\n            entity.visible = visible;\n            return changed;\n        });\n    }\n\n    /**\n     * Batch-updates {@link Entity#collidable} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Boolean} collidable Whether or not to set collidable.\n     * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n     */\n    setObjectsCollidable(ids, collidable) {\n        return this.withObjects(ids, entity => {\n            const changed = (entity.collidable !== collidable);\n            entity.collidable = collidable;\n            return changed;\n        });\n    }\n\n    /**\n     * Batch-updates {@link Entity#culled} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Boolean} culled Whether or not to cull.\n     * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n     */\n    setObjectsCulled(ids, culled) {\n        return this.withObjects(ids, entity => {\n            const changed = (entity.culled !== culled);\n            entity.culled = culled;\n            return changed;\n        });\n    }\n\n    /**\n     * Batch-updates {@link Entity#selected} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#selected} are ````true```` is\n     * registered by {@link Entity#id} in {@link Scene#selectedObjects}.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Boolean} selected Whether or not to select.\n     * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n     */\n    setObjectsSelected(ids, selected) {\n        return this.withObjects(ids, entity => {\n            const changed = (entity.selected !== selected);\n            entity.selected = selected;\n            return changed;\n        });\n    }\n\n    /**\n     * Batch-updates {@link Entity#highlighted} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * Each {@link Entity} on which both {@link Entity#isObject} and {@link Entity#highlighted} are ````true```` is\n     * registered by {@link Entity#id} in {@link Scene#highlightedObjects}.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Boolean} highlighted Whether or not to highlight.\n     * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n     */\n    setObjectsHighlighted(ids, highlighted) {\n        return this.withObjects(ids, entity => {\n            const changed = (entity.highlighted !== highlighted);\n            entity.highlighted = highlighted;\n            return changed;\n        });\n    }\n\n    /**\n     * Batch-updates {@link Entity#xrayed} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Boolean} xrayed Whether or not to xray.\n     * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n     */\n    setObjectsXRayed(ids, xrayed) {\n        return this.withObjects(ids, entity => {\n            const changed = (entity.xrayed !== xrayed);\n            entity.xrayed = xrayed;\n            return changed;\n        });\n    }\n\n    /**\n     * Batch-updates {@link Entity#edges} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Boolean} edges Whether or not to show edges.\n     * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n     */\n    setObjectsEdges(ids, edges) {\n        return this.withObjects(ids, entity => {\n            const changed = (entity.edges !== edges);\n            entity.edges = edges;\n            return changed;\n        });\n    }\n\n    /**\n     * Batch-updates {@link Entity#colorize} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Number[]} [colorize=(1,1,1)] RGB colorize factors, multiplied by the rendered pixel colors.\n     * @returns {Boolean} True if any {@link Entity}s were colorized, else false if all updates were redundant and not applied.\n     */\n    setObjectsColorized(ids, colorize) {\n        return this.withObjects(ids, entity => {\n            entity.colorize = colorize;\n        });\n    }\n\n    /**\n     * Batch-updates {@link Entity#opacity} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Number} [opacity=1.0] Opacity factor, multiplied by the rendered pixel alphas.\n     * @returns {Boolean} True if any {@link Entity}s changed opacity, else false if all updates were redundant and not applied.\n     */\n    setObjectsOpacity(ids, opacity) {\n        return this.withObjects(ids, entity => {\n            const changed = (entity.opacity !== opacity);\n            entity.opacity = opacity;\n            return changed;\n        });\n    }\n\n    /**\n     * Batch-updates {@link Entity#pickable} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Boolean} pickable Whether or not to set pickable.\n     * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n     */\n    setObjectsPickable(ids, pickable) {\n        return this.withObjects(ids, entity => {\n            const changed = (entity.pickable !== pickable);\n            entity.pickable = pickable;\n            return changed;\n        });\n    }\n\n    /**\n     * Batch-updates {@link Entity#offset} on {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Number[]} [offset] 3D offset vector.\n     */\n    setObjectsOffset(ids, offset) {\n        this.withObjects(ids, entity => {\n            entity.offset = offset;\n        });\n    }\n\n    /**\n     * Iterates with a callback over {@link Entity}s that represent objects.\n     *\n     * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````.\n     *\n     * @param {String[]} ids Array of {@link Entity#id} values.\n     * @param {Function} callback Callback to execute on eacn {@link Entity}.\n     * @returns {Boolean} True if any {@link Entity}s were updated, else false if all updates were redundant and not applied.\n     */\n    withObjects(ids, callback) {\n        if (utils.isString(ids)) {\n            ids = [ids];\n        }\n        let changed = false;\n        for (let i = 0, len = ids.length; i < len; i++) {\n            const id = ids[i];\n            let entity = this.objects[id];\n            if (entity) {\n                changed = callback(entity) || changed;\n            } else {\n                const modelIds = this.modelIds;\n                for (let i = 0, len = modelIds.length; i < len; i++) {\n                    const modelId = modelIds[i];\n                    const globalObjectId = math.globalizeObjectId(modelId, id);\n                    entity = this.objects[globalObjectId];\n                    if (entity) {\n                        changed = callback(entity) || changed;\n                    }\n                }\n            }\n        }\n        return changed;\n    }\n\n    /**\n     * This method will \"tickify\" the provided `cb` function.\n     *\n     * This means, the function will be wrapped so:\n     *\n     * - it runs time-aligned to scene ticks\n     * - it runs maximum once per scene-tick\n     *\n     * @param {Function} cb The function to tickify\n     * @returns {Function}\n     */\n    tickify(cb) {\n        const cbString = cb.toString();\n\n        /**\n         * Check if the function is already tickified, and if so return the cached one.\n         */\n        if (cbString in this._tickifiedFunctions) {\n            return this._tickifiedFunctions[cbString].wrapperFunc;\n        }\n\n        let alreadyRun = 0;\n        let needToRun = 0;\n\n        let lastArgs;\n\n        /**\n         * The provided `cb` function is replaced with a \"set-dirty\" function\n         *\n         * @type {Function}\n         */\n        const wrapperFunc = function (...args) {\n            lastArgs = args;\n            needToRun++;\n        };\n\n        /**\n         * An each scene tick, if the \"dirty-flag\" is set, run the `cb` function.\n         *\n         * This will make it run time-aligned to the scene tick.\n         */\n        const tickSubId = this.on(\"tick\", () => {\n            const tmp = needToRun;\n            if (tmp > alreadyRun) {\n                alreadyRun = tmp;\n                cb(...lastArgs);\n            }\n        });\n\n        /**\n         * And, store the list of subscribers.\n         */\n        this._tickifiedFunctions[cbString] = {tickSubId, wrapperFunc};\n\n        return wrapperFunc;\n    }\n\n    /**\n     * Destroys this Scene.\n     */\n    destroy() {\n\n        super.destroy();\n\n        this._removeWebglcontextlostListener();\n        // this.canvas.gl.getExtension(\"WEBGL_lose_context\").loseContext(); // disabled because of XCD-306 and XEOK-295\n\n        for (const id in this.components) {\n            if (this.components.hasOwnProperty(id)) {\n                this.components[id].destroy();\n            }\n        }\n\n        //destroy section caps separately because it's not a component\n        this._sectionCaps.destroy();\n\n        this.canvas.gl = null;\n\n        // Memory leak prevention\n        this.components = null;\n        this.models = null;\n        this.objects = null;\n        this.visibleObjects = null;\n        this.xrayedObjects = null;\n        this.highlightedObjects = null;\n        this.selectedObjects = null;\n        this.colorizedObjects = null;\n        this.opacityObjects = null;\n        this.sectionPlanes = null;\n        this.lights = null;\n        this.lightMaps = null;\n        this.reflectionMaps = null;\n        this._objectIds = null;\n        this._visibleObjectIds = null;\n        this._xrayedObjectIds = null;\n        this._highlightedObjectIds = null;\n        this._selectedObjectIds = null;\n        this._colorizedObjectIds = null;\n        this._sectionCaps = null;\n        this.types = null;\n        this.components = null;\n        this.canvas = null;\n        this._renderer = null;\n        this.input = null;\n        this._viewport = null;\n        this._camera = null;\n    }\n}\n\nconst screenPos = math.vec4();\nconst viewPos = math.vec4();\n\nconst tempVec3a$9 = math.vec3();\nconst tempVec3b$6 = math.vec3();\nconst tempVec3c$5 = math.vec3();\n\nconst tempVec4a$6 = math.vec4();\nconst tempVec4b$6 = math.vec4();\nconst tempVec4c$1 = math.vec4();\n\n/**\n * @private\n */\nclass PanController {\n\n    constructor(scene) {\n        this._scene = scene;\n    }\n\n    /**\n     * Dollys the Camera towards the given target 2D canvas position.\n     *\n     * When the target's corresponding World-space position is also provided, then this function will also test if we've\n     * dollied past the target, and will return ````true```` if that's the case.\n     *\n     * @param [optionalTargetWorldPos] Optional world position of the target\n     * @param targetCanvasPos Canvas position of the target\n     * @param dollyDelta Amount to dolly\n     * @return True if optionalTargetWorldPos was given, and we've dollied past that position.\n     */\n    dollyToCanvasPos(optionalTargetWorldPos, targetCanvasPos, dollyDelta) {\n\n        let dolliedThroughSurface = false;\n\n        const camera = this._scene.camera;\n\n        if (optionalTargetWorldPos) {\n            const eyeToWorldPosVec = math.subVec3(optionalTargetWorldPos, camera.eye, tempVec3a$9);\n            const eyeWorldPosDist = math.lenVec3(eyeToWorldPosVec);\n            dolliedThroughSurface = (eyeWorldPosDist < dollyDelta);\n        }\n\n        if (camera.projection === \"perspective\") {\n\n            camera.ortho.scale = camera.ortho.scale - dollyDelta;\n\n            const unprojectedWorldPos = this._unproject(targetCanvasPos, tempVec4a$6);\n            const offset = math.subVec3(unprojectedWorldPos, camera.eye, tempVec4c$1);\n            const moveVec = math.mulVec3Scalar(math.normalizeVec3(offset), -dollyDelta, []);\n\n            camera.eye = [camera.eye[0] - moveVec[0], camera.eye[1] - moveVec[1], camera.eye[2] - moveVec[2]];\n            camera.look = [camera.look[0] - moveVec[0], camera.look[1] - moveVec[1], camera.look[2] - moveVec[2]];\n\n            if (optionalTargetWorldPos) {\n\n                // Subtle UX tweak - if we have a target World position, then set camera eye->look distance to\n                // the same distance as from eye->target. This just gives us a better position for look,\n                // if we subsequently orbit eye about look, so that we don't orbit a position that's\n                // suddenly a lot closer than the point we pivoted about on the surface of the last object\n                // that we click-drag-pivoted on.\n\n                const eyeTargetVec = math.subVec3(optionalTargetWorldPos, camera.eye, tempVec3a$9);\n                const lenEyeTargetVec = math.lenVec3(eyeTargetVec);\n                const eyeLookVec = math.mulVec3Scalar(math.normalizeVec3(math.subVec3(camera.look, camera.eye, tempVec3b$6)), lenEyeTargetVec);\n                camera.look = [camera.eye[0] + eyeLookVec[0], camera.eye[1] + eyeLookVec[1], camera.eye[2] + eyeLookVec[2]];\n            }\n\n        } else if (camera.projection === \"ortho\") {\n\n            // - set ortho scale, getting the unprojected targetCanvasPos before and after, get that difference in a vector;\n            // - get the vector in which we're dollying;\n            // - add both vectors to camera eye and look.\n\n            const worldPos1 = this._unproject(targetCanvasPos, tempVec4a$6);\n\n            camera.ortho.scale = camera.ortho.scale - dollyDelta;\n            camera.ortho._update(); // HACK\n\n            const worldPos2 = this._unproject(targetCanvasPos, tempVec4b$6);\n            const offset = math.subVec3(worldPos2, worldPos1, tempVec4c$1);\n            const eyeLookMoveVec = math.mulVec3Scalar(math.normalizeVec3(math.subVec3(camera.look, camera.eye, tempVec3a$9)), -dollyDelta, tempVec3b$6);\n            const moveVec = math.addVec3(offset, eyeLookMoveVec, tempVec3c$5);\n\n            camera.eye = [camera.eye[0] - moveVec[0], camera.eye[1] - moveVec[1], camera.eye[2] - moveVec[2]];\n            camera.look = [camera.look[0] - moveVec[0], camera.look[1] - moveVec[1], camera.look[2] - moveVec[2]];\n        }\n\n        return dolliedThroughSurface;\n    }\n\n    _unproject(canvasPos, worldPos) {\n\n        const camera = this._scene.camera;\n        const transposedProjectMat = camera.project.transposedMatrix;\n        const Pt3 = transposedProjectMat.subarray(8, 12);\n        const Pt4 = transposedProjectMat.subarray(12);\n        const D = [0, 0, -1.0, 1];\n        const screenZ = math.dotVec4(D, Pt3) / math.dotVec4(D, Pt4);\n\n        camera.project.unproject(canvasPos, screenZ, screenPos, viewPos, worldPos);\n\n        return worldPos;\n    }\n\n    destroy() {\n    }\n}\n\nconst tempVec3a$8 = math.vec3();\nconst tempVec3b$5 = math.vec3();\nconst tempVec3c$4 = math.vec3();\n\nconst tempVec4a$5 = math.vec4();\nconst tempVec4b$5 = math.vec4();\nconst tempVec4c = math.vec4();\n\nconst TOP_LIMIT = 0.001;\nconst BOTTOM_LIMIT = Math.PI - 0.001;\n\n\n/** @private */\nclass PivotController {\n\n    /**\n     * @private\n     */\n    constructor(scene, configs) {\n\n        // Pivot math by: http://www.derschmale.com/\n\n        this._scene = scene;\n        this._configs = configs;\n        this._pivotWorldPos = math.vec3();\n        this._cameraOffset = math.vec3();\n        this._azimuth = 0;\n        this._polar = 0;\n        this._radius = 0;\n        this._pivotPosSet = false; // Initially false, true as soon as _pivotWorldPos has been set to some value\n        this._pivoting = false; // True while pivoting\n        this._shown = false;\n\n        this._pivotSphereEnabled = false;\n        this._pivotSphere = null;\n        this._pivotSphereSize = 1;\n        this._pivotSphereGeometry = null;\n        this._pivotSphereMaterial = null;\n        this._rtcCenter = math.vec3();\n        this._rtcPos = math.vec3();\n\n        this._pivotViewPos = math.vec4();\n        this._pivotProjPos = math.vec4();\n        this._pivotCanvasPos = math.vec2();\n        this._cameraDirty = true;\n\n        this._onViewMatrix = this._scene.camera.on(\"viewMatrix\", () => {\n            this._cameraDirty = true;\n        });\n\n        this._onProjMatrix = this._scene.camera.on(\"projMatrix\", () => {\n            this._cameraDirty = true;\n        });\n\n        this._onTick = this._scene.on(\"tick\", () => {\n            this.updatePivotElement();\n            this.updatePivotSphere();\n        });\n    }\n\n    createPivotSphere() {\n        const currentPos = this.getPivotPos();\n        const cameraPos = math.vec3();\n        math.decomposeMat4(math.inverseMat4(this._scene.viewer.camera.viewMatrix, math.mat4()), cameraPos, math.vec4(), math.vec3());\n        const length = math.distVec3(cameraPos, currentPos);\n        let radius = (Math.tan(Math.PI / 500) * length) * this._pivotSphereSize;\n\n        if (this._scene.camera.projection == \"ortho\") {\n            radius /= (this._scene.camera.ortho.scale / 2);\n        }\n\n        worldToRTCPos(currentPos, this._rtcCenter, this._rtcPos);\n        this._pivotSphereGeometry = new VBOGeometry(\n            this._scene,\n            buildSphereGeometry({ radius })\n        );\n        this._pivotSphere = new Mesh(this._scene, {\n            geometry: this._pivotSphereGeometry,\n            material: this._pivotSphereMaterial,\n            pickable: false,\n            position: this._rtcPos,\n            rtcCenter: this._rtcCenter\n        });\n    };\n\n    destroyPivotSphere() {\n        if (this._pivotSphere) {\n            this._pivotSphere.destroy();\n            this._pivotSphere = null;\n        }\n        if (this._pivotSphereGeometry) {\n            this._pivotSphereGeometry.destroy();\n            this._pivotSphereGeometry = null;\n        }\n    }\n\n    updatePivotElement() {\n\n        const camera = this._scene.camera;\n        const canvas = this._scene.canvas;\n\n        if (this._pivoting && this._cameraDirty) {\n\n            math.transformPoint3(camera.viewMatrix, this.getPivotPos(), this._pivotViewPos);\n            this._pivotViewPos[3] = 1;\n            math.transformPoint4(camera.projMatrix, this._pivotViewPos, this._pivotProjPos);\n\n            const canvasAABB = canvas.boundary;\n            const canvasWidth = canvasAABB[2];\n            const canvasHeight = canvasAABB[3];\n\n            this._pivotCanvasPos[0] = Math.floor((1 + this._pivotProjPos[0] / this._pivotProjPos[3]) * canvasWidth / 2);\n            this._pivotCanvasPos[1] = Math.floor((1 - this._pivotProjPos[1] / this._pivotProjPos[3]) * canvasHeight / 2);\n\n            // data-textures: avoid to do continuous DOM layout calculations            \n            let canvasBoundingRect = canvas._lastBoundingClientRect;\n\n            if (!canvasBoundingRect || canvas._canvasSizeChanged)\n            {\n                const canvasElem = canvas.canvas;\n\n                canvasBoundingRect = canvas._lastBoundingClientRect = canvasElem.getBoundingClientRect ();\n            }\n\n            if (this._pivotElement) {\n                this._pivotElement.style.left = (Math.floor(canvasBoundingRect.left + this._pivotCanvasPos[0]) - (this._pivotElement.clientWidth / 2) + window.scrollX) + \"px\";\n                this._pivotElement.style.top = (Math.floor(canvasBoundingRect.top + this._pivotCanvasPos[1]) - (this._pivotElement.clientHeight / 2) + window.scrollY) + \"px\";\n            }\n            this._cameraDirty = false;\n        }\n    }\n\n    updatePivotSphere() {\n        if (this._pivoting && this._pivotSphere) {\n            worldToRTCPos(this.getPivotPos(), this._rtcCenter, this._rtcPos);\n            if(!math.compareVec3(this._rtcPos, this._pivotSphere.position)) {\n                this.destroyPivotSphere();\n                this.createPivotSphere();\n            }\n        }\n    }\n    /**\n     * Sets the HTML DOM element that will represent the pivot position.\n     *\n     * @param pivotElement\n     */\n    setPivotElement(pivotElement) {\n        this._pivotElement = pivotElement;\n    }\n\n    /**\n     * Sets a sphere as the representation of the pivot position.\n     *\n     * @param {Object} [cfg] Sphere configuration.\n     * @param {String} [cfg.size=1] Optional size factor of the sphere. Defaults to 1.\n     * @param {String} [cfg.color=Array] Optional maretial color. Defaults to a red.\n     */\n    enablePivotSphere(cfg = {}) {\n        this.destroyPivotSphere();\n        this._pivotSphereEnabled = true;\n        if (cfg.size) {\n            this._pivotSphereSize = cfg.size;\n        }\n        const color = cfg.color || [1, 0, 0];\n        this._pivotSphereMaterial = new PhongMaterial(this._scene, {\n            emissive: color,\n            ambient: color,\n            specular: [0,0,0],\n            diffuse: [0,0,0],\n        });\n    }\n\n    /**\n     * Remove the sphere as the representation of the pivot position.\n     *\n     */\n    disablePivotSphere() {\n        this.destroyPivotSphere();\n        this._pivotSphereEnabled = false;\n    }\n\n    /**\n     * Begins pivoting.\n     */\n    startPivot() {\n\n        const camera = this._scene.camera;\n\n        let lookat = math.lookAtMat4v(camera.eye, camera.look, camera.up);\n        math.transformPoint3(lookat, this.getPivotPos(), this._cameraOffset);\n\n        const pivotPos = this.getPivotPos();\n        this._cameraOffset[2] += math.distVec3(camera.eye, pivotPos);\n\n        lookat = math.inverseMat4(lookat);\n\n        const offset = math.transformVec3(lookat, this._cameraOffset);\n        const diff = math.vec3();\n\n        math.subVec3(camera.eye, pivotPos, diff);\n        math.addVec3(diff, offset);\n\n        if (camera.zUp) {\n            const t = diff[1];\n            diff[1] = diff[2];\n            diff[2] = t;\n        }\n\n        this._radius = math.lenVec3(diff);\n        this._polar = Math.acos(diff[1] / this._radius);\n        this._azimuth = Math.atan2(diff[0], diff[2]);\n        this._pivoting = true;\n    }\n\n    _cameraLookingDownwards() { // Returns true if angle between camera viewing direction and World-space \"up\" axis is too small\n        const camera = this._scene.camera;\n        const forwardAxis = math.normalizeVec3(math.subVec3(camera.look, camera.eye, tempVec3a$8));\n        const rightAxis = math.cross3Vec3(forwardAxis, camera.worldUp, tempVec3b$5);\n        let rightAxisLen = math.sqLenVec3(rightAxis);\n        return (rightAxisLen <= 0.0001);\n    }\n\n    /**\n     * Returns true if we are currently pivoting.\n     *\n     * @returns {Boolean}\n     */\n    getPivoting() {\n        return this._pivoting;\n    }\n\n    /**\n     * Sets a 3D World-space position to pivot about.\n     *\n     * @param {Number[]} worldPos The new World-space pivot position.\n     */\n    setPivotPos(worldPos) {\n        this._pivotWorldPos.set(worldPos);\n        this._pivotPosSet = true;\n    }\n\n    /**\n     * Sets the pivot position to the 3D projection of the given 2D canvas coordinates on a sphere centered\n     * at the viewpoint. The radius of the sphere is configured via {@link CameraControl#smartPivot}.\n     *\n     *\n     * @param canvasPos\n     */\n    setCanvasPivotPos(canvasPos) {\n        const camera = this._scene.camera;\n        const pivotShereRadius = Math.abs(math.distVec3(this._scene.center, camera.eye));\n        const transposedProjectMat = camera.project.transposedMatrix;\n        const Pt3 = transposedProjectMat.subarray(8, 12);\n        const Pt4 = transposedProjectMat.subarray(12);\n        const D = [0, 0, -1.0, 1];\n        const screenZ = math.dotVec4(D, Pt3) / math.dotVec4(D, Pt4);\n        const worldPos = tempVec4a$5;\n        camera.project.unproject(canvasPos, screenZ, tempVec4b$5, tempVec4c, worldPos);\n        const eyeWorldPosVec = math.normalizeVec3(math.subVec3(worldPos, camera.eye, tempVec3a$8));\n        const posOnSphere = math.addVec3(camera.eye, math.mulVec3Scalar(eyeWorldPosVec, pivotShereRadius, tempVec3b$5), tempVec3c$4);\n        this.setPivotPos(posOnSphere);\n    }\n\n    /**\n     * Gets the current position we're pivoting about.\n     * @returns {Number[]} The current World-space pivot position.\n     */\n    getPivotPos() {\n        return (this._pivotPosSet) ? this._pivotWorldPos : this._scene.camera.look; // Avoid pivoting about [0,0,0] by default\n    }\n\n    /**\n     * Continues to pivot.\n     *\n     * @param {Number} yawInc Yaw rotation increment.\n     * @param {Number} pitchInc Pitch rotation increment.\n     */\n    continuePivot(yawInc, pitchInc) {\n        if (!this._pivoting) {\n            return;\n        }\n        if (yawInc === 0 && pitchInc === 0) {\n            return;\n        }\n        const camera = this._scene.camera;\n        var dx = -yawInc;\n        const dy = -pitchInc;\n        if (camera.worldUp[2] === 1) {\n            dx = -dx;\n        }\n        this._azimuth += -dx * .01;\n\n        const isMovingUp = dy < 0;\n        const isMovingDown = dy > 0;\n        \n        // Track if we're at limits - only check if we're very close to the limit\n        const atTopLimit = Math.abs(this._polar - TOP_LIMIT) < 0.005;\n        const atBottomLimit = Math.abs(this._polar - BOTTOM_LIMIT) < 0.005;\n        \n        let newPolar = this._polar + dy * .01;\n        \n        // Case 1: At top limit and trying to go beyond\n        if (atTopLimit && isMovingUp) {\n            newPolar = TOP_LIMIT;\n        }\n        // Case 2: At bottom limit and trying to go beyond\n        else if (atBottomLimit && isMovingDown) {\n            newPolar = BOTTOM_LIMIT;\n        }\n        // Case 3: Normal rotation or moving away from a limit\n        else {\n            newPolar = math.clamp(newPolar, TOP_LIMIT, BOTTOM_LIMIT);\n        }\n\n        this._polar = newPolar;\n\n        const pos = [\n            this._radius * Math.sin(this._polar) * Math.sin(this._azimuth),\n            this._radius * Math.cos(this._polar),\n            this._radius * Math.sin(this._polar) * Math.cos(this._azimuth)\n        ];\n        if (camera.worldUp[2] === 1) {\n            const t = pos[1];\n            pos[1] = pos[2];\n            pos[2] = t;\n        }\n        // Preserve the eye->look distance, since in xeokit \"look\" is the point-of-interest, not the direction vector.\n        const eyeLookLen = math.lenVec3(math.subVec3(camera.look, camera.eye, math.vec3()));\n        const pivotPos = this.getPivotPos();\n        math.addVec3(pos, pivotPos);\n        let lookat = math.lookAtMat4v(pos, pivotPos, camera.worldUp);\n        lookat = math.inverseMat4(lookat);\n        const offset = math.transformVec3(lookat, this._cameraOffset);\n        lookat[12] -= offset[0];\n        lookat[13] -= offset[1];\n        lookat[14] -= offset[2];\n        const zAxis = [lookat[8], lookat[9], lookat[10]];\n        camera.eye = [lookat[12], lookat[13], lookat[14]];\n        math.subVec3(camera.eye, math.mulVec3Scalar(zAxis, eyeLookLen), camera.look);\n        camera.up = [lookat[4], lookat[5], lookat[6]];\n        this.showPivot();\n    }\n\n    /**\n     * Shows the pivot position.\n     *\n     * Only works if we set an  HTML DOM element to represent the pivot position.\n     */\n    showPivot() {\n        if (this._shown) {\n            return;\n        }\n        if (this._pivotElement) {\n            this.updatePivotElement();\n            this._pivotElement.style.visibility = \"visible\";\n        }\n        if (this._pivotSphereEnabled) {\n            this.destroyPivotSphere();\n            this.createPivotSphere();\n        }\n        this._shown = true;\n    }\n\n    /**\n     * Hides the pivot position.\n     *\n     * Only works if we set an  HTML DOM element to represent the pivot position.\n     */\n    hidePivot() {\n        if (!this._shown) {\n            return;\n        }\n        if (this._pivotElement) {\n            this._pivotElement.style.visibility = \"hidden\";\n        }\n        if (this._pivotSphereEnabled) {\n            this.destroyPivotSphere();\n        }\n        this._shown = false;\n    }\n\n    /**\n     * Finishes pivoting.\n     */\n    endPivot() {\n        this._pivoting = false;\n    }\n\n    destroy() {\n        this.destroyPivotSphere();\n        this._scene.camera.off(this._onViewMatrix);\n        this._scene.camera.off(this._onProjMatrix);\n        this._scene.off(this._onTick);\n    }\n}\n\n/**\n *\n * @private\n */\nclass PickController {\n\n    constructor(cameraControl, configs) {\n        /**\n         * @type {Scene}\n         */\n        this._scene = cameraControl.scene;\n\n        this._cameraControl = cameraControl;\n\n        this._scene.canvas.canvas.oncontextmenu = function (e) {\n            e.preventDefault();\n        };\n\n        this._configs = configs;\n\n        /**\n         * Set true to schedule picking of an Entity.\n         * @type {boolean}\n         */\n        this.schedulePickEntity = false;\n\n        /**\n         * Set true to schedule picking of a position on teh surface of an Entity.\n         * @type {boolean}\n         */\n        this.schedulePickSurface = false;\n\n        /**\n         * Set true to schedule snap-picking with surface picking as a fallback - used for measurement.\n         * @type {boolean}\n         */\n        this.scheduleSnapOrPick = false;\n\n        /**\n         * The canvas position at which to do the next scheduled pick.\n         * @type {Number[]}\n         */\n        this.pickCursorPos = math.vec2();\n\n        /**\n         * Will be true after picking to indicate that something was picked.\n         * @type {boolean}\n         */\n        this.picked = false;\n\n        /**\n         * Will be true after picking to indicate that a position on the surface of an Entity was picked.\n         * @type {boolean}\n         */\n        this.pickedSurface = false;\n\n        /**\n         * Will hold the PickResult after after picking.\n         * @type {PickResult}\n         */\n        this.pickResult = null;\n\n        this._lastPickedEntityId = null;\n\n        this._lastHash = null;\n\n        this._needFireEvents = 0;\n    }\n\n    /**\n     * Immediately attempts a pick, if scheduled.\n     */\n    update() {\n\n        if (!this._configs.pointerEnabled) {\n            return;\n        }\n\n        if (!this.schedulePickEntity && !this.schedulePickSurface) {\n            return;\n        }\n\n        const hash = `${~~this.pickCursorPos[0]}-${~~this.pickCursorPos[1]}-${this.scheduleSnapOrPick}-${this.schedulePickSurface}-${this.schedulePickEntity}`;\n        if (this._lastHash === hash) {\n            return;\n        }\n\n        this.picked = false;\n        this.pickedSurface = false;\n        this.snappedOrPicked = false;\n        this.hoveredSnappedOrSurfaceOff = false;\n\n        const hasHoverSurfaceSubs = this._cameraControl.hasSubs(\"hoverSurface\");\n\n        if (this.scheduleSnapOrPick) {\n            const snapPickResult = this._scene.pick({\n                canvasPos: this.pickCursorPos,\n                snapRadius: this._configs.snapRadius,\n                snapToVertex: this._configs.snapToVertex,\n                snapToEdge: this._configs.snapToEdge,\n            });\n            if (snapPickResult && (snapPickResult.snappedToEdge || snapPickResult.snappedToVertex)) {\n                this.snapPickResult = snapPickResult;\n                this.snappedOrPicked = true;\n                this._needFireEvents++;\n            } else {\n                this.schedulePickSurface = true; // Fallback\n                this.snapPickResult = null;\n            }\n        }\n\n        if (this.schedulePickSurface) {\n            if (this.pickResult && this.pickResult.worldPos) {\n                const pickResultCanvasPos = this.pickResult.canvasPos;\n                if (pickResultCanvasPos[0] === this.pickCursorPos[0] && pickResultCanvasPos[1] === this.pickCursorPos[1]) {\n                    this.picked = true;\n                    this.pickedSurface = true;\n                    this._needFireEvents += hasHoverSurfaceSubs ? 1 : 0;\n                    this.schedulePickEntity = false;\n                    this.schedulePickSurface = false;\n                    if (this.scheduleSnapOrPick) {\n                        this.snappedOrPicked = true;\n                    } else {\n                        this.hoveredSnappedOrSurfaceOff = true;\n                    }\n                    this.scheduleSnapOrPick = false;\n                    return;\n                }\n            }\n        }\n\n        if (this.schedulePickEntity) {\n            if (this.pickResult && (this.pickResult.canvasPos || this.pickResult.snappedCanvasPos)) {\n                const pickResultCanvasPos = this.pickResult.canvasPos || this.pickResult.snappedCanvasPos;\n                if (pickResultCanvasPos[0] === this.pickCursorPos[0] && pickResultCanvasPos[1] === this.pickCursorPos[1]) {\n                    this.picked = true;\n                    this.pickedSurface = false;\n                    this.schedulePickEntity = false;\n                    this.schedulePickSurface = false;\n                    return;\n                }\n            }\n        }\n\n        if (this.schedulePickSurface || (this.scheduleSnapOrPick && !this.snapPickResult)) {\n            this.pickResult = this._scene.pick({\n                pickSurface: true,\n                pickSurfaceNormal: false,\n                canvasPos: this.pickCursorPos\n            });\n            if (this.pickResult) {\n                this.picked = true;\n                if (this.scheduleSnapOrPick) {\n                    this.snappedOrPicked = true;\n                } else {\n                    this.pickedSurface = true;\n                }\n                this._needFireEvents++;\n            } else if (this.scheduleSnapOrPick) {\n                this.hoveredSnappedOrSurfaceOff = true;\n                this._needFireEvents++;\n            }\n\n        } else { // schedulePickEntity == true\n\n            this.pickResult = this._scene.pick({\n                canvasPos: this.pickCursorPos\n            });\n\n            if (this.pickResult) {\n                this.picked = true;\n                this.pickedSurface = false;\n                this._needFireEvents++;\n            }\n        }\n\n        this.scheduleSnapOrPick = false;\n        this.schedulePickEntity = false;\n        this.schedulePickSurface = false;\n    }\n\n    fireEvents() {\n\n        if (this._needFireEvents === 0) {\n            return;\n        }\n\n        if (this.hoveredSnappedOrSurfaceOff) {\n            this._cameraControl.fire(\"hoverSnapOrSurfaceOff\", {\n                canvasPos: this.pickCursorPos,\n                pointerPos : this.pickCursorPos\n            }, true);\n        }\n\n        if (this.snappedOrPicked) {\n            if (this.snapPickResult) {\n                const pickResult = new PickResult();\n                pickResult.entity = this.snapPickResult.entity;\n                pickResult.snappedToVertex = this.snapPickResult.snappedToVertex;\n                pickResult.snappedToEdge = this.snapPickResult.snappedToEdge;\n                pickResult.worldPos = this.snapPickResult.worldPos;\n                pickResult.canvasPos = this.pickCursorPos;\n                pickResult.snappedCanvasPos = this.snapPickResult.snappedCanvasPos;\n                this._cameraControl.fire(\"hoverSnapOrSurface\", pickResult, true);\n                this.snapPickResult = null;\n            } else {\n                this._cameraControl.fire(\"hoverSnapOrSurface\", this.pickResult, true);\n            }\n        }\n\n        if (this.picked && this.pickResult && (this.pickResult.entity || this.pickResult.worldPos)) {\n\n            if (this.pickResult.entity) {\n\n                const pickedEntityId = this.pickResult.entity.id;\n\n                if (this._lastPickedEntityId !== pickedEntityId) {\n\n                    if (this._lastPickedEntityId !== undefined) {\n                        this._cameraControl.fire(\"hoverOut\", {\n                            entity: this._scene.objects[this._lastPickedEntityId]\n                        }, true);\n                    }\n\n                    this._cameraControl.fire(\"hoverEnter\", this.pickResult, true);\n                    this._lastPickedEntityId = pickedEntityId;\n                }\n            }\n\n            this._cameraControl.fire(\"hover\", this.pickResult, true);\n\n            if (this.pickResult.worldPos) {\n                this.pickedSurface = true;\n                this._cameraControl.fire(\"hoverSurface\", this.pickResult, true);\n            }\n\n        } else {\n\n            if (this._lastPickedEntityId !== undefined) {\n                this._cameraControl.fire(\"hoverOut\", {\n                    entity: this._scene.objects[this._lastPickedEntityId]\n                }, true);\n                this._lastPickedEntityId = undefined;\n            }\n\n            this._cameraControl.fire(\"hoverOff\", {\n                canvasPos: this.pickCursorPos\n            }, true);\n        }\n\n        this.pickResult = null;\n\n        this._needFireEvents = 0;\n    }\n}\n\n/**\n * @private\n */\n\nconst canvasPos = math.vec2();\n\nconst getCanvasPosFromEvent$3 = function(event, canvas, canvasPos) {\n    if (!event) {\n        event = window.event;\n        canvasPos[0] = event.x;\n        canvasPos[1] = event.y;\n    } else {\n        const canvasRect = canvas.getBoundingClientRect();\n        canvasPos[0] = event.clientX - canvasRect.left;\n        canvasPos[1] = event.clientY - canvasRect.top;\n    }\n    return canvasPos;\n};\n\n/**\n * @private\n */\nclass MousePanRotateDollyHandler {\n\n    constructor(scene, controllers, configs, states, updates) {\n\n        this._scene = scene;\n\n        const pickController = controllers.pickController;\n        const cameraControl = controllers.cameraControl;\n\n        let lastX = 0;\n        let lastY = 0;\n        let lastXDown = 0;\n        let lastYDown = 0;\n\n        let mouseDownLeft;\n        let mouseDownMiddle;\n        let mouseDownRight;\n\n        let mouseDownPicked = false;\n        const pickedWorldPos = math.vec3();\n\n        let mouseMovedOnCanvasSinceLastWheel = true;\n\n        const canvas = this._scene.canvas.canvas;\n\n        const keyDown = [];\n\n        document.addEventListener(\"keydown\", this._documentKeyDownHandler = (e) => {\n            if (!(configs.active && configs.pointerEnabled) || (!scene.input.keyboardEnabled)) {\n                return;\n            }\n            const keyCode = e.keyCode;\n            keyDown[keyCode] = true;\n        });\n\n        document.addEventListener(\"keyup\", this._documentKeyUpHandler = (e) => {\n            if (!(configs.active && configs.pointerEnabled) || (!scene.input.keyboardEnabled)) {\n                return;\n            }\n            const keyCode = e.keyCode;\n            keyDown[keyCode] = false;\n        });\n\n        document.addEventListener(\"visibilitychange\", this._onVisibilityChange = () => {\n            keyDown.splice(0);\n        });\n\n        window.addEventListener(\"blur\", this._onBlur = () => {\n            keyDown.splice(0);\n        });\n\n        function setMousedownState(pick = true) {\n            setMousedownPositions();\n            if (pick) {\n                setMousedownPick();\n            }\n        }\n\n        function setMousedownPositions() {\n\n            lastX = states.pointerCanvasPos[0];\n            lastY = states.pointerCanvasPos[1];\n            lastXDown = states.pointerCanvasPos[0];\n            lastYDown = states.pointerCanvasPos[1];\n        }\n\n        function setMousedownPick() {\n            pickController.pickCursorPos = states.pointerCanvasPos;\n            pickController.schedulePickSurface = true;\n            pickController.update();\n\n            if (pickController.picked && pickController.pickedSurface && pickController.pickResult && pickController.pickResult.worldPos) {\n                mouseDownPicked = true;\n                pickedWorldPos.set(pickController.pickResult.worldPos);\n            } else {\n                mouseDownPicked = false;\n            }\n        }\n\n        function isPanning() {\n            return configs.planView || cameraControl._isKeyDownForAction(cameraControl.MOUSE_PAN, keyDown);\n        }\n\n        function isRotating() {\n            return cameraControl._isKeyDownForAction(cameraControl.MOUSE_ROTATE, keyDown);\n        }\n\n\n        canvas.addEventListener(\"mousedown\", this._mouseDownHandler = (e) => {\n\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n\n            switch (e.which) {\n\n                case 1: // Left button\n\n                    if (keyDown[scene.input.KEY_SHIFT] || configs.planView) {\n\n                        mouseDownLeft = true;\n                        keyDown[scene.input.MOUSE_LEFT_BUTTON] = true;\n\n                        setMousedownState();\n\n                    } else {\n\n                        mouseDownLeft = true;\n                        keyDown[scene.input.MOUSE_LEFT_BUTTON] = true;\n\n                        setMousedownState(false);\n                    }\n\n                    break;\n\n                case 2: // Middle/both buttons\n\n                    mouseDownMiddle = true;\n                    keyDown[scene.input.MOUSE_MIDDLE_BUTTON] = true;\n\n                    setMousedownState();\n\n                    break;\n\n                case 3: // Right button\n\n                    mouseDownRight = true;\n                    keyDown[scene.input.MOUSE_RIGHT_BUTTON] = true;\n\n                    if (configs.panRightClick) {\n\n                        setMousedownState();\n                    }\n\n                    break;\n            }\n        });\n\n        document.addEventListener(\"mousemove\", this._documentMouseMoveHandler = (e) => {\n\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n\n            if (!mouseDownLeft && !mouseDownMiddle && !mouseDownRight) {\n                return;\n            }\n\n            // Scaling drag-rotate to canvas boundary\n\n            const canvasBoundary = scene.canvas.boundary;\n\n            const canvasWidth = canvasBoundary[2];\n            const canvasHeight = canvasBoundary[3];\n            const x = states.pointerCanvasPos[0];\n            const y = states.pointerCanvasPos[1];\n\n            const panning = isPanning();\n            const rotating = isRotating();\n\n            const xDelta = document.pointerLockElement ? e.movementX : (x - lastX);\n            const yDelta = document.pointerLockElement ? e.movementY : (y - lastY);\n\n            if (panning) {\n\n                const camera = scene.camera;\n\n                // We use only canvasHeight here so that aspect ratio does not distort speed\n\n                if (camera.projection === \"perspective\") {\n\n                    const depth = Math.abs(mouseDownPicked ? math.lenVec3(math.subVec3(pickedWorldPos, scene.camera.eye, [])) : scene.camera.eyeLookDist);\n                    const targetDistance = depth * Math.tan((camera.perspective.fov / 2) * Math.PI / 180.0);\n\n                    updates.panDeltaX += (1.5 * xDelta * targetDistance / canvasHeight);\n                    updates.panDeltaY += (1.5 * yDelta * targetDistance / canvasHeight);\n\n                } else {\n\n                    updates.panDeltaX += 0.5 * camera.ortho.scale * (xDelta / canvasHeight);\n                    updates.panDeltaY += 0.5 * camera.ortho.scale * (yDelta / canvasHeight);\n                }\n\n            } else if (rotating) {\n\n                if (!configs.planView) { // No rotating in plan-view mode\n\n                    if (configs.firstPerson) {\n                        updates.rotateDeltaY -= (xDelta / canvasWidth) * configs.dragRotationRate / 2;\n                        updates.rotateDeltaX += (yDelta / canvasHeight) * (configs.dragRotationRate / 4);\n\n                    } else {\n                        updates.rotateDeltaY -= (xDelta / canvasWidth) * (configs.dragRotationRate * 1.5);\n                        updates.rotateDeltaX += (yDelta / canvasHeight) * (configs.dragRotationRate * 1.5);\n                    }\n                }\n            }\n\n            lastX = x;\n            lastY = y;\n        });\n\n        canvas.addEventListener(\"mousemove\", this._canvasMouseMoveHandler = (e) => {\n\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n\n            if (!states.mouseover) {\n                return;\n            }\n\n            mouseMovedOnCanvasSinceLastWheel = true;\n        });\n\n        document.addEventListener(\"mouseup\", this._documentMouseUpHandler = (e) => {\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n            switch (e.which) {\n                case 1: // Left button\n                    mouseDownLeft = false;\n                    mouseDownMiddle = false;\n                    mouseDownRight = false;\n                    keyDown[scene.input.MOUSE_LEFT_BUTTON] = false;\n                    keyDown[scene.input.MOUSE_MIDDLE_BUTTON] = false;\n                    keyDown[scene.input.MOUSE_RIGHT_BUTTON] = false;\n                    break;\n                case 2: // Middle/both buttons\n                    mouseDownLeft = false;\n                    mouseDownMiddle = false;\n                    mouseDownRight = false;\n                    keyDown[scene.input.MOUSE_LEFT_BUTTON] = false;\n                    keyDown[scene.input.MOUSE_MIDDLE_BUTTON] = false;\n                    keyDown[scene.input.MOUSE_RIGHT_BUTTON] = false;\n                    break;\n                case 3: // Right button\n                    mouseDownLeft = false;\n                    mouseDownMiddle = false;\n                    mouseDownRight = false;\n                    keyDown[scene.input.MOUSE_LEFT_BUTTON] = false;\n                    keyDown[scene.input.MOUSE_MIDDLE_BUTTON] = false;\n                    keyDown[scene.input.MOUSE_RIGHT_BUTTON] = false;\n                    break;\n            }\n        });\n\n        canvas.addEventListener(\"mouseup\", this._mouseUpHandler = (e) => {\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n            switch (e.which) {\n                case 3: // Right button\n                    getCanvasPosFromEvent$3(e, canvas, canvasPos);\n                    const x = canvasPos[0];\n                    const y = canvasPos[1];\n                    if (Math.abs(x - lastXDown) < 3 && Math.abs(y - lastYDown) < 3) {\n                        controllers.cameraControl.fire(\"rightClick\", { // For context menus\n                            pagePos: [Math.round(e.pageX), Math.round(e.pageY)],\n                            canvasPos: canvasPos,\n                            event: e\n                        }, true);\n                    }\n                    break;\n            }\n            canvas.style.removeProperty(\"cursor\");\n        });\n\n        canvas.addEventListener(\"mouseenter\", this._mouseEnterHandler = () => {\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n        });\n\n        const maxElapsed = 1 / 20;\n        const minElapsed = 1 / 60;\n\n        let secsNowLast = null;\n\n        canvas.addEventListener(\"wheel\", this._mouseWheelHandler = (e) => {\n            if (!(configs.active && configs.pointerEnabled && configs.zoomOnMouseWheel && cameraControl._isKeyDownForAction(cameraControl.MOUSE_DOLLY, keyDown))) {\n                return;\n            }\n            const secsNow = performance.now() / 1000.0;\n            var secsElapsed = (secsNowLast !== null) ? (secsNow - secsNowLast) : 0;\n            secsNowLast = secsNow;\n            if (secsElapsed > maxElapsed) {\n                secsElapsed = maxElapsed;\n            }\n            if (secsElapsed < minElapsed) {\n                secsElapsed = minElapsed;\n            }\n            const delta = Math.max(-1, Math.min(1, -e.deltaY * 40));\n            if (delta === 0) {\n                return;\n            }\n            const normalizedDelta = delta / Math.abs(delta);\n            updates.dollyDelta += -normalizedDelta * secsElapsed * configs.mouseWheelDollyRate;\n\n            if (mouseMovedOnCanvasSinceLastWheel) {\n                if ((states.pointerCanvasPos[0] === 0) && (states.pointerCanvasPos[1] === 0)) {\n                    // Dirty fix to initiate states.pointerCanvasPos if a wheel over an empty space is the first action in a scene\n                    getCanvasPosFromEvent$3(e, canvas, states.pointerCanvasPos); // Added to fix XCD-386: The zoom speed slows down when zooming into an empty space for the first time on a relatively large model, and it cannot be reset without reloading\n                }\n                states.followPointerDirty = true;\n                mouseMovedOnCanvasSinceLastWheel = false;\n            }\n\n        }, {passive: true});\n    }\n\n    reset() {\n    }\n\n    destroy() {\n\n        const canvas = this._scene.canvas.canvas;\n\n        document.removeEventListener(\"keydown\", this._documentKeyDownHandler);\n        document.removeEventListener(\"keyup\", this._documentKeyUpHandler);\n        document.removeEventListener(\"visibilitychange\", this._onVisibilityChange);\n        window.removeEventListener(\"blur\", this._onBlur);\n        canvas.removeEventListener(\"mousedown\", this._mouseDownHandler);\n        document.removeEventListener(\"mousemove\", this._documentMouseMoveHandler);\n        canvas.removeEventListener(\"mousemove\", this._canvasMouseMoveHandler);\n        document.removeEventListener(\"mouseup\", this._documentMouseUpHandler);\n        canvas.removeEventListener(\"mouseup\", this._mouseUpHandler);\n        canvas.removeEventListener(\"mouseenter\", this._mouseEnterHandler);\n        canvas.removeEventListener(\"wheel\", this._mouseWheelHandler);\n    }\n}\n\nconst center = math.vec3();\nconst tempVec3a$7 = math.vec3();\nconst tempVec3b$4 = math.vec3();\nconst tempVec3c$3 = math.vec3();\nconst tempVec3d = math.vec3();\n\nconst tempCameraTarget = {\n    eye: math.vec3(),\n    look: math.vec3(),\n    up: math.vec3()\n};\n\n/**\n * @private\n */\nclass KeyboardAxisViewHandler {\n\n    constructor(scene, controllers, configs, states) {\n\n        this._scene = scene;\n        const cameraControl = controllers.cameraControl;\n        const camera = scene.camera;\n\n        this._onSceneKeyDown = scene.input.on(\"keydown\", () => {\n\n            if (!(configs.active && configs.pointerEnabled) || (!scene.input.keyboardEnabled)) {\n                return;\n            }\n\n            if (configs.keyboardEnabledOnlyIfMouseover && !states.mouseover) {\n                return;\n            }\n\n            const axisViewRight = cameraControl._isKeyDownForAction(cameraControl.AXIS_VIEW_RIGHT);\n            const axisViewBack = cameraControl._isKeyDownForAction(cameraControl.AXIS_VIEW_BACK);\n            const axisViewLeft = cameraControl._isKeyDownForAction(cameraControl.AXIS_VIEW_LEFT);\n            const axisViewFront = cameraControl._isKeyDownForAction(cameraControl.AXIS_VIEW_FRONT);\n            const axisViewTop = cameraControl._isKeyDownForAction(cameraControl.AXIS_VIEW_TOP);\n            const axisViewBottom = cameraControl._isKeyDownForAction(cameraControl.AXIS_VIEW_BOTTOM);\n\n            if ((!axisViewRight) && (!axisViewBack) && (!axisViewLeft) && (!axisViewFront) && (!axisViewTop) && (!axisViewBottom)) {\n                return;\n            }\n\n            const aabb = scene.aabb;\n            const diag = math.getAABB3Diag(aabb);\n\n            math.getAABB3Center(aabb, center);\n\n            const perspectiveDist = Math.abs(diag / Math.tan(controllers.cameraFlight.fitFOV * math.DEGTORAD));\n            const orthoScale = diag * 1.1;\n\n            tempCameraTarget.orthoScale = orthoScale;\n\n            if (axisViewRight) {\n\n                tempCameraTarget.eye.set(math.addVec3(center, math.mulVec3Scalar(camera.worldRight, perspectiveDist, tempVec3a$7), tempVec3d));\n                tempCameraTarget.look.set(center);\n                tempCameraTarget.up.set(camera.worldUp);\n\n            } else if (axisViewBack) {\n\n                tempCameraTarget.eye.set(math.addVec3(center, math.mulVec3Scalar(camera.worldForward, perspectiveDist, tempVec3a$7), tempVec3d));\n                tempCameraTarget.look.set(center);\n                tempCameraTarget.up.set(camera.worldUp);\n\n            } else if (axisViewLeft) {\n\n                tempCameraTarget.eye.set(math.addVec3(center, math.mulVec3Scalar(camera.worldRight, -perspectiveDist, tempVec3a$7), tempVec3d));\n                tempCameraTarget.look.set(center);\n                tempCameraTarget.up.set(camera.worldUp);\n\n            } else if (axisViewFront) {\n\n                tempCameraTarget.eye.set(math.addVec3(center, math.mulVec3Scalar(camera.worldForward, -perspectiveDist, tempVec3a$7), tempVec3d));\n                tempCameraTarget.look.set(center);\n                tempCameraTarget.up.set(camera.worldUp);\n\n            } else if (axisViewTop) {\n\n                tempCameraTarget.eye.set(math.addVec3(center, math.mulVec3Scalar(camera.worldUp, perspectiveDist, tempVec3a$7), tempVec3d));\n                tempCameraTarget.look.set(center);\n                tempCameraTarget.up.set(math.normalizeVec3(math.mulVec3Scalar(camera.worldForward, 1, tempVec3b$4), tempVec3c$3));\n\n            } else if (axisViewBottom) {\n\n                tempCameraTarget.eye.set(math.addVec3(center, math.mulVec3Scalar(camera.worldUp, -perspectiveDist, tempVec3a$7), tempVec3d));\n                tempCameraTarget.look.set(center);\n                tempCameraTarget.up.set(math.normalizeVec3(math.mulVec3Scalar(camera.worldForward, -1, tempVec3b$4)));\n            }\n\n            if ((!configs.firstPerson) && configs.followPointer) {\n                controllers.pivotController.setPivotPos(center);\n            }\n\n            if (controllers.cameraFlight.duration > 0) {\n                controllers.cameraFlight.flyTo(tempCameraTarget, () => {\n                    if (controllers.pivotController.getPivoting() && configs.followPointer) {\n                        controllers.pivotController.showPivot();\n                    }\n                });\n\n            } else {\n                controllers.cameraFlight.jumpTo(tempCameraTarget);\n                if (controllers.pivotController.getPivoting() && configs.followPointer) {\n                    controllers.pivotController.showPivot();\n                }\n            }\n        });\n    }\n\n    reset() {\n    }\n\n    destroy() {\n        this._scene.input.off(this._onSceneKeyDown);\n    }\n}\n\n/**\n * @private\n */\nclass MousePickHandler {\n\n    constructor(scene, controllers, configs, states, updates) {\n\n        this._scene = scene;\n\n        const pickController = controllers.pickController;\n        const pivotController = controllers.pivotController;\n        const cameraControl = controllers.cameraControl;\n\n        this._clicks = 0;\n        this._timeout = null;\n        this._lastPickedEntityId = null;\n        this._lastClickedWorldPos = null;\n\n        let leftDown = false;\n        let rightDown = false;\n\n        const canvas = this._scene.canvas.canvas;\n\n        const flyCameraTo = (pickResult) => {\n            let pos;\n            if (pickResult && pickResult.worldPos) {\n                pos = pickResult.worldPos;\n            }\n            const aabb = pickResult && pickResult.entity ? pickResult.entity.aabb : scene.aabb;\n            if (pos) { // Fly to look at point, don't change eye->look dist\n                const camera = scene.camera;\n                math.subVec3(camera.eye, camera.look, []);\n                controllers.cameraFlight.flyTo({\n                    // look: pos,\n                    // eye: xeokit.math.addVec3(pos, diff, []),\n                    // up: camera.up,\n                    aabb: aabb\n                });\n                // TODO: Option to back off to fit AABB in view\n            } else {// Fly to fit target boundary in view\n                controllers.cameraFlight.flyTo({\n                    aabb: aabb\n                });\n            }\n        };\n\n        const tickifiedMouseMoveFn = scene.tickify (\n            this._canvasMouseMoveHandler = (e) => {\n                if (!(configs.active && configs.pointerEnabled)) {\n                    return;\n                }\n\n                if (leftDown || rightDown) {\n                    return;\n                }\n\n                if (cameraControl.hasSubs(\"rayMove\"))\n                {\n                    const origin = math.vec3();\n                    const direction = math.vec3();\n                    math.canvasPosToWorldRay(scene.canvas.canvas, scene.camera.viewMatrix, scene.camera.projMatrix, scene.camera.projection, states.pointerCanvasPos, origin, direction);\n                    cameraControl.fire(\"rayMove\", { canvasPos: states.pointerCanvasPos, ray: { origin: origin, direction: direction, canvasPos: states.pointerCanvasPos } }, true);\n                }\n\n                const hoverSubs = cameraControl.hasSubs(\"hover\");\n                const hoverEnterSubs = cameraControl.hasSubs(\"hoverEnter\");\n                const hoverOutSubs = cameraControl.hasSubs(\"hoverOut\");\n                const hoverOffSubs = cameraControl.hasSubs(\"hoverOff\");\n                const hoverSurfaceSubs = cameraControl.hasSubs(\"hoverSurface\");\n                const hoverSnapOrSurfaceSubs = cameraControl.hasSubs(\"hoverSnapOrSurface\");\n\n                if (hoverSubs || hoverEnterSubs || hoverOutSubs || hoverOffSubs || hoverSurfaceSubs || hoverSnapOrSurfaceSubs) {\n\n                    pickController.pickCursorPos = states.pointerCanvasPos;\n                    pickController.schedulePickEntity = true;\n                    pickController.schedulePickSurface = hoverSurfaceSubs;\n                    pickController.scheduleSnapOrPick = hoverSnapOrSurfaceSubs;\n\n                    pickController.update();\n\n                    if (pickController.pickResult) {\n\n                        if (pickController.pickResult.entity) {\n                            const pickedEntityId = pickController.pickResult.entity.id;\n\n                            if (this._lastPickedEntityId !== pickedEntityId) {\n\n                                if (this._lastPickedEntityId !== undefined) {\n\n                                    cameraControl.fire(\"hoverOut\", { // Hovered off an entity\n                                        entity: scene.objects[this._lastPickedEntityId]\n                                    }, true);\n                                }\n\n                                cameraControl.fire(\"hoverEnter\", pickController.pickResult, true); // Hovering over a new entity\n\n                                this._lastPickedEntityId = pickedEntityId;\n                            }\n                        }\n\n                        cameraControl.fire(\"hover\", pickController.pickResult, true);\n\n                        if (pickController.pickResult.worldPos || pickController.pickResult.snappedWorldPos) { // Hovering the surface of an entity\n                            cameraControl.fire(\"hoverSurface\", pickController.pickResult, true);\n                        }\n\n                    } else {\n\n                        if (this._lastPickedEntityId !== undefined) {\n\n                            cameraControl.fire(\"hoverOut\", { // Hovered off an entity\n                                entity: scene.objects[this._lastPickedEntityId]\n                            }, true);\n\n                            this._lastPickedEntityId = undefined;\n                        }\n\n                        cameraControl.fire(\"hoverOff\", { // Not hovering on any entity\n                            canvasPos: pickController.pickCursorPos\n                        }, true);\n                    }\n                }\n            }\n        );\n\n        canvas.addEventListener(\"mousemove\", tickifiedMouseMoveFn);\n\n        canvas.addEventListener('mousedown', this._canvasMouseDownHandler = (e) => {\n\n            if (e.which === 1) {\n                leftDown = true;\n            }\n\n            if (e.which === 3) {\n                rightDown = true;\n            }\n\n            const leftButtonDown = (e.which === 1);\n\n            if (!leftButtonDown) {\n                return;\n            }\n\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n\n            // Left mouse button down to start pivoting\n\n            states.mouseDownClientX = e.clientX;\n            states.mouseDownClientY = e.clientY;\n            states.mouseDownCursorX = states.pointerCanvasPos[0];\n            states.mouseDownCursorY = states.pointerCanvasPos[1];\n\n            if ((!configs.firstPerson) && configs.followPointer) {\n\n                pickController.pickCursorPos = states.pointerCanvasPos;\n                pickController.schedulePickSurface = true;\n\n                pickController.update();\n\n                if (e.which === 1) {// Left button\n                    const pickResult = pickController.pickResult;\n                    if (pickResult && pickResult.worldPos) {\n                        pivotController.setPivotPos(pickResult.worldPos);\n                        pivotController.startPivot();\n                        this._lastClickedWorldPos = pickResult.worldPos.slice();\n                    } else {\n                        if (configs.smartPivot) {\n                            pivotController.setCanvasPivotPos(states.pointerCanvasPos);\n                        } else {\n                            if (this._lastClickedWorldPos) {\n                                pivotController.setPivotPos(this._lastClickedWorldPos);\n                            } else {\n                                pivotController.setPivotPos(scene.camera.look);\n                            }\n                        }\n                        pivotController.startPivot();\n                    }\n                }\n            }\n        });\n\n        document.addEventListener('mouseup', this._documentMouseUpHandler = (e) => {\n\n            if (e.which === 1) {\n                leftDown = false;\n            }\n\n            if (e.which === 3) {\n                rightDown = false;\n            }\n\n            if (pivotController.getPivoting()) {\n                pivotController.endPivot();\n            }\n        });\n\n        canvas.addEventListener('mouseup', this._canvasMouseUpHandler = (e) => {\n\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n\n            const leftButtonUp = (e.which === 1);\n\n            if (!leftButtonUp) {\n                return;\n            }\n\n            // Left mouse button up to possibly pick or double-pick\n\n            pivotController.hidePivot();\n\n            if (Math.abs(e.clientX - states.mouseDownClientX) > 3 || Math.abs(e.clientY - states.mouseDownClientY) > 3) {\n                return;\n            }\n\n            const pickedSubs = cameraControl.hasSubs(\"picked\");\n            const pickedNothingSubs = cameraControl.hasSubs(\"pickedNothing\");\n            const pickedSurfaceSubs = cameraControl.hasSubs(\"pickedSurface\");\n            const doublePickedSubs = cameraControl.hasSubs(\"doublePicked\");\n            const doublePickedSurfaceSubs = cameraControl.hasSubs(\"doublePickedSurface\");\n            const doublePickedNothingSubs = cameraControl.hasSubs(\"doublePickedNothing\");\n\n            if ((!configs.doublePickFlyTo) &&\n                (!doublePickedSubs) &&\n                (!doublePickedSurfaceSubs) &&\n                (!doublePickedNothingSubs)) {\n\n                //  Avoid the single/double click differentiation timeout\n\n                if (pickedSubs || pickedNothingSubs || pickedSurfaceSubs) {\n\n                    pickController.pickCursorPos = states.pointerCanvasPos;\n                    pickController.schedulePickEntity = true;\n                    pickController.schedulePickSurface = pickedSurfaceSubs;\n                    pickController.update();\n\n                    if (pickController.pickResult) {\n\n                        cameraControl.fire(\"picked\", pickController.pickResult, true);\n\n                        if (pickController.pickedSurface) {\n                            cameraControl.fire(\"pickedSurface\", pickController.pickResult, true);\n                        }\n                    } else {\n                        cameraControl.fire(\"pickedNothing\", {\n                            canvasPos: states.pointerCanvasPos\n                        }, true);\n                    }\n                }\n\n                this._clicks = 0;\n\n                return;\n            }\n\n            this._clicks++;\n\n            if (this._clicks === 1) { // First click\n\n                pickController.pickCursorPos = states.pointerCanvasPos;\n                pickController.schedulePickEntity = configs.doublePickFlyTo;\n                pickController.schedulePickSurface = pickedSurfaceSubs;\n                pickController.update();\n\n                const firstClickPickResult = pickController.pickResult;\n                const firstClickPickSurface = pickController.pickedSurface;\n\n                this._timeout = setTimeout(() => {\n\n                    if (firstClickPickResult) {\n\n                        cameraControl.fire(\"picked\", firstClickPickResult, true);\n\n                        if (firstClickPickSurface) {\n\n                            cameraControl.fire(\"pickedSurface\", firstClickPickResult, true);\n\n                            if ((!configs.firstPerson) && configs.followPointer) {\n                                controllers.pivotController.setPivotPos(firstClickPickResult.worldPos);\n                                if (controllers.pivotController.startPivot()) {\n                                    controllers.pivotController.showPivot();\n                                }\n                            }\n                        }\n                    } else {\n                        cameraControl.fire(\"pickedNothing\", {\n                            canvasPos: states.pointerCanvasPos\n                        }, true);\n                    }\n\n                    this._clicks = 0;\n\n                }, configs.doubleClickTimeFrame);\n\n            } else { // Second click\n\n                if (this._timeout !== null) {\n                    window.clearTimeout(this._timeout);\n                    this._timeout = null;\n                }\n\n                pickController.pickCursorPos = states.pointerCanvasPos;\n                pickController.schedulePickEntity = configs.doublePickFlyTo || doublePickedSubs || doublePickedSurfaceSubs;\n                pickController.schedulePickSurface = pickController.schedulePickEntity && doublePickedSurfaceSubs;\n                pickController.update();\n\n                if (pickController.pickResult) {\n\n                    cameraControl.fire(\"doublePicked\", pickController.pickResult, true);\n\n                    if (pickController.pickedSurface) {\n                        cameraControl.fire(\"doublePickedSurface\", pickController.pickResult, true);\n                    }\n\n                    if (configs.doublePickFlyTo) {\n\n                        flyCameraTo(pickController.pickResult);\n\n                        if ((!configs.firstPerson) && configs.followPointer) {\n\n                            const pickedEntityAABB = pickController.pickResult.entity.aabb;\n                            const pickedEntityCenterPos = math.getAABB3Center(pickedEntityAABB);\n\n                            controllers.pivotController.setPivotPos(pickedEntityCenterPos);\n\n                            if (controllers.pivotController.startPivot()) {\n                                controllers.pivotController.showPivot();\n                            }\n                        }\n                    }\n\n                } else {\n\n                    cameraControl.fire(\"doublePickedNothing\", {\n                        canvasPos: states.pointerCanvasPos\n                    }, true);\n\n                    if (configs.doublePickFlyTo) {\n\n                        flyCameraTo();\n\n                        if ((!configs.firstPerson) && configs.followPointer) {\n\n                            const sceneAABB = scene.aabb;\n                            const sceneCenterPos = math.getAABB3Center(sceneAABB);\n\n                            controllers.pivotController.setPivotPos(sceneCenterPos);\n\n                            if (controllers.pivotController.startPivot()) {\n                                controllers.pivotController.showPivot();\n                            }\n                        }\n                    }\n                }\n\n                this._clicks = 0;\n            }\n        }, false);\n    }\n\n    reset() {\n        this._clicks = 0;\n        this._lastPickedEntityId = null;\n        if (this._timeout) {\n            window.clearTimeout(this._timeout);\n            this._timeout = null;\n        }\n    }\n\n    destroy() {\n        const canvas = this._scene.canvas.canvas;\n        canvas.removeEventListener(\"mousemove\", this._canvasMouseMoveHandler);\n        canvas.removeEventListener(\"mousedown\", this._canvasMouseDownHandler);\n        document.removeEventListener(\"mouseup\", this._documentMouseUpHandler);\n        canvas.removeEventListener(\"mouseup\", this._canvasMouseUpHandler);\n        if (this._timeout) {\n            window.clearTimeout(this._timeout);\n            this._timeout = null;\n        }\n    }\n}\n\n/**\n * @private\n */\nclass KeyboardPanRotateDollyHandler {\n\n    constructor(scene, controllers, configs, states, updates) {\n\n        this._scene = scene;\n        const input = scene.input;\n\n        const keyDownMap = [];\n\n        scene.canvas.canvas;\n\n        let mouseMovedSinceLastKeyboardDolly = true;\n\n        this._onSceneMouseMove = input.on(\"mousemove\", () => {\n            mouseMovedSinceLastKeyboardDolly = true;\n        });\n\n        this._onSceneKeyDown = input.on(\"keydown\", (keyCode) => {\n            if (!(configs.active && configs.pointerEnabled) || (!scene.input.keyboardEnabled)) {\n                return;\n            }\n            if (configs.keyboardEnabledOnlyIfMouseover && !states.mouseover) {\n                return;\n            }\n            keyDownMap[keyCode] = true;\n        });\n\n        this._onSceneKeyUp = input.on(\"keyup\", (keyCode) => {\n            if (!(configs.active && configs.pointerEnabled) || (!scene.input.keyboardEnabled)) {\n                return;\n            }\n            keyDownMap[keyCode] = false;\n\n            if (controllers.pivotController.getPivoting()) {\n                controllers.pivotController.endPivot();\n            }\n        });\n\n        document.addEventListener(\"visibilitychange\", this._onVisibilityChange = () => {\n            keyDownMap.splice(0);\n        });\n\n        window.addEventListener(\"blur\", this._onBlur = () => {\n            keyDownMap.splice(0);\n        });\n\n        this._onTick = scene.on(\"tick\", (e) => {\n\n            if (!(configs.active && configs.pointerEnabled) || (!scene.input.keyboardEnabled)) {\n                return;\n            }\n\n            if (configs.keyboardEnabledOnlyIfMouseover &&  !states.mouseover) {\n                return;\n            }\n\n            const cameraControl = controllers.cameraControl;\n            const elapsedSecs = (e.deltaTime / 1000.0);\n\n            //-------------------------------------------------------------------------------------------------\n            // Keyboard rotation\n            //-------------------------------------------------------------------------------------------------\n\n            if (!configs.planView) {\n\n                const rotateYPos = cameraControl._isKeyDownForAction(cameraControl.ROTATE_Y_POS, keyDownMap);\n                const rotateYNeg = cameraControl._isKeyDownForAction(cameraControl.ROTATE_Y_NEG, keyDownMap);\n                const rotateXPos = cameraControl._isKeyDownForAction(cameraControl.ROTATE_X_POS, keyDownMap);\n                const rotateXNeg = cameraControl._isKeyDownForAction(cameraControl.ROTATE_X_NEG, keyDownMap);\n\n                const orbitDelta = elapsedSecs * configs.keyboardRotationRate;\n\n                if (rotateYPos || rotateYNeg || rotateXPos || rotateXNeg) {\n\n                    if ((!configs.firstPerson) && configs.followPointer) {\n                        controllers.pivotController.startPivot();\n                    }\n\n                    if (rotateYPos) {\n                        updates.rotateDeltaY += orbitDelta;\n\n                    } else if (rotateYNeg) {\n                        updates.rotateDeltaY -= orbitDelta;\n                    }\n\n                    if (rotateXPos) {\n                        updates.rotateDeltaX += orbitDelta;\n\n                    } else if (rotateXNeg) {\n                        updates.rotateDeltaX -= orbitDelta;\n                    }\n\n                    if ((!configs.firstPerson) && configs.followPointer) {\n                        controllers.pivotController.startPivot();\n                    }\n                }\n            }\n\n            //-------------------------------------------------------------------------------------------------\n            // Keyboard panning\n            //-------------------------------------------------------------------------------------------------\n\n            if (!keyDownMap[input.KEY_CTRL] && !keyDownMap[input.KEY_ALT]) {\n\n                const dollyBackwards = cameraControl._isKeyDownForAction(cameraControl.DOLLY_BACKWARDS, keyDownMap);\n                const dollyForwards = cameraControl._isKeyDownForAction(cameraControl.DOLLY_FORWARDS, keyDownMap);\n\n                if (dollyBackwards || dollyForwards) {\n\n                    const dollyDelta = elapsedSecs * configs.keyboardDollyRate;\n\n                    if ((!configs.firstPerson) && configs.followPointer) {\n                        controllers.pivotController.startPivot();\n                    }\n                    if (dollyForwards) {\n                        updates.dollyDelta -= dollyDelta;\n                    } else if (dollyBackwards) {\n                        updates.dollyDelta += dollyDelta;\n                    }\n\n                    if (mouseMovedSinceLastKeyboardDolly) {\n                        states.followPointerDirty = true;\n                        mouseMovedSinceLastKeyboardDolly = false;\n                    }\n                }\n            }\n\n            const panForwards = cameraControl._isKeyDownForAction(cameraControl.PAN_FORWARDS, keyDownMap);\n            const panBackwards = cameraControl._isKeyDownForAction(cameraControl.PAN_BACKWARDS, keyDownMap);\n            const panLeft = cameraControl._isKeyDownForAction(cameraControl.PAN_LEFT, keyDownMap);\n            const panRight = cameraControl._isKeyDownForAction(cameraControl.PAN_RIGHT, keyDownMap);\n            const panUp = cameraControl._isKeyDownForAction(cameraControl.PAN_UP, keyDownMap);\n            const panDown = cameraControl._isKeyDownForAction(cameraControl.PAN_DOWN, keyDownMap);\n\n            const panDelta = (keyDownMap[input.KEY_ALT] ? 0.3 : 1.0) * elapsedSecs * configs.keyboardPanRate; // ALT for slower pan rate\n\n            if (panForwards || panBackwards || panLeft || panRight || panUp || panDown) {\n\n                if ((!configs.firstPerson) && configs.followPointer) {\n                    controllers.pivotController.startPivot();\n                }\n\n                if (panDown) {\n                    updates.panDeltaY += panDelta;\n\n                } else if (panUp) {\n                    updates.panDeltaY += -panDelta;\n                }\n\n                if (panRight) {\n                    updates.panDeltaX += -panDelta;\n\n                } else if (panLeft) {\n                    updates.panDeltaX += panDelta;\n                }\n\n                if (panBackwards) {\n                    updates.panDeltaZ += panDelta;\n\n                } else if (panForwards) {\n                    updates.panDeltaZ += -panDelta;\n                }\n            }\n        });\n    }\n\n    reset() {\n    }\n\n    destroy() {\n\n        this._scene.off(this._onTick);\n\n        this._scene.input.off(this._onSceneMouseMove);\n        this._scene.input.off(this._onSceneKeyDown);\n        document.removeEventListener(\"visibilitychange\", this._onVisibilityChange);\n        window.removeEventListener(\"blur\", this._onBlur);\n        this._scene.input.off(this._onSceneKeyUp);\n    }\n}\n\nconst SCALE_DOLLY_EACH_FRAME = 1; // Recalculate dolly speed for eye->target distance on each Nth frame\nconst EPSILON = 0.001;\nconst tempVec3$3 = math.vec3();\n\n/**\n * Handles camera updates on each \"tick\" that were scheduled by the various controllers.\n *\n * @private\n */\nclass CameraUpdater {\n\n    constructor(scene, controllers, configs, states, updates) {\n\n        this._scene = scene;\n        const camera = scene.camera;\n        const pickController = controllers.pickController;\n        const pivotController = controllers.pivotController;\n        const panController = controllers.panController;\n        const cameraControl = controllers.cameraControl;\n\n        let countDown = SCALE_DOLLY_EACH_FRAME; // Decrements on each tick\n        let dollyDistFactor = 1.0; // Calculated when countDown is zero\n        let followPointerWorldPos = null; // Holds the pointer's World position when configs.followPointer is true\n        \n        this._onTick = scene.on(\"tick\", () => {\n\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n\n            let cursorType = \"default\";\n\n            //----------------------------------------------------------------------------------------------------------\n            // Dolly decay\n            //------------------------------------------------------------------------------------  ----------------------\n\n            if (Math.abs(updates.dollyDelta) < EPSILON) {\n                updates.dollyDelta = 0;\n            }\n\n            //----------------------------------------------------------------------------------------------------------\n            // Rotation decay\n            //----------------------------------------------------------------------------------------------------------\n\n            if (Math.abs(updates.rotateDeltaX) < EPSILON) {\n                updates.rotateDeltaX = 0;\n            }\n\n            if (Math.abs(updates.rotateDeltaY) < EPSILON) {\n                updates.rotateDeltaY = 0;\n            }\n\n            if (updates.rotateDeltaX !== 0 || updates.rotateDeltaY !== 0) {\n                updates.dollyDelta = 0;\n            }\n\n            //----------------------------------------------------------------------------------------------------------\n            // Dolly speed eye->look scaling\n            //\n            // If pointer is over an object, then dolly speed is proportional to the distance to that object.\n            //\n            // If pointer is not over an object, then dolly speed is proportional to the distance to the last\n            // object the pointer was over. This is so that we can dolly to structures that may have gaps through\n            // which empty background shows, that the pointer may inadvertently be over. In these cases, we don't\n            // want dolly speed wildly varying depending on how accurately the user avoids the gaps with the pointer.\n            //----------------------------------------------------------------------------------------------------------\n\n            if (configs.followPointer) {\n\n                if (--countDown <= 0) {\n\n                    countDown = SCALE_DOLLY_EACH_FRAME;\n\n                    if (updates.dollyDelta !== 0) {\n                        if (updates.rotateDeltaY === 0 && updates.rotateDeltaX === 0) {\n\n                            if (configs.followPointer && states.followPointerDirty) {\n\n                                pickController.pickCursorPos = states.pointerCanvasPos;\n                                pickController.schedulePickSurface = true;\n                                pickController.update();\n\n                                if (pickController.pickResult && pickController.pickResult.worldPos) {\n                                    followPointerWorldPos = pickController.pickResult.worldPos;\n                                    \n                                } else {\n                                    dollyDistFactor = 1.0;\n                                    followPointerWorldPos = null;\n                                }\n\n                                states.followPointerDirty = false;\n                            }\n                        }\n\n                        if (followPointerWorldPos) {\n                            const dist = Math.abs(math.lenVec3(math.subVec3(followPointerWorldPos, scene.camera.eye, tempVec3$3)));\n                            dollyDistFactor = dist / configs.dollyProximityThreshold;\n                        }\n\n                        if (dollyDistFactor < configs.dollyMinSpeed) {\n                            dollyDistFactor = configs.dollyMinSpeed;\n                        }\n                    }\n                }\n            } else {\n              dollyDistFactor = 1;\n              followPointerWorldPos = null;\n            }\n\n            const dollyDeltaForDist = (updates.dollyDelta * dollyDistFactor);\n\n            //----------------------------------------------------------------------------------------------------------\n            // Rotation\n            //----------------------------------------------------------------------------------------------------------\n\n            if (updates.rotateDeltaY !== 0 || updates.rotateDeltaX !== 0) {\n\n                if ((!configs.firstPerson) && configs.followPointer && pivotController.getPivoting()) {\n                    pivotController.continuePivot(updates.rotateDeltaY, updates.rotateDeltaX);\n                    pivotController.showPivot();\n\n                } else {\n\n                    if (updates.rotateDeltaX !== 0) {\n                        if (configs.firstPerson) {\n                            camera.pitch(-updates.rotateDeltaX);\n                        } else {\n                            camera.orbitPitch(updates.rotateDeltaX);\n                        }\n                    }\n\n                    if (updates.rotateDeltaY !== 0) {\n                        if (configs.firstPerson) {\n                            camera.yaw(updates.rotateDeltaY);\n                        } else {\n                            camera.orbitYaw(updates.rotateDeltaY);\n                        }\n                    }\n                }\n\n                updates.rotateDeltaX *= configs.rotationInertia;\n                updates.rotateDeltaY *= configs.rotationInertia;\n\n                cursorType = cameraControl._cursors.rotate;\n            }\n\n            //----------------------------------------------------------------------------------------------------------\n            // Panning\n            //----------------------------------------------------------------------------------------------------------\n\n            if (Math.abs(updates.panDeltaX) < EPSILON) {\n                updates.panDeltaX = 0;\n            }\n\n            if (Math.abs(updates.panDeltaY) < EPSILON) {\n                updates.panDeltaY = 0;\n            }\n\n            if (Math.abs(updates.panDeltaZ) < EPSILON) {\n                updates.panDeltaZ = 0;\n            }\n\n            if (updates.panDeltaX !== 0 || updates.panDeltaY !== 0 || updates.panDeltaZ !== 0) {\n\n                const vec = math.vec3();\n\n                vec[0] = updates.panDeltaX;\n                vec[1] = updates.panDeltaY;\n                vec[2] = updates.panDeltaZ;\n\n                let verticalEye;\n                let verticalLook;\n\n                if (configs.constrainVertical) {\n\n                    if (camera.xUp) {\n                        verticalEye = camera.eye[0];\n                        verticalLook = camera.look[0];\n                    } else if (camera.yUp) {\n                        verticalEye = camera.eye[1];\n                        verticalLook = camera.look[1];\n                    } else if (camera.zUp) {\n                        verticalEye = camera.eye[2];\n                        verticalLook = camera.look[2];\n                    }\n\n                    camera.pan(vec);\n\n                    const eye = camera.eye;\n                    const look = camera.look;\n\n                    if (camera.xUp) {\n                        eye[0] = verticalEye;\n                        look[0] = verticalLook;\n                    } else if (camera.yUp) {\n                        eye[1] = verticalEye;\n                        look[1] = verticalLook;\n                    } else if (camera.zUp) {\n                        eye[2] = verticalEye;\n                        look[2] = verticalLook;\n                    }\n\n                    camera.eye = eye;\n                    camera.look = look;\n\n                } else {\n                    camera.pan(vec);\n                }\n\n                cursorType = cameraControl._cursors.pan;\n            }\n\n            updates.panDeltaX *= configs.panInertia;\n            updates.panDeltaY *= configs.panInertia;\n            updates.panDeltaZ *= configs.panInertia;\n\n            //----------------------------------------------------------------------------------------------------------\n            // Dollying\n            //----------------------------------------------------------------------------------------------------------\n\n            if (dollyDeltaForDist !== 0) {\n\n                if (dollyDeltaForDist < 0) {\n                    cursorType = cameraControl._cursors.dollyForward;\n                } else {\n                    cursorType = cameraControl._cursors.dollyBackward;\n                }\n\n                if (configs.firstPerson) {\n\n                    let verticalEye;\n                    let verticalLook;\n\n                    if (configs.constrainVertical) {\n                        if (camera.xUp) {\n                            verticalEye = camera.eye[0];\n                            verticalLook = camera.look[0];\n                        } else if (camera.yUp) {\n                            verticalEye = camera.eye[1];\n                            verticalLook = camera.look[1];\n                        } else if (camera.zUp) {\n                            verticalEye = camera.eye[2];\n                            verticalLook = camera.look[2];\n                        }\n                    }\n\n                    if (configs.followPointer) {\n                        const dolliedThroughSurface = panController.dollyToCanvasPos(followPointerWorldPos, states.pointerCanvasPos, -dollyDeltaForDist);\n                        if (dolliedThroughSurface) {\n                            states.followPointerDirty = true;\n                        }\n                    } else {\n                        camera.pan([0, 0, dollyDeltaForDist]);\n                        camera.ortho.scale = camera.ortho.scale - dollyDeltaForDist;\n                    }\n\n                    if (configs.constrainVertical) {\n                        const eye = camera.eye;\n                        const look = camera.look;\n                        if (camera.xUp) {\n                            eye[0] = verticalEye;\n                            look[0] = verticalLook;\n                        } else if (camera.yUp) {\n                            eye[1] = verticalEye;\n                            look[1] = verticalLook;\n                        } else if (camera.zUp) {\n                            eye[2] = verticalEye;\n                            look[2] = verticalLook;\n                        }\n                        camera.eye = eye;\n                        camera.look = look;\n                    }\n\n                } else if (configs.planView) {\n\n                    if (configs.followPointer) {\n                        const dolliedThroughSurface = panController.dollyToCanvasPos(followPointerWorldPos, states.pointerCanvasPos, -dollyDeltaForDist);\n                        if (dolliedThroughSurface) {\n                            states.followPointerDirty = true;\n                        }\n                    } else {\n                        camera.ortho.scale = camera.ortho.scale + dollyDeltaForDist;\n                        camera.zoom(dollyDeltaForDist);\n                    }\n\n                } else { // Orbiting\n\n                    if (configs.followPointer) {\n                        const dolliedThroughSurface = panController.dollyToCanvasPos(followPointerWorldPos, states.pointerCanvasPos, -dollyDeltaForDist);\n                        if (dolliedThroughSurface) {\n                            states.followPointerDirty = true;\n                        }\n                    } else {\n                        camera.ortho.scale = camera.ortho.scale + dollyDeltaForDist;\n                        camera.zoom(dollyDeltaForDist);\n                    }\n                }\n\n                updates.dollyDelta *= configs.dollyInertia;\n            }\n\n            pickController.fireEvents();\n\n            document.body.style.cursor = cursorType;\n        });\n    }\n\n\n    destroy() {\n        this._scene.off(this._onTick);\n    }\n}\n\n/**\n * @private\n */\nclass MouseMiscHandler {\n\n    constructor(scene, controllers, configs, states, updates) {\n\n        this._scene = scene;\n\n        const canvas = this._scene.canvas.canvas;\n\n        canvas.addEventListener(\"mouseenter\", this._mouseEnterHandler = () => {\n            states.mouseover = true;\n        });\n\n        canvas.addEventListener(\"mouseleave\", this._mouseLeaveHandler = () => {\n            states.mouseover = false;\n            canvas.style.cursor = null;\n        });\n\n        document.addEventListener(\"mousemove\", this._mouseMoveHandler = (e) => {\n            getCanvasPosFromEvent$2(e, canvas, states.pointerCanvasPos);\n            states.mouseover = true; // Added to fix XCD-386: The zoom speed slows down when zooming into an empty space for the first time on a relatively large model, and it cannot be reset without reloading\n        });\n\n        canvas.addEventListener(\"mousedown\", this._mouseDownHandler = (e) => {\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n            getCanvasPosFromEvent$2(e, canvas, states.pointerCanvasPos);\n            states.mouseover = true;\n        });\n\n        canvas.addEventListener(\"mouseup\", this._mouseUpHandler = (e) => {\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n        });\n    }\n\n    reset() {\n    }\n\n    destroy() {\n\n        const canvas = this._scene.canvas.canvas;\n\n        document.removeEventListener(\"mousemove\", this._mouseMoveHandler);\n        canvas.removeEventListener(\"mouseenter\", this._mouseEnterHandler);\n        canvas.removeEventListener(\"mouseleave\", this._mouseLeaveHandler);\n        canvas.removeEventListener(\"mousedown\", this._mouseDownHandler);\n        canvas.removeEventListener(\"mouseup\", this._mouseUpHandler);\n    }\n}\n\nfunction getCanvasPosFromEvent$2(event, canvas, canvasPos) {\n    if (!event) {\n        event = window.event;\n        canvasPos[0] = event.x;\n        canvasPos[1] = event.y;\n    } else {\n        const { left, top } = canvas.getBoundingClientRect();\n        canvasPos[0] = event.clientX - left;\n        canvasPos[1] = event.clientY - top;\n    }\n    return canvasPos;\n}\n\nconst getCanvasPosFromEvent$1 = function(event, canvas, canvasPos) {\n    if (!event) {\n        event = window.event;\n        canvasPos[0] = event.x;\n        canvasPos[1] = event.y;\n    } else {\n        const canvasRect = canvas.getBoundingClientRect();\n        canvasPos[0] = event.clientX - canvasRect.left;\n        canvasPos[1] = event.clientY - canvasRect.top;\n    }\n    return canvasPos;\n};\n\n/**\n * @private\n */\nclass TouchPanRotateAndDollyHandler {\n\n    constructor(scene, controllers, configs, states, updates) {\n\n        this._scene = scene;\n\n        const pickController = controllers.pickController;\n        const pivotController = controllers.pivotController;\n\n        const tapStartCanvasPos = math.vec2();\n        const tapCanvasPos0 = math.vec2();\n        const tapCanvasPos1 = math.vec2();\n        const touch0Vec = math.vec2();\n\n        const lastCanvasTouchPosList = [];\n        const canvas = this._scene.canvas.canvas;\n\n        let numTouches = 0;\n        let waitForTick = false;\n\n        this._onTick = scene.on(\"tick\", () => {\n            waitForTick = false;\n        });\n\n        canvas.addEventListener(\"touchstart\", this._canvasTouchStartHandler = (event) => {\n\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n\n            event.preventDefault();\n\n            const touches = event.touches;\n            const changedTouches = event.changedTouches;\n\n            states.touchStartTime = Date.now();\n\n            if (touches.length === 1 && changedTouches.length === 1) {\n\n                getCanvasPosFromEvent$1(touches[0], canvas, tapStartCanvasPos);\n\n                if (configs.followPointer) {\n\n                    pickController.pickCursorPos = tapStartCanvasPos;\n                    pickController.schedulePickSurface = true;\n                    pickController.update();\n\n                    if (!configs.planView) {\n\n                        if (pickController.picked && pickController.pickedSurface && pickController.pickResult && pickController.pickResult.worldPos) {\n\n                            pivotController.setPivotPos(pickController.pickResult.worldPos);\n\n                            if (!configs.firstPerson && pivotController.startPivot()) {\n                                pivotController.showPivot();\n                            }\n\n                        } else {\n\n                            if (configs.smartPivot) {\n                                pivotController.setCanvasPivotPos(states.pointerCanvasPos);\n                            } else {\n                                pivotController.setPivotPos(scene.camera.look);\n                            }\n\n                            if (!configs.firstPerson && pivotController.startPivot()) {\n                                pivotController.showPivot();\n                            }\n                        }\n                    }\n                }\n\n            }\n\n            while (lastCanvasTouchPosList.length < touches.length) {\n                lastCanvasTouchPosList.push(math.vec2());\n            }\n\n            for (let i = 0, len = touches.length; i < len; ++i) {\n                getCanvasPosFromEvent$1(touches[i], canvas, lastCanvasTouchPosList[i]);\n            }\n\n            numTouches = touches.length;\n        });\n\n        canvas.addEventListener(\"touchend\", this._canvasTouchEndHandler = () => {\n            if (pivotController.getPivoting()) {\n                pivotController.endPivot();\n                pivotController.hidePivot();\n            }\n        });\n\n        canvas.addEventListener(\"touchmove\", this._canvasTouchMoveHandler = (event) => {\n\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n\n            event.stopPropagation();\n            event.preventDefault();\n\n            if (waitForTick) {\n                // Limit changes detection to one per frame\n                return;\n            }\n\n            waitForTick = true;\n\n            // Scaling drag-rotate to canvas boundary\n\n            const canvasBoundary = scene.canvas.boundary;\n            const canvasWidth = canvasBoundary[2];\n            const canvasHeight = canvasBoundary[3];\n\n            const touches = event.touches;\n\n            if (event.touches.length !== numTouches) {\n                // Two fingers were pressed, then one of them is removed\n                // We don't want to rotate in this case (weird behavior)\n                return;\n            }\n\n            if (numTouches === 1) {\n\n                getCanvasPosFromEvent$1(touches[0], canvas, tapCanvasPos0);\n\n                //-----------------------------------------------------------------------------------------------\n                // Drag rotation\n                //-----------------------------------------------------------------------------------------------\n\n                math.subVec2(tapCanvasPos0, lastCanvasTouchPosList[0], touch0Vec);\n\n                const xPanDelta = touch0Vec[0];\n                const yPanDelta = touch0Vec[1];\n\n                if (states.longTouchTimeout !== null && (Math.abs(xPanDelta) > configs.longTapRadius || Math.abs(yPanDelta) > configs.longTapRadius)) {\n                    clearTimeout(states.longTouchTimeout);\n                    states.longTouchTimeout = null;\n                }\n\n                if (configs.planView) { // No rotating in plan-view mode\n\n                    const camera = scene.camera;\n\n                    // We use only canvasHeight here so that aspect ratio does not distort speed\n\n                    if (camera.projection === \"perspective\") {\n\n                        const depth = Math.abs(scene.camera.eyeLookDist);\n                        const targetDistance = depth * Math.tan((camera.perspective.fov / 2) * Math.PI / 180.0);\n\n                        updates.panDeltaX += (xPanDelta * targetDistance / canvasHeight) * configs.touchPanRate;\n                        updates.panDeltaY += (yPanDelta * targetDistance / canvasHeight) * configs.touchPanRate;\n\n                    } else {\n\n                        updates.panDeltaX += 0.5 * camera.ortho.scale * (xPanDelta / canvasHeight) * configs.touchPanRate;\n                        updates.panDeltaY += 0.5 * camera.ortho.scale * (yPanDelta / canvasHeight) * configs.touchPanRate;\n                    }\n\n                } else {\n                  //  if (!absorbTinyFirstDrag) {\n                        updates.rotateDeltaY -= (xPanDelta / canvasWidth) * (configs.dragRotationRate * 1.0); // Full horizontal rotation\n                        updates.rotateDeltaX += (yPanDelta / canvasHeight) * (configs.dragRotationRate * 1.5); // Half vertical rotation\n                    // } else {\n                    //     firstDragDeltaY -= (xPanDelta / canvasWidth) * (configs.dragRotationRate * 1.0); // Full horizontal rotation\n                    //     firstDragDeltaX += (yPanDelta / canvasHeight) * (configs.dragRotationRate * 1.5); // Half vertical rotation\n                    //     if (Math.abs(firstDragDeltaX) > 5 || Math.abs(firstDragDeltaY) > 5) {\n                    //         updates.rotateDeltaX += firstDragDeltaX;\n                    //         updates.rotateDeltaY += firstDragDeltaY;\n                    //         firstDragDeltaX = 0;\n                    //         firstDragDeltaY = 0;\n                    //         absorbTinyFirstDrag = false;\n                    //     }\n                    // }\n                }\n\n            } else if (numTouches === 2) {\n\n                const touch0 = touches[0];\n                const touch1 = touches[1];\n\n                getCanvasPosFromEvent$1(touch0, canvas, tapCanvasPos0);\n                getCanvasPosFromEvent$1(touch1, canvas, tapCanvasPos1);\n\n                const lastMiddleTouch = math.geometricMeanVec2(lastCanvasTouchPosList[0], lastCanvasTouchPosList[1]);\n                const currentMiddleTouch = math.geometricMeanVec2(tapCanvasPos0, tapCanvasPos1);\n\n                const touchDelta = math.vec2();\n\n                math.subVec2(lastMiddleTouch, currentMiddleTouch, touchDelta);\n\n                const xPanDelta = touchDelta[0];\n                const yPanDelta = touchDelta[1];\n\n                const camera = scene.camera;\n\n                // Dollying\n\n                const d1 = math.distVec2([touch0.pageX, touch0.pageY], [touch1.pageX, touch1.pageY]);\n                const d2 = math.distVec2(lastCanvasTouchPosList[0], lastCanvasTouchPosList[1]);\n\n                const dollyDelta = (d2 - d1) * configs.touchDollyRate;\n\n                updates.dollyDelta = dollyDelta;\n                states.followPointerDirty = true; // Added to fix XCD-386: The zoom speed slows down when zooming into an empty space for the first time on a relatively large model, and it cannot be reset without reloading\n\n                if (Math.abs(dollyDelta) < 1.0) {\n\n                    // We use only canvasHeight here so that aspect ratio does not distort speed\n\n                    if (camera.projection === \"perspective\") {\n                        const pickedWorldPos = pickController.pickResult ? pickController.pickResult.worldPos : scene.center;\n\n                        const depth = Math.abs(math.lenVec3(math.subVec3(pickedWorldPos, scene.camera.eye, [])));\n                        const targetDistance = depth * Math.tan((camera.perspective.fov / 2) * Math.PI / 180.0);\n\n                        updates.panDeltaX -= (xPanDelta * targetDistance / canvasHeight) * configs.touchPanRate;\n                        updates.panDeltaY -= (yPanDelta * targetDistance / canvasHeight) * configs.touchPanRate;\n\n                    } else {\n\n                        updates.panDeltaX -= 0.5 * camera.ortho.scale * (xPanDelta / canvasHeight) * configs.touchPanRate;\n                        updates.panDeltaY -= 0.5 * camera.ortho.scale * (yPanDelta / canvasHeight) * configs.touchPanRate;\n                    }\n                }\n\n\n                states.pointerCanvasPos = currentMiddleTouch;\n            }\n\n            for (let i = 0; i < numTouches; ++i) {\n                getCanvasPosFromEvent$1(touches[i], canvas, lastCanvasTouchPosList[i]);\n            }\n        });\n    }\n\n    reset() {\n    }\n\n    destroy() {\n        const canvas = this._scene.canvas.canvas;\n        canvas.removeEventListener(\"touchstart\", this._canvasTouchStartHandler);\n        canvas.removeEventListener(\"touchend\", this._canvasTouchEndHandler);\n        canvas.removeEventListener(\"touchmove\", this._canvasTouchMoveHandler);\n        this._scene.off(this._onTick);\n    }\n}\n\nconst TAP_INTERVAL = 150;\nconst DBL_TAP_INTERVAL = 325;\nconst TAP_DISTANCE_THRESHOLD = 4;\n\nconst getCanvasPosFromEvent = function (event, canvasPos) {\n    if (!event) {\n        event = window.event;\n        canvasPos[0] = event.x;\n        canvasPos[1] = event.y;\n    } else {\n        let element = event.target;\n        let totalOffsetLeft = 0;\n        let totalOffsetTop = 0;\n        while (element.offsetParent) {\n            totalOffsetLeft += element.offsetLeft;\n            totalOffsetTop += element.offsetTop;\n            element = element.offsetParent;\n        }\n        canvasPos[0] = event.pageX - totalOffsetLeft;\n        canvasPos[1] = event.pageY - totalOffsetTop;\n    }\n    return canvasPos;\n};\n\n/**\n * @private\n */\nclass TouchPickHandler {\n\n    constructor(scene, controllers, configs, states, updates) {\n\n        this._scene = scene;\n\n        const pickController = controllers.pickController;\n        const cameraControl = controllers.cameraControl;\n\n        let touchStartTime;\n        const activeTouches = [];\n        const tapStartPos = new Float32Array(2);\n        let tapStartTime = -1;\n        let lastTapTime = -1;\n\n        const canvas = this._scene.canvas.canvas;\n\n        const flyCameraTo = (pickResult) => {\n            let pos;\n            if (pickResult && pickResult.worldPos) {\n                pos = pickResult.worldPos;\n            }\n            const aabb = pickResult ? pickResult.entity.aabb : scene.aabb;\n            if (pos) { // Fly to look at point, don't change eye->look dist\n                const camera = scene.camera;\n                math.subVec3(camera.eye, camera.look, []);\n                controllers.cameraFlight.flyTo({\n                    aabb: aabb\n                });\n                // TODO: Option to back off to fit AABB in view\n            } else {// Fly to fit target boundary in view\n                controllers.cameraFlight.flyTo({\n                    aabb: aabb\n                });\n            }\n        };\n\n        canvas.addEventListener(\"touchstart\", this._canvasTouchStartHandler = (e) => {\n\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n\n            if (states.longTouchTimeout !== null) {\n                clearTimeout(states.longTouchTimeout);\n                states.longTouchTimeout = null;\n            }\n\n            const touches = e.touches;\n            const changedTouches = e.changedTouches;\n\n            touchStartTime = Date.now();\n\n            if (touches.length === 1 && changedTouches.length === 1) {\n                tapStartTime = touchStartTime;\n\n                getCanvasPosFromEvent(touches[0], tapStartPos);\n\n                const rightClickClientX = tapStartPos[0];\n                const rightClickClientY = tapStartPos[1];\n\n                const rightClickPageX = touches[0].pageX;\n                const rightClickPageY = touches[0].pageY;\n\n                states.longTouchTimeout = setTimeout(() => {\n                    if (configs.active && configs.pointerEnabled) {\n                        controllers.cameraControl.fire(\"rightClick\", { // For context menus\n                            pagePos: [Math.round(rightClickPageX), Math.round(rightClickPageY)],\n                            canvasPos: [Math.round(rightClickClientX), Math.round(rightClickClientY)],\n                            event: e\n                        }, true);\n                    }\n                    states.longTouchTimeout = null;\n                }, configs.longTapTimeout);\n\n            } else {\n                tapStartTime = -1;\n            }\n\n            while (activeTouches.length < touches.length) {\n                activeTouches.push(new Float32Array(2));\n            }\n\n            for (let i = 0, len = touches.length; i < len; ++i) {\n                getCanvasPosFromEvent(touches[i], activeTouches[i]);\n            }\n\n            activeTouches.length = touches.length;\n\n        }, {passive: true});\n\n\n        canvas.addEventListener(\"touchend\", this._canvasTouchEndHandler = (e) => {\n\n            if (!(configs.active && configs.pointerEnabled)) {\n                return;\n            }\n\n            const currentTime = Date.now();\n            const touches = e.touches;\n            const changedTouches = e.changedTouches;\n\n            const pickedSurfaceSubs = cameraControl.hasSubs(\"pickedSurface\");\n\n            if (states.longTouchTimeout !== null) {\n                clearTimeout(states.longTouchTimeout);\n                states.longTouchTimeout = null;\n            }\n\n            // process tap\n\n            if (touches.length === 0 && changedTouches.length === 1) {\n\n                if (tapStartTime > -1 && currentTime - tapStartTime < TAP_INTERVAL) {\n\n                    if (lastTapTime > -1 && tapStartTime - lastTapTime < DBL_TAP_INTERVAL) {\n\n                        // Double-tap\n\n                        getCanvasPosFromEvent(changedTouches[0], pickController.pickCursorPos);\n                        pickController.schedulePickEntity = true;\n                        pickController.schedulePickSurface = pickedSurfaceSubs;\n\n                        pickController.update();\n\n                        if (pickController.pickResult) {\n\n                            pickController.pickResult.touchInput = true;\n\n                            cameraControl.fire(\"doublePicked\", pickController.pickResult);\n\n                            if (pickController.pickedSurface) {\n                                cameraControl.fire(\"doublePickedSurface\", pickController.pickResult);\n                            }\n\n                            if (configs.doublePickFlyTo) {\n                                flyCameraTo(pickController.pickResult);\n                            }\n                        } else {\n                            cameraControl.fire(\"doublePickedNothing\");\n                            if (configs.doublePickFlyTo) {\n                                flyCameraTo();\n                            }\n                        }\n\n                        lastTapTime = -1;\n\n                    } else if (math.distVec2(activeTouches[0], tapStartPos) < TAP_DISTANCE_THRESHOLD) {\n\n                        // Single-tap\n\n                        getCanvasPosFromEvent(changedTouches[0], pickController.pickCursorPos);\n                        pickController.schedulePickEntity = true;\n                        pickController.schedulePickSurface = pickedSurfaceSubs;\n\n                        pickController.update();\n\n                        if (pickController.pickResult) {\n\n                            pickController.pickResult.touchInput = true;\n\n                            cameraControl.fire(\"picked\", pickController.pickResult);\n\n                            if (pickController.pickedSurface) {\n                                cameraControl.fire(\"pickedSurface\", pickController.pickResult);\n                            }\n\n                        } else {\n                            cameraControl.fire(\"pickedNothing\");\n                        }\n\n                        lastTapTime = currentTime;\n                    }\n\n                    tapStartTime = -1;\n                }\n            }\n\n            activeTouches.length = touches.length;\n\n            for (let i = 0, len = touches.length; i < len; ++i) {\n                activeTouches[i][0] = touches[i].pageX;\n                activeTouches[i][1] = touches[i].pageY;\n            }\n\n          //  e.stopPropagation();\n\n        }, {passive: true});\n\n    }\n\n    reset() {\n        // TODO\n        // tapStartTime = -1;\n        // lastTapTime = -1;\n\n    }\n\n    destroy() {\n        const canvas = this._scene.canvas.canvas;\n        canvas.removeEventListener(\"touchstart\", this._canvasTouchStartHandler);\n        canvas.removeEventListener(\"touchend\", this._canvasTouchEndHandler);\n    }\n}\n\nconst DEFAULT_SNAP_PICK_RADIUS = 30;\nconst DEFAULT_SNAP_VERTEX = true;\nconst DEFAULT_SNAP_EDGE = true;\n\n/**\n * @desc Controls the {@link Camera} with user input, and fires events when the user interacts with pickable {@link Entity}s.\n *\n * # Contents\n *\n * * [Overview](#overview)\n * * [Examples](#examples)\n * * [Orbit Mode](#orbit-mode)\n *      + [Following the Pointer in Orbit Mode](#--following-the-pointer-in-orbit-mode--)\n *      + [Showing the Pivot Position](#--showing-the-pivot-position--)\n *      + [Axis-Aligned Views in Orbit Mode](#--axis-aligned-views-in-orbit-mode--)\n *      + [View-Fitting Entitys in Orbit Mode](#--view-fitting-entitys-in-orbit-mode--)\n * * [First-Person Mode](#first-person-mode)\n *      + [Following the Pointer in First-Person Mode](#--following-the-pointer-in-first-person-mode--)\n *      + [Constraining Vertical Position in First-Person Mode](#--constraining-vertical-position-in-first-person-mode--)\n *      + [Axis-Aligned Views in First-Person Mode](#--axis-aligned-views-in-first-person-mode--)\n *      + [View-Fitting Entitys in First-Person Mode](#--view-fitting-entitys-in-first-person-mode--)\n * * [Plan-View Mode](#plan-view-mode)\n *      + [Following the Pointer in Plan-View Mode](#--following-the-pointer-in-plan-view-mode--)\n *      + [Axis-Aligned Views in Plan-View Mode](#--axis-aligned-views-in-plan-view-mode--)\n * * [CameraControl Events](#cameracontrol-events)\n *      + [\"hover\"](#---hover---)\n *      + [\"hoverOff\"](#---hoveroff---)\n *      + [\"hoverEnter\"](#---hoverenter---)\n *      + [\"hoverOut\"](#---hoverout---)\n *      + [\"picked\"](#---picked---)\n *      + [\"pickedSurface\"](#---pickedsurface---)\n *      + [\"pickedNothing\"](#---pickednothing---)\n *      + [\"doublePicked\"](#---doublepicked---)\n *      + [\"doublePickedSurface\"](#---doublepickedsurface---)\n *      + [\"doublePickedNothing\"](#---doublepickednothing---)\n *      + [\"rightClick\"](#---rightclick---)\n * * [Custom Keyboard Mappings](#custom-keyboard-mappings)\n *\n * <br><br>\n *\n * # Overview\n *\n * * Each {@link Viewer} has a ````CameraControl````, located at {@link Viewer#cameraControl}.\n * * {@link CameraControl#navMode} selects the navigation mode:\n *      * ````\"orbit\"```` rotates the {@link Camera} position about the target.\n *      * ````\"firstPerson\"```` rotates the World about the Camera position.\n *      * ````\"planView\"```` never rotates, but still allows to pan and dolly, typically for an axis-aligned view.\n * * {@link CameraControl#followPointer} makes the Camera follow the mouse or touch pointer.\n * * {@link CameraControl#constrainVertical} locks the Camera to its current height when in first-person mode.\n * * ````CameraControl```` fires pick events when we hover, click or tap on an {@link Entity}.\n * <br><br>\n *\n * # Examples\n *\n * * [Orbit Navigation - Duplex Model](https://xeokit.github.io/xeokit-sdk/examples/index.html#CameraControl_orbit_Duplex)\n * * [Orbit Navigation - Holter Tower Model](https://xeokit.github.io/xeokit-sdk/examples/index.html#CameraControl_orbit_HolterTower)\n * * [First-Person Navigation - Duplex Model](https://xeokit.github.io/xeokit-sdk/examples/index.html#CameraControl_firstPerson_Duplex)\n * * [First-Person Navigation - Holter Tower Model](https://xeokit.github.io/xeokit-sdk/examples/index.html#CameraControl_firstPerson_HolterTower)\n * * [Plan-view Navigation - Schependomlaan Model](https://xeokit.github.io/xeokit-sdk/examples/index.html#CameraControl_planView_Schependomlaan)\n * * [Custom Keyboard Mapping](https://xeokit.github.io/xeokit-sdk/examples/index.html#CameraControl_keyMap)\n * <br><br>\n *\n * # Orbit Mode\n *\n * In orbit mode, ````CameraControl```` orbits the {@link Camera} about the target.\n *\n * To enable orbit mode:\n *\n * ````javascript\n * const cameraControl = myViewer.cameraControl;\n * cameraControl.navMode = \"orbit\";\n * ````\n *\n * Then orbit by:\n *\n * * left-dragging the mouse,\n * * tap-dragging the touch pad, and\n * * pressing arrow keys, or ````Q```` and ````E```` on a QWERTY keyboard, or ````A```` and ````E```` on an AZERTY keyboard.\n * <br><br>\n *\n * Dolly forwards and backwards by:\n *\n * * spinning the mouse wheel,\n * * pinching on the touch pad, and\n * * pressing the ````+```` and ````-```` keys, or ````W```` and ````S```` on a QWERTY keyboard, or ````Z```` and ````S```` for AZERTY.\n * <br><br>\n *\n * Pan horizontally and vertically by:\n *\n * * right-dragging the mouse,\n * * left-dragging the mouse with the SHIFT key down,\n * * tap-dragging the touch pad with SHIFT down,\n * * pressing the ````A````, ````D````, ````Z```` and ````X```` keys on a QWERTY keyboard, and\n * * pressing the ````Q````, ````D````, ````W```` and ````X```` keys on an AZERTY keyboard,\n * <br><br>\n *\n * ## Following the Pointer in Orbit Mode\n *\n * When {@link CameraControl#followPointer} is ````true````in orbiting mode, the mouse or touch pointer will dynamically\n * indicate the target that the {@link Camera} will orbit, as well as dolly to and from.\n *\n * Lets ensure that we're in orbit mode, then enable the {@link Camera} to follow the pointer:\n *\n * ````javascript\n * cameraControl.navMode = \"orbit\";\n * cameraControl.followPointer = true;\n * ````\n *\n * ## Smart Pivoting\n *\n * TODO\n *\n * ## Showing the Pivot Position\n *\n * We can configure {@link CameraControl#pivotElement} with an HTML element to indicate the current\n * pivot position. The indicator will appear momentarily each time we move the {@link Camera} while in orbit mode with\n * {@link CameraControl#followPointer} set ````true````.\n *\n * First we'll define some CSS to style our pivot indicator as a black dot with a white border:\n *\n * ````css\n * .camera-pivot-marker {\n *      color: #ffffff;\n *      position: absolute;\n *      width: 25px;\n *      height: 25px;\n *      border-radius: 15px;\n *      border: 2px solid #ebebeb;\n *      background: black;\n *      visibility: hidden;\n *      box-shadow: 5px 5px 15px 1px #000000;\n *      z-index: 10000;\n *      pointer-events: none;\n * }\n * ````\n *\n * Then we'll attach our pivot indicator's HTML element to the ````CameraControl````:\n *\n * ````javascript\n * const pivotElement = document.createRange().createContextualFragment(\"<div class='camera-pivot-marker'></div>\").firstChild;\n *\n * document.body.appendChild(pivotElement);\n *\n * cameraControl.pivotElement = pivotElement;\n * ````\n *\n * ## Axis-Aligned Views in Orbit Mode\n *\n * In orbit mode, we can use keys 1-6 to position the {@link Camera} to look at the center of the {@link Scene} from along each of the\n * six World-space axis. Pressing one of these keys will fly the {@link Camera} to the corresponding axis-aligned view.\n *\n * ## View-Fitting Entitys in Orbit Mode\n *\n * When {@link CameraControl#doublePickFlyTo} is ````true````, we can left-double-click or\n * double-tap (ie. \"double-pick\") an {@link Entity} to fit it to view. This will cause the {@link Camera}\n * to fly to that Entity. Our target then becomes the center of that Entity. If we are currently pivoting,\n * then our pivot position is then also set to the Entity center.\n *\n * Disable that behaviour by setting {@link CameraControl#doublePickFlyTo} ````false````.\n *\n * # First-Person Mode\n *\n * In first-person mode, ````CameraControl```` rotates the World about the {@link Camera} position.\n *\n * To enable first-person mode:\n *\n * ````javascript\n * cameraControl.navMode = \"firstPerson\";\n * ````\n *\n * Then rotate by:\n *\n * * left-dragging the mouse,\n * * tap-dragging the touch pad,\n * * pressing arrow keys, or ````Q```` and ````E```` on a QWERTY keyboard, or ````A```` and ````E```` on an AZERTY keyboard.\n * <br><br>\n *\n * Dolly forwards and backwards by:\n *\n * * spinning the mouse wheel,\n * * pinching on the touch pad, and\n * * pressing the ````+```` and ````-```` keys, or ````W```` and ````S```` on a QWERTY keyboard, or ````Z```` and ````S```` for AZERTY.\n * <br><br>\n *\n * Pan left, right, up and down by:\n *\n * * left-dragging or right-dragging the mouse, and\n * * tap-dragging the touch pad with SHIFT down.\n *\n * Pan forwards, backwards, left, right, up and down by pressing the ````WSADZX```` keys on a QWERTY keyboard,\n * or ````WSQDWX```` keys on an AZERTY keyboard.\n * <br><br>\n *\n * ## Following the Pointer in First-Person Mode\n *\n * When {@link CameraControl#followPointer} is ````true```` in first-person mode, the mouse or touch pointer will dynamically\n * indicate the target to which the {@link Camera} will dolly to and from. In first-person mode, however, the World will always rotate\n * about the {@link Camera} position.\n *\n * Lets ensure that we're in first-person mode, then enable the {@link Camera} to follow the pointer:\n *\n * ````javascript\n * cameraControl.navMode = \"firstPerson\";\n * cameraControl.followPointer = true;\n * ````\n *\n * When the pointer is over empty space, the target will remain the last object that the pointer was over.\n *\n * ## Constraining Vertical Position in First-Person Mode\n *\n * In first-person mode, we can lock the {@link Camera} to its current position on the vertical World axis, which is useful for walk-through navigation:\n *\n * ````javascript\n * cameraControl.constrainVertical = true;\n * ````\n *\n * ## Axis-Aligned Views in First-Person Mode\n *\n * In first-person mode we can use keys 1-6 to position the {@link Camera} to look at the center of\n * the {@link Scene} from along each of the six World-space axis. Pressing one of these keys will fly the {@link Camera} to the\n * corresponding axis-aligned view.\n *\n * ## View-Fitting Entitys in First-Person Mode\n *\n * As in orbit mode, when in first-person mode and {@link CameraControl#doublePickFlyTo} is ````true````, we can double-click\n * or double-tap an {@link Entity} (ie. \"double-picking\") to fit it in view. This will cause the {@link Camera} to fly to\n * that Entity. Our target then becomes the center of that Entity.\n *\n * Disable that behaviour by setting {@link CameraControl#doublePickFlyTo} ````false````.\n *\n * # Plan-View Mode\n *\n * In plan-view mode, ````CameraControl```` pans and rotates the {@link Camera}, without rotating it.\n *\n * To enable plan-view mode:\n *\n * ````javascript\n * cameraControl.navMode = \"planView\";\n * ````\n *\n * Dolly forwards and backwards by:\n *\n * * spinning the mouse wheel,\n * * pinching on the touch pad, and\n * * pressing the ````+```` and ````-```` keys.\n *\n * <br>\n * Pan left, right, up and down by:\n *\n * * left-dragging or right-dragging the mouse, and\n * * tap-dragging the touch pad with SHIFT down.\n *\n * Pan forwards, backwards, left, right, up and down by pressing the ````WSADZX```` keys on a QWERTY keyboard,\n * or ````WSQDWX```` keys on an AZERTY keyboard.\n * <br><br>\n *\n * ## Following the Pointer in Plan-View Mode\n *\n * When {@link CameraControl#followPointer} is ````true```` in plan-view mode, the mouse or touch pointer will dynamically\n * indicate the target to which the {@link Camera} will dolly to and from.  In plan-view mode, however, the {@link Camera} cannot rotate.\n *\n * Lets ensure that we're in plan-view mode, then enable the {@link Camera} to follow the pointer:\n *\n * ````javascript\n * cameraControl.navMode = \"planView\";\n * cameraControl.followPointer = true; // Default\n * ````\n *\n * When the pointer is over empty space, the target will remain the last object that the pointer was over.\n *\n * ## Axis-Aligned Views in Plan-View Mode\n *\n * As in orbit and first-person modes, in plan-view mode we can use keys 1-6 to position the {@link Camera} to look at the center of\n * the {@link Scene} from along each of the six World-space axis. Pressing one of these keys will fly the {@link Camera} to the\n * corresponding axis-aligned view.\n *\n * # CameraControl Events\n *\n * ````CameraControl```` fires events as we interact with {@link Entity}s using mouse or touch input.\n *\n * The following examples demonstrate how to subscribe to those events.\n *\n * The first example shows how to save a handle to a subscription, which we can later use to unsubscribe.\n *\n * ## \"hover\"\n *\n * Event fired when the pointer moves while hovering over an Entity.\n *\n * ````javascript\n * const onHover = cameraControl.on(\"hover\", (e) => {\n *      const entity = e.entity; // Entity\n *      const canvasPos = e.canvasPos; // 2D canvas position\n * });\n * ````\n *\n * To unsubscribe from the event:\n *\n * ````javascript\n * cameraControl.off(onHover);\n * ````\n *\n * ## \"hoverOff\"\n *\n * Event fired when the pointer moves while hovering over empty space.\n *\n * ````javascript\n * cameraControl.on(\"hoverOff\", (e) => {\n *      const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"hoverEnter\"\n *\n * Event fired when the pointer moves onto an Entity.\n *\n * ````javascript\n * cameraControl.on(\"hoverEnter\", (e) => {\n *      const entity = e.entity;\n *      const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"hoverOut\"\n *\n * Event fired when the pointer moves off an Entity.\n *\n * ````javascript\n * cameraControl.on(\"hoverOut\", (e) => {\n *      const entity = e.entity;\n *      const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"picked\"\n *\n * Event fired when we left-click or tap on an Entity.\n *\n * ````javascript\n * cameraControl.on(\"picked\", (e) => {\n *      const entity = e.entity;\n *      const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"pickedSurface\"\n *\n * Event fired when we left-click or tap on the surface of an Entity.\n *\n * ````javascript\n * cameraControl.on(\"picked\", (e) => {\n *      const entity = e.entity;\n *      const canvasPos = e.canvasPos;\n *      const worldPos = e.worldPos; // 3D World-space position\n *      const viewPos = e.viewPos; // 3D View-space position\n *      const worldNormal = e.worldNormal; // 3D World-space normal vector\n * });\n * ````\n *\n * ## \"pickedNothing\"\n *\n * Event fired when we left-click or tap on empty space.\n *\n * ````javascript\n * cameraControl.on(\"pickedNothing\", (e) => {\n *      const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"doublePicked\"\n *\n * Event fired wwhen we left-double-click or double-tap on an Entity.\n *\n * ````javascript\n * cameraControl.on(\"doublePicked\", (e) => {\n *      const entity = e.entity;\n *      const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"doublePickedSurface\"\n *\n * Event fired when we left-double-click or double-tap on the surface of an Entity.\n *\n * ````javascript\n * cameraControl.on(\"doublePickedSurface\", (e) => {\n *      const entity = e.entity;\n *      const canvasPos = e.canvasPos;\n *      const worldPos = e.worldPos;\n *      const viewPos = e.viewPos;\n *      const worldNormal = e.worldNormal;\n * });\n * ````\n *\n * ## \"doublePickedNothing\"\n *\n * Event fired when we left-double-click or double-tap on empty space.\n *\n * ````javascript\n * cameraControl.on(\"doublePickedNothing\", (e) => {\n *      const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## \"rightClick\"\n *\n * Event fired when we right-click on the canvas.\n *\n * ````javascript\n * cameraControl.on(\"rightClick\", (e) => {\n *      const event = e.event; // Mouse event\n *      const canvasPos = e.canvasPos;\n * });\n * ````\n *\n * ## Custom Keyboard Mappings\n *\n * We can customize````CameraControl```` key bindings as shown below.\n *\n * In this example, we'll just set the default bindings for a QWERTY keyboard.\n *\n * ````javascript\n * const input = myViewer.scene.input;\n *\n * cameraControl.navMode = \"orbit\";\n * cameraControl.followPointer = true;\n *\n * const keyMap = {};\n *\n * keyMap[cameraControl.PAN_LEFT] = [input.KEY_A];\n * keyMap[cameraControl.PAN_RIGHT] = [input.KEY_D];\n * keyMap[cameraControl.PAN_UP] = [input.KEY_Z];\n * keyMap[cameraControl.PAN_DOWN] = [input.KEY_X];\n * keyMap[cameraControl.DOLLY_FORWARDS] = [input.KEY_W, input.KEY_ADD];\n * keyMap[cameraControl.DOLLY_BACKWARDS] = [input.KEY_S, input.KEY_SUBTRACT];\n * keyMap[cameraControl.ROTATE_X_POS] = [input.KEY_DOWN_ARROW];\n * keyMap[cameraControl.ROTATE_X_NEG] = [input.KEY_UP_ARROW];\n * keyMap[cameraControl.ROTATE_Y_POS] = [input.KEY_LEFT_ARROW];\n * keyMap[cameraControl.ROTATE_Y_NEG] = [input.KEY_RIGHT_ARROW];\n * keyMap[cameraControl.AXIS_VIEW_RIGHT] = [input.KEY_NUM_1];\n * keyMap[cameraControl.AXIS_VIEW_BACK] = [input.KEY_NUM_2];\n * keyMap[cameraControl.AXIS_VIEW_LEFT] = [input.KEY_NUM_3];\n * keyMap[cameraControl.AXIS_VIEW_FRONT] = [input.KEY_NUM_4];\n * keyMap[cameraControl.AXIS_VIEW_TOP] = [input.KEY_NUM_5];\n * keyMap[cameraControl.AXIS_VIEW_BOTTOM] = [input.KEY_NUM_6];\n * keyMap[cameraControl.MOUSE_PAN] = [[input.KEY_SHIFT, input.MOUSE_LEFT_BUTTON]];\n * keyMap[cameraControl.MOUSE_ROTATE] = [\n *     [input.KEY_SHIFT, input.MOUSE_MIDDLE_BUTTON],\n *     [input.KEY_SHIFT, input.MOUSE_RIGHT_BUTTON]\n * ]\n * keyMap[cameraControl.MOUSE_DOLLY] = [[input.KEY_CTRL, input.MOUSE_RIGHT_BUTTON]];\n *\n * cameraControl.keyMap = keyMap;\n * ````\n *\n * We can also just configure default bindings for a specified keyboard layout, like this:\n *\n * ````javascript\n * cameraControl.keyMap = \"qwerty\";\n * ````\n *\n * Then, ````CameraControl```` will internally set {@link CameraControl#keyMap} to the default key map for the QWERTY\n * layout (which is the same set of mappings we set in the previous example). In other words, if we subsequently\n * read {@link CameraControl#keyMap}, it will now be a key map, instead of the \"qwerty\" string value we set it to.\n *\n * Supported layouts are, so far:\n *\n * * ````\"qwerty\"````\n * * ````\"azerty\"````\n * \n * ## Basic Keyboard Mapping\n * * ````\"OR\" Relation````\n * Set multiple keys to trigger an action if any one is pressed:\n * \n * ````javascript\n * keyMap[cameraControl.DOLLY_BACKWARDS] = [input.KEY_S, input.KEY_SUBTRACT];\n * ````\n * \n * If either ````KEY_S```` or ````KEY_SUBTRACT```` is pressed, the camera will dolly backward.\n * \n * * ````\"AND\" Relation````\n * To require all keys in a combination to be pressed:\n * \n * ````javascript\n * keyMap[cameraControl.DOLLY_BACKWARDS] = [[input.KEY_S, input.KEY_SUBTRACT]];\n * ````\n * \n * The camera will dolly backward if ````both KEY_S```` and ````KEY_SUBTRACT```` are pressed.\n * \n * * ````Mix \"AND\" and \"OR\" Relation````\n * Use a combination of keys and groups for flexibility:\n * \n * ````javascript\n * keyMap[cameraControl.DOLLY_BACKWARDS] = [\n *     [input.KEY_S, input.KEY_SUBTRACT],  // 'And' group\n *     input.KEY_SHIFT                      // 'Or' with previous\n * ];\n * ````\n * \n * The camera will dolly backward if ````KEY_S```` + ````KEY_SUBTRACT```` are pressed together, or if ````KEY_SHIFT```` is pressed.\n * \n * ## Special Mouse Actions\n * Certain actions support combinations with specific mouse buttons or events:\n * \n * * ````MOUSE_PAN````\n * For panning with a key and mouse movement:\n * \n * ````javascript\n * keyMap[cameraControl.MOUSE_PAN] = [[input.KEY_SHIFT, input.MOUSE_LEFT_BUTTON]];\n * ````\n * \n * Panning is triggered by pressing ````KEY_SHIFT```` + ````MOUSE_LEFT_BUTTON```` while moving the mouse.\n * \n * * ````MOUSE_ROTATE````\n * Similar to panning, rotation can be configured with key and mouse button combinations:\n * \n * ````javascript\n * keyMap[cameraControl.MOUSE_ROTATE] = [[input.KEY_CTRL, input.MOUSE_LEFT_BUTTON]];\n * ````\n * \n * Rotation is triggered by pressing ````KEY_CTRL```` + ````MOUSE_LEFT_BUTTON```` during mouse movement.\n * \n * * ````MOUSE_DOLLY````\n * Dolly with mouse wheel scrolling and optional key combinations:\n * \n * ````javascript\n * keyMap[cameraControl.MOUSE_DOLLY] = [[input.KEY_ALT]];\n * ````\n * \n * Dolly action occurs when scrolling the mouse wheel with ````KEY_ALT```` held (no need to specify MOUSE_WHEEL).\n * \n * ## Special Mouse Actions\n * Use ````input.MOUSE_LEFT_BUTTON````, ````input.MOUSE_MIDDLE_BUTTON````, and ````input.MOUSE_RIGHT_BUTTON```` in combinations only for camera movements involving the mouse.\n */\nclass CameraControl extends Component {\n\n    /**\n     * @private\n     * @constructor\n     */\n    constructor(owner, cfg = {}) {\n\n        super(owner, cfg);\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.PAN_LEFT = 0;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.PAN_RIGHT = 1;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.PAN_UP = 2;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.PAN_DOWN = 3;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.PAN_FORWARDS = 4;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.PAN_BACKWARDS = 5;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.ROTATE_X_POS = 6;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.ROTATE_X_NEG = 7;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.ROTATE_Y_POS = 8;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.ROTATE_Y_NEG = 9;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.DOLLY_FORWARDS = 10;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.DOLLY_BACKWARDS = 11;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.AXIS_VIEW_RIGHT = 12;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.AXIS_VIEW_BACK = 13;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.AXIS_VIEW_LEFT = 14;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.AXIS_VIEW_FRONT = 15;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.AXIS_VIEW_TOP = 16;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.AXIS_VIEW_BOTTOM = 17;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.MOUSE_PAN = 18;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.MOUSE_ROTATE = 19;\n\n        /**\n         * Identifies the XX action.\n         * @final\n         * @type {Number}\n         */\n        this.MOUSE_DOLLY = 20;\n\n        this._keyMap = {}; // Maps key codes to the above actions\n\n        this.scene.canvas.canvas.oncontextmenu = (e) => {\n            e.preventDefault();\n        };\n\n        // User-settable CameraControl configurations\n\n        this._configs = {\n\n            // Private\n\n            longTapTimeout: 600, // Millisecs\n            longTapRadius: 5, // Pixels\n\n            // General\n\n            active: true,\n            keyboardLayout: \"qwerty\",\n            navMode: \"orbit\",\n            planView: false,\n            firstPerson: false,\n            followPointer: true,\n            doublePickFlyTo: true,\n            panRightClick: true,\n            showPivot: false,\n            pointerEnabled: true,\n            constrainVertical: false,\n            smartPivot: false,\n            doubleClickTimeFrame: 250,\n            zoomOnMouseWheel: true,\n\n            snapToVertex: DEFAULT_SNAP_VERTEX,\n            snapToEdge: DEFAULT_SNAP_EDGE,\n            snapRadius: DEFAULT_SNAP_PICK_RADIUS,\n\n            keyboardEnabledOnlyIfMouseover: true,\n\n            // Rotation\n\n            dragRotationRate: 360.0,\n            keyboardRotationRate: 90.0,\n            rotationInertia: 0.0,\n\n            // Panning\n\n            keyboardPanRate: 1.0,\n            touchPanRate: 1.0,\n            panInertia: 0.5,\n\n            // Dollying\n\n            keyboardDollyRate: 10,\n            mouseWheelDollyRate: 100,\n            touchDollyRate: 0.2,\n            dollyInertia: 0,\n            dollyProximityThreshold: 30.0,\n            dollyMinSpeed: 0.04\n        };\n\n        // Current runtime state of the CameraControl\n\n        this._states = {\n            pointerCanvasPos: math.vec2(),\n            mouseover: false,\n            followPointerDirty: true,\n            mouseDownClientX: 0,\n            mouseDownClientY: 0,\n            mouseDownCursorX: 0,\n            mouseDownCursorY: 0,\n            touchStartTime: null,\n            activeTouches: [],\n            tapStartPos: math.vec2(),\n            tapStartTime: -1,\n            lastTapTime: -1,\n            longTouchTimeout: null\n        };\n\n        // Updates for CameraUpdater to process on next Scene \"tick\" event\n\n        this._updates = {\n            rotateDeltaX: 0,\n            rotateDeltaY: 0,\n            panDeltaX: 0,\n            panDeltaY: 0,\n            panDeltaZ: 0,\n            dollyDelta: 0\n        };\n\n        // Controllers to assist input event handlers with controlling the Camera\n\n        const scene = this.scene;\n\n        this._controllers = {\n            cameraControl: this,\n            pickController: new PickController(this, this._configs),\n            pivotController: new PivotController(scene, this._configs),\n            panController: new PanController(scene),\n            cameraFlight: new CameraFlightAnimation(this, {\n                duration: 0.5\n            })\n        };\n\n        // Input event handlers\n\n        this._handlers = [\n            new MouseMiscHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n            new TouchPanRotateAndDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n            new MousePanRotateDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n            new KeyboardAxisViewHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n            new MousePickHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n            new TouchPickHandler(this.scene, this._controllers, this._configs, this._states, this._updates),\n            new KeyboardPanRotateDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates)\n        ];\n\n        this._cursors = {\n            dollyForward: \"zoom-in\",\n            dollyBackward: \"zoom-out\",\n            rotate: 'grabbing',\n            pan: 'move',\n        };\n\n        // Applies scheduled updates to the Camera on each Scene \"tick\" event\n\n        this._cameraUpdater = new CameraUpdater(this.scene, this._controllers, this._configs, this._states, this._updates);\n\n        // Set initial user configurations\n\n        this.navMode = cfg.navMode;\n        if (cfg.planView) {\n            this.planView = cfg.planView;\n        }\n        this.constrainVertical = cfg.constrainVertical;\n        if (cfg.keyboardLayout) {\n            this.keyboardLayout = cfg.keyboardLayout; // Deprecated\n        } else {\n            this.keyMap = cfg.keyMap;\n        }\n        this.doublePickFlyTo = cfg.doublePickFlyTo;\n        this.panRightClick = cfg.panRightClick;\n        this.active = cfg.active;\n        this.followPointer = cfg.followPointer;\n        this.rotationInertia = cfg.rotationInertia;\n        this.keyboardPanRate = cfg.keyboardPanRate;\n        this.touchPanRate = cfg.touchPanRate;\n        this.keyboardRotationRate = cfg.keyboardRotationRate;\n        this.dragRotationRate = cfg.dragRotationRate;\n        this.touchDollyRate = cfg.touchDollyRate;\n        this.dollyInertia = cfg.dollyInertia;\n        this.dollyProximityThreshold = cfg.dollyProximityThreshold;\n        this.dollyMinSpeed = cfg.dollyMinSpeed;\n        this.panInertia = cfg.panInertia;\n        this.pointerEnabled = true;\n        this.keyboardDollyRate = cfg.keyboardDollyRate;\n        this.mouseWheelDollyRate = cfg.mouseWheelDollyRate;\n    }\n\n    /**\n     * Sets custom mappings of keys to ````CameraControl```` actions.\n     *\n     * See class docs for usage.\n     *\n     * @param {{Number:(Number | Number[])[]} | String} value Either a set of new key mappings, or a string to select a keyboard layout,\n     * which causes ````CameraControl```` to use the default key mappings for that layout.\n     */\n    set keyMap(value) {\n        value = value || \"qwerty\";\n        if (utils.isString(value)) {\n            const input = this.scene.input;\n            const keyMap = {};\n\n            switch (value) {\n\n                default:\n                    this.error(\"Unsupported value for 'keyMap': \" + value + \" defaulting to 'qwerty'\");\n                // Intentional fall-through to \"qwerty\"\n                case \"qwerty\":\n                    keyMap[this.PAN_LEFT] = [input.KEY_A];\n                    keyMap[this.PAN_RIGHT] = [input.KEY_D];\n                    keyMap[this.PAN_UP] = [input.KEY_Z];\n                    keyMap[this.PAN_DOWN] = [input.KEY_X];\n                    keyMap[this.PAN_BACKWARDS] = [];\n                    keyMap[this.PAN_FORWARDS] = [];\n                    keyMap[this.DOLLY_FORWARDS] = [input.KEY_W, input.KEY_ADD];\n                    keyMap[this.DOLLY_BACKWARDS] = [input.KEY_S, input.KEY_SUBTRACT];\n                    keyMap[this.ROTATE_X_POS] = [input.KEY_DOWN_ARROW];\n                    keyMap[this.ROTATE_X_NEG] = [input.KEY_UP_ARROW];\n                    keyMap[this.ROTATE_Y_POS] = [input.KEY_Q, input.KEY_LEFT_ARROW];\n                    keyMap[this.ROTATE_Y_NEG] = [input.KEY_E, input.KEY_RIGHT_ARROW];\n                    keyMap[this.AXIS_VIEW_RIGHT] = [input.KEY_NUM_1];\n                    keyMap[this.AXIS_VIEW_BACK] = [input.KEY_NUM_2];\n                    keyMap[this.AXIS_VIEW_LEFT] = [input.KEY_NUM_3];\n                    keyMap[this.AXIS_VIEW_FRONT] = [input.KEY_NUM_4];\n                    keyMap[this.AXIS_VIEW_TOP] = [input.KEY_NUM_5];\n                    keyMap[this.AXIS_VIEW_BOTTOM] = [input.KEY_NUM_6];\n                    keyMap[this.MOUSE_PAN] = [\n                        [input.MOUSE_LEFT_BUTTON, input.KEY_SHIFT],\n                        this._configs.panRightClick ? input.MOUSE_RIGHT_BUTTON : input.MOUSE_MIDDLE_BUTTON\n                    ];\n                    keyMap[this.MOUSE_ROTATE] = [input.MOUSE_LEFT_BUTTON];\n                    keyMap[this.MOUSE_DOLLY] = [];\n                    break;\n\n                case \"azerty\":\n                    keyMap[this.PAN_LEFT] = [input.KEY_Q];\n                    keyMap[this.PAN_RIGHT] = [input.KEY_D];\n                    keyMap[this.PAN_UP] = [input.KEY_W];\n                    keyMap[this.PAN_DOWN] = [input.KEY_X];\n                    keyMap[this.PAN_BACKWARDS] = [];\n                    keyMap[this.PAN_FORWARDS] = [];\n                    keyMap[this.DOLLY_FORWARDS] = [input.KEY_Z, input.KEY_ADD];\n                    keyMap[this.DOLLY_BACKWARDS] = [input.KEY_S, input.KEY_SUBTRACT];\n                    keyMap[this.ROTATE_X_POS] = [input.KEY_DOWN_ARROW];\n                    keyMap[this.ROTATE_X_NEG] = [input.KEY_UP_ARROW];\n                    keyMap[this.ROTATE_Y_POS] = [input.KEY_A, input.KEY_LEFT_ARROW];\n                    keyMap[this.ROTATE_Y_NEG] = [input.KEY_E, input.KEY_RIGHT_ARROW];\n                    keyMap[this.AXIS_VIEW_RIGHT] = [input.KEY_NUM_1];\n                    keyMap[this.AXIS_VIEW_BACK] = [input.KEY_NUM_2];\n                    keyMap[this.AXIS_VIEW_LEFT] = [input.KEY_NUM_3];\n                    keyMap[this.AXIS_VIEW_FRONT] = [input.KEY_NUM_4];\n                    keyMap[this.AXIS_VIEW_TOP] = [input.KEY_NUM_5];\n                    keyMap[this.AXIS_VIEW_BOTTOM] = [input.KEY_NUM_6];\n                    keyMap[this.MOUSE_PAN] = [\n                        [input.MOUSE_LEFT_BUTTON, input.KEY_SHIFT],\n                        this._configs.panRightClick ? input.MOUSE_RIGHT_BUTTON : input.MOUSE_MIDDLE_BUTTON\n                    ];\n                    keyMap[this.MOUSE_ROTATE] = [input.MOUSE_LEFT_BUTTON];\n                    keyMap[this.MOUSE_DOLLY] = [];\n                    break;\n            }\n\n            this._keyMap = keyMap;\n        } else {\n            const keyMap = value;\n            this._keyMap = keyMap;\n        }\n    }\n\n    /**\n     * Gets custom mappings of keys to {@link CameraControl} actions.\n     *\n     * @returns {{Number:(Number | Number[])[]}} Current key mappings.\n     */\n    get keyMap() {\n        return this._keyMap;\n    }\n\n    _areAllKeysDown(keyDownMap, keys) {\n        if (!keys || keys.length <= 0) {\n            return true;\n        }\n        if (!keyDownMap) {\n            return false;\n        }\n        for (let i = 0, len = keys.length; i < len; i++) {\n            const key = keys[i];\n            if (!keyDownMap[key])\n                return false;\n        }\n        return true;\n    }\n\n    _isAnyOtherKeyDown(keyDownMap, keyMap) {\n        for (let i = 0, len = keyDownMap.length; i < len; i++) {\n            if (keyDownMap[i]) {\n                if (Array.isArray(keyMap)) {\n                    if (keyMap.indexOf(i) < 0) return true;\n                }\n                else if (i !== keyMap) return true;\n            }\n        }\n        return false;\n    }\n\n    _isMouseAction(action) {\n        switch (action) {\n            case this.MOUSE_ROTATE:\n            case this.MOUSE_DOLLY:\n            case this.MOUSE_PAN:\n                return true;\n            default:\n                return false;\n        }\n    }\n\n    /**\n     * Returns true if any keys configured for the given action are down.\n     * @param action\n     * @param keyDownMap\n     * @private\n     */\n    _isKeyDownForAction(action, keyDownMap) {\n        const keys = this._keyMap[action];\n        if (!keys) {\n            return false;\n        }\n        if (keys.length === 0 && this._isMouseAction(action)) return true;\n        if (!keyDownMap) {\n            keyDownMap = this.scene.input.keyDown;\n        }\n        for (let i = 0, len = keys.length; i < len; i++) {\n            const key = keys[i];\n            if (!Array.isArray(key)) {\n                if (keyDownMap[key] && !this._isAnyOtherKeyDown(keyDownMap, key))\n                    return true;\n            }\n            else {\n                if (this._areAllKeysDown(keyDownMap, key) && !this._isAnyOtherKeyDown(keyDownMap, key))\n                    return true;\n            }\n\n        }\n        return false;\n    }\n\n    /**\n     * Sets the HTMl element to represent the pivot point when {@link CameraControl#followPointer} is true.\n     *\n     * See class comments for an example.\n     *\n     * @param {HTMLElement} element HTML element representing the pivot point.\n     */\n    set pivotElement(element) {\n        this._controllers.pivotController.setPivotElement(element);\n    }\n\n    /**\n     *  Sets if this ````CameraControl```` is active or not.\n     *\n     * When inactive, the ````CameraControl```` will not react to input.\n     *\n     * Default is ````true````.\n     *\n     * @param {Boolean} value Set ````true```` to activate this ````CameraControl````.\n     */\n    set active(value) {\n        value = value !== false;\n        this._configs.active = value;\n        this._handlers[1]._active = value;\n        this._handlers[5]._active = value;\n    }\n\n    /**\n     * Gets if this ````CameraControl```` is active or not.\n     *\n     * When inactive, the ````CameraControl```` will not react to input.\n     *\n     * Default is ````true````.\n     *\n     * @returns {Boolean} Returns ````true```` if this ````CameraControl```` is active.\n     */\n    get active() {\n        return this._configs.active;\n    }\n\n    /**\n     * Sets whether the pointer snap to vertex.\n     *\n     * @param {boolean} snapToVertex\n     */\n    set snapToVertex(snapToVertex) {\n        this._configs.snapToVertex = !!snapToVertex;\n    }\n\n    /**\n     * Gets whether the pointer snap to vertex.\n     *\n     * @returns {boolean}\n     */\n    get snapToVertex() {\n        return this._configs.snapToVertex;\n    }\n\n    /**\n     * Sets whether the pointer snap to edge.\n     *\n     * @param {boolean} snapToEdge\n     */\n    set snapToEdge(snapToEdge) {\n        this._configs.snapToEdge = !!snapToEdge;\n    }\n\n    /**\n     * Gets whether the pointer snap to edge.\n     *\n     * @returns {boolean}\n     */\n    get snapToEdge() {\n        return this._configs.snapToEdge;\n    }\n\n    /**\n     * Sets the current snap radius for \"hoverSnapOrSurface\" events, to specify whether the radius\n     * within which the pointer snaps to the nearest vertex or the nearest edge.\n     *\n     * Default value is 30 pixels.\n     *\n     * @param {Number} snapRadius The snap radius.\n     */\n    set snapRadius(snapRadius) {\n        snapRadius = snapRadius || DEFAULT_SNAP_PICK_RADIUS;\n        this._configs.snapRadius = snapRadius;\n    }\n\n    /**\n     * Gets the current snap radius.\n     *\n     * @returns {Number} The snap radius.\n     */\n    get snapRadius() {\n        return this._configs.snapRadius;\n    }\n\n    /**\n     * If `true`, the keyboard shortcuts are enabled ONLY if the mouse is over the canvas.\n     * \n     * @param {boolean} value\n     */\n    set keyboardEnabledOnlyIfMouseover(value) {\n        this._configs.keyboardEnabledOnlyIfMouseover = !!value;\n    }\n\n    /**\n     * Gets whether the keyboard shortcuts are enabled ONLY if the mouse is over the canvas or ALWAYS.\n     * \n     * @returns {boolean}\n     */\n    get keyboardEnabledOnlyIfMouseover() {\n        return this._configs.keyboardEnabledOnlyIfMouseover;\n    }\n    \n    /**\n     * Sets the current navigation mode.\n     *\n     * Accepted values are:\n     *\n     * * \"orbit\" - rotation orbits about the current target or pivot point,\n     * * \"firstPerson\" - rotation is about the current eye position,\n     * * \"planView\" - rotation is disabled.\n     *\n     * See class comments for more info.\n     *\n     * @param {String} navMode The navigation mode: \"orbit\", \"firstPerson\" or \"planView\".\n     */\n    set navMode(navMode) {\n        navMode = navMode || \"orbit\";\n        if (navMode !== \"firstPerson\" && navMode !== \"orbit\" && navMode !== \"planView\") {\n            this.error(\"Unsupported value for navMode: \" + navMode + \" - supported values are 'orbit', 'firstPerson' and 'planView' - defaulting to 'orbit'\");\n            navMode = \"orbit\";\n        }\n        this._configs.firstPerson = (navMode === \"firstPerson\");\n        this._configs.planView = (navMode === \"planView\");\n        if (this._configs.firstPerson || this._configs.planView) {\n            this._controllers.pivotController.hidePivot();\n            this._controllers.pivotController.endPivot();\n        }\n        this._configs.navMode = navMode;\n    }\n\n    /**\n     * Gets the current navigation mode.\n     *\n     * @returns {String} The navigation mode: \"orbit\", \"firstPerson\" or \"planView\".\n     */\n    get navMode() {\n        return this._configs.navMode;\n    }\n\n    /**\n     * Sets whether mouse and touch input is enabled.\n     *\n     * Default is ````true````.\n     *\n     * Disabling mouse and touch input on ````CameraControl```` is useful when we want to temporarily use mouse or\n     * touch input to interact with some other 3D control, without disturbing the {@link Camera}.\n     *\n     * @param {Boolean} value Set ````true```` to enable mouse and touch input.\n     */\n    set pointerEnabled(value) {\n        this._reset();\n        this._configs.pointerEnabled = !!value;\n    }\n\n    /**\n     * Sets the cursor to be used when a particular action is being performed.\n     *\n     * Accepted actions are:\n     * \n     * * \"dollyForward\" - when the camera is dollying in the forward direction\n     * * \"dollyBackward\" - when the camera is dollying in the backward direction\n     * * \"pan\" - when the camera is being panned\n     * * \"rotate\" - when the camera is being rotated\n     *\n     * @param {String} action\n     * @param {String} style\n     */\n    setCursorStyle(action, style) {\n        if (Object.prototype.hasOwnProperty.call(this._cursors, action)) {\n            this._cursors = { ...this._cursors, [action]: style };\n        }\n        else\n            console.warn(`Action '${action}' is not valid for cursor styles.`);\n    }\n\n    /**\n     * Gets the current style for a particular action.\n     *\n     * @param {String} action To get the style for\n     * @returns {String} style set on the cursor for action\n     */\n    getCursorStyle(action) {\n        return this._cursors[action] || null;\n    }\n\n    _reset() {\n        for (let i = 0, len = this._handlers.length; i < len; i++) {\n            const handler = this._handlers[i];\n            if (handler.reset) {\n                handler.reset();\n            }\n        }\n\n        this._updates.panDeltaX = 0;\n        this._updates.panDeltaY = 0;\n        this._updates.rotateDeltaX = 0;\n        this._updates.rotateDeltaY = 0;\n        this._updates.dolyDelta = 0;\n    }\n\n    /**\n     * Gets whether mouse and touch input is enabled.\n     *\n     * Default is ````true````.\n     *\n     * Disabling mouse and touch input on ````CameraControl```` is desirable when we want to temporarily use mouse or\n     * touch input to interact with some other 3D control, without interfering with the {@link Camera}.\n     *\n     * @returns {Boolean} Returns ````true```` if mouse and touch input is enabled.\n     */\n    get pointerEnabled() {\n        return this._configs.pointerEnabled;\n    }\n\n    /**\n     * Sets whether the {@link Camera} follows the mouse/touch pointer.\n     *\n     * In orbiting mode, the Camera will orbit about the pointer, and will dolly to and from the pointer.\n     *\n     * In fly-to mode, the Camera will dolly to and from the pointer, however the World will always rotate about the Camera position.\n     *\n     * In plan-view mode, the Camera will dolly to and from the pointer, however the Camera will not rotate.\n     *\n     * Default is ````true````.\n     *\n     * See class comments for more info.\n     *\n     * @param {Boolean} value Set ````true```` to enable the Camera to follow the pointer.\n     */\n    set followPointer(value) {\n        this._configs.followPointer = (value !== false);\n    }\n\n    /**\n     * Sets whether the {@link Camera} follows the mouse/touch pointer.\n     *\n     * In orbiting mode, the Camera will orbit about the pointer, and will dolly to and from the pointer.\n     *\n     * In fly-to mode, the Camera will dolly to and from the pointer, however the World will always rotate about the Camera position.\n     *\n     * In plan-view mode, the Camera will dolly to and from the pointer, however the Camera will not rotate.\n     *\n     * Default is ````true````.\n     *\n     * See class comments for more info.\n     *\n     * @returns {Boolean} Returns ````true```` if the Camera follows the pointer.\n     */\n    get followPointer() {\n        return this._configs.followPointer;\n    }\n\n    /**\n     * Sets the current World-space 3D target position.\n     *\n     * Only applies when {@link CameraControl#followPointer} is ````true````.\n     *\n     * @param {Number[]} worldPos The new World-space 3D target position.\n     */\n    set pivotPos(worldPos) {\n        this._controllers.pivotController.setPivotPos(worldPos);\n    }\n\n    /**\n     * Gets the current World-space 3D pivot position.\n     *\n     * Only applies when {@link CameraControl#followPointer} is ````true````.\n     *\n     * @return {Number[]} worldPos The current World-space 3D pivot position.\n     */\n    get pivotPos() {\n        return this._controllers.pivotController.getPivotPos();\n    }\n\n    /**\n     * @deprecated\n     * @param {Boolean} value Set ````true```` to enable dolly-to-pointer behaviour.\n     */\n    set dollyToPointer(value) {\n        this.warn(\"dollyToPointer property is deprecated - replaced with followPointer\");\n        this.followPointer = value;\n    }\n\n    /**\n     * @deprecated\n     * @returns {Boolean} Returns ````true```` if dolly-to-pointer behaviour is enabled.\n     */\n    get dollyToPointer() {\n        this.warn(\"dollyToPointer property is deprecated - replaced with followPointer\");\n        return this.followPointer;\n    }\n\n    /**\n     * @deprecated\n     * @param {Boolean} value Set ````true```` to enable dolly-to-pointer behaviour.\n     */\n    set panToPointer(value) {\n        this.warn(\"panToPointer property is deprecated - replaced with followPointer\");\n    }\n\n    /**\n     * @deprecated\n     * @returns {Boolean} Returns ````true```` if dolly-to-pointer behaviour is enabled.\n     */\n    get panToPointer() {\n        this.warn(\"panToPointer property is deprecated - replaced with followPointer\");\n        return false;\n    }\n\n    /**\n     * Sets whether this ````CameraControl```` is in plan-view mode.\n     *\n     * When in plan-view mode, rotation is disabled.\n     *\n     * Default is ````false````.\n     *\n     * Deprecated - use {@link CameraControl#navMode} instead.\n     *\n     * @param {Boolean} value Set ````true```` to enable plan-view mode.\n     * @deprecated\n     */\n    set planView(value) {\n        this._configs.planView = !!value;\n        this._configs.firstPerson = false;\n        if (this._configs.planView) {\n            this._controllers.pivotController.hidePivot();\n            this._controllers.pivotController.endPivot();\n        }\n        this.warn(\"planView property is deprecated - replaced with navMode\");\n    }\n\n    /**\n     * Gets whether this ````CameraControl```` is in plan-view mode.\n     *\n     * When in plan-view mode, rotation is disabled.\n     *\n     * Default is ````false````.\n     *\n     * Deprecated - use {@link CameraControl#navMode} instead.\n     *\n     * @returns {Boolean} Returns ````true```` if plan-view mode is enabled.\n     * @deprecated\n     */\n    get planView() {\n        this.warn(\"planView property is deprecated - replaced with navMode\");\n        return this._configs.planView;\n    }\n\n    /**\n     * Sets whether this ````CameraControl```` is in first-person mode.\n     *\n     * In \"first person\" mode (disabled by default) the look position rotates about the eye position. Otherwise,  {@link Camera#eye} rotates about {@link Camera#look}.\n     *\n     * Default is ````false````.\n     *\n     * Deprecated - use {@link CameraControl#navMode} instead.\n     *\n     * @param {Boolean} value Set ````true```` to enable first-person mode.\n     * @deprecated\n     */\n    set firstPerson(value) {\n        this.warn(\"firstPerson property is deprecated - replaced with navMode\");\n        this._configs.firstPerson = !!value;\n        this._configs.planView = false;\n        if (this._configs.firstPerson) {\n            this._controllers.pivotController.hidePivot();\n            this._controllers.pivotController.endPivot();\n        }\n    }\n\n    /**\n     * Gets whether this ````CameraControl```` is in first-person mode.\n     *\n     * In \"first person\" mode (disabled by default) the look position rotates about the eye position. Otherwise,  {@link Camera#eye} rotates about {@link Camera#look}.\n     *\n     * Default is ````false````.\n     *\n     * Deprecated - use {@link CameraControl#navMode} instead.\n     *\n     * @returns {Boolean} Returns ````true```` if first-person mode is enabled.\n     * @deprecated\n     */\n    get firstPerson() {\n        this.warn(\"firstPerson property is deprecated - replaced with navMode\");\n        return this._configs.firstPerson;\n    }\n\n    /**\n     * Sets whether to vertically constrain the {@link Camera} position for first-person navigation.\n     *\n     * When set ````true````, this constrains {@link Camera#eye} to its current vertical position.\n     *\n     * Only applies when {@link CameraControl#navMode} is ````\"firstPerson\"````.\n     *\n     * Default is ````false````.\n     *\n     * @param {Boolean} value Set ````true```` to vertically constrain the Camera.\n     */\n    set constrainVertical(value) {\n        this._configs.constrainVertical = !!value;\n    }\n\n    /**\n     * Gets whether to vertically constrain the {@link Camera} position for first-person navigation.\n     *\n     * When set ````true````, this constrains {@link Camera#eye} to its current vertical position.\n     *\n     * Only applies when {@link CameraControl#navMode} is ````\"firstPerson\"````.\n     *\n     * Default is ````false````.\n     *\n     * @returns {Boolean} ````true```` when Camera is vertically constrained.\n     */\n    get constrainVertical() {\n        return this._configs.constrainVertical;\n    }\n\n    /**\n     * Sets whether double-picking an {@link Entity} causes the {@link Camera} to fly to its boundary.\n     *\n     * Default is ````false````.\n     *\n     * @param {Boolean} value Set ````true```` to enable double-pick-fly-to mode.\n     */\n    set doublePickFlyTo(value) {\n        this._configs.doublePickFlyTo = value !== false;\n    }\n\n    /**\n     * Gets whether double-picking an {@link Entity} causes the {@link Camera} to fly to its boundary.\n     *\n     * Default is ````false````.\n     *\n     * @returns {Boolean} Returns ````true```` when double-pick-fly-to mode is enabled.\n     */\n    get doublePickFlyTo() {\n        return this._configs.doublePickFlyTo;\n    }\n\n    /**\n     * Sets whether either right-clicking (true) or middle-clicking (false) pans the {@link Camera}.\n     *\n     * Default is ````true````.\n     *\n     * @param {Boolean} value Set ````false```` to disable pan on right-click.\n     */\n    set panRightClick(value) {\n        this._configs.panRightClick = value !== false;\n        const panKeyMap = this._keyMap[this.MOUSE_PAN];\n        if (panKeyMap && panKeyMap.length > 0) {\n            const input = this.scene.input;\n            for (let i = 0, len = panKeyMap.length; i < len; i++) {\n                if (this._configs.panRightClick && panKeyMap[i] === input.MOUSE_MIDDLE_BUTTON) \n                    this._keyMap[this.MOUSE_PAN][i] = input.MOUSE_RIGHT_BUTTON;\n                else if (!this._configs.panRightClick && panKeyMap[i] === input.MOUSE_RIGHT_BUTTON)\n                    this._keyMap[this.MOUSE_PAN][i] = input.MOUSE_MIDDLE_BUTTON;\n            }\n        }\n    }\n\n    /**\n     * Gets whether right-clicking pans the {@link Camera}.\n     *\n     * Default is ````true````.\n     *\n     * @returns {Boolean} Returns ````false```` when pan on right-click is disabled.\n     */\n    get panRightClick() {\n        return this._configs.panRightClick;\n    }\n\n    /**\n     * Sets a factor in range ````[0..1]```` indicating how much the {@link Camera} keeps moving after you finish rotating it.\n     *\n     * A value of ````0.0```` causes it to immediately stop, ````0.5```` causes its movement to decay 50% on each tick,\n     * while ````1.0```` causes no decay, allowing it continue moving, by the current rate of rotation.\n     *\n     * You may choose an inertia of zero when you want be able to precisely rotate the Camera,\n     * without interference from inertia. Zero inertia can also mean that less frames are rendered while\n     * you are rotating the Camera.\n     *\n     * Default is ````0.0````.\n     *\n     * Does not apply when {@link CameraControl#navMode} is ````\"planView\"````, which disallows rotation.\n     *\n     * @param {Number} rotationInertia New inertial factor.\n     */\n    set rotationInertia(rotationInertia) {\n        this._configs.rotationInertia = (rotationInertia !== undefined && rotationInertia !== null) ? rotationInertia : 0.0;\n    }\n\n    /**\n     * Gets the rotation inertia factor.\n     *\n     * Default is ````0.0````.\n     *\n     * Does not apply when {@link CameraControl#navMode} is ````\"planView\"````, which disallows rotation.\n     *\n     * @returns {Number} The inertia factor.\n     */\n    get rotationInertia() {\n        return this._configs.rotationInertia;\n    }\n\n    /**\n     * Sets how much the {@link Camera} pans each second with keyboard input.\n     *\n     * Default is ````5.0````, to pan the Camera ````5.0```` World-space units every second that\n     * a panning key is depressed. See the ````CameraControl```` class documentation for which keys control\n     * panning.\n     *\n     * Panning direction is aligned to our Camera's orientation. When we pan horizontally, we pan\n     * to our left and right, when we pan vertically, we pan upwards and downwards, and when we pan forwards\n     * and backwards, we pan along the direction the Camera is pointing.\n     *\n     * Unlike dollying when {@link followPointer} is ````true````, panning does not follow the pointer.\n     *\n     * @param {Number} keyboardPanRate The new keyboard pan rate.\n     */\n    set keyboardPanRate(keyboardPanRate) {\n        this._configs.keyboardPanRate = (keyboardPanRate !== null && keyboardPanRate !== undefined) ? keyboardPanRate : 5.0;\n    }\n\n\n    /**\n     * Sets how fast the camera pans on touch panning\n     *\n     * @param {Number} touchPanRate The new touch pan rate.\n     */\n    set touchPanRate(touchPanRate) {\n        this._configs.touchPanRate = (touchPanRate !== null && touchPanRate !== undefined) ? touchPanRate : 1.0;\n    }\n\n    /**\n     * Gets how fast the {@link Camera} pans on touch panning\n     *\n     * Default is ````1.0````.\n     *\n     * @returns {Number} The current touch pan rate.\n     */\n    get touchPanRate() {\n        return this._configs.touchPanRate;\n    }\n\n    /**\n     * Gets how much the {@link Camera} pans each second with keyboard input.\n     *\n     * Default is ````5.0````.\n     *\n     * @returns {Number} The current keyboard pan rate.\n     */\n    get keyboardPanRate() {\n        return this._configs.keyboardPanRate;\n    }\n\n    /**\n     * Sets how many degrees per second the {@link Camera} rotates/orbits with keyboard input.\n     *\n     * Default is ````90.0````, to rotate/orbit the Camera ````90.0```` degrees every second that\n     * a rotation key is depressed. See the ````CameraControl```` class documentation for which keys control\n     * rotation/orbit.\n     *\n     * @param {Number} keyboardRotationRate The new keyboard rotation rate.\n     */\n    set keyboardRotationRate(keyboardRotationRate) {\n        this._configs.keyboardRotationRate = (keyboardRotationRate !== null && keyboardRotationRate !== undefined) ? keyboardRotationRate : 90.0;\n    }\n\n    /**\n     * Sets how many degrees per second the {@link Camera} rotates/orbits with keyboard input.\n     *\n     * Default is ````90.0````.\n     *\n     * @returns {Number} The current keyboard rotation rate.\n     */\n    get keyboardRotationRate() {\n        return this._configs.keyboardRotationRate;\n    }\n\n    /**\n     * Sets the current drag rotation rate.\n     *\n     * This configures how many degrees the {@link Camera} rotates/orbits for a full sweep of the canvas by mouse or touch dragging.\n     *\n     * For example, a value of ````360.0```` indicates that the ````Camera```` rotates/orbits ````360.0```` degrees horizontally\n     * when we sweep the entire width of the canvas.\n     *\n     * ````CameraControl```` makes vertical rotation half as sensitive as horizontal rotation, so that we don't tend to\n     * flip upside-down. Therefore, a value of ````360.0```` rotates/orbits the ````Camera```` through ````180.0```` degrees\n     * vertically when we sweep the entire height of the canvas.\n     *\n     * Default is ````360.0````.\n     *\n     * @param {Number} dragRotationRate The new drag rotation rate.\n     */\n    set dragRotationRate(dragRotationRate) {\n        this._configs.dragRotationRate = (dragRotationRate !== null && dragRotationRate !== undefined) ? dragRotationRate : 360.0;\n    }\n\n    /**\n     * Gets the current drag rotation rate.\n     *\n     * Default is ````360.0````.\n     *\n     * @returns {Number} The current drag rotation rate.\n     */\n    get dragRotationRate() {\n        return this._configs.dragRotationRate;\n    }\n\n    /**\n     * Sets how much the {@link Camera} dollys each second with keyboard input.\n     *\n     * Default is ````15.0````, to dolly the {@link Camera} ````15.0```` World-space units per second while we hold down\n     * the ````+```` and ````-```` keys.\n     *\n     * @param {Number} keyboardDollyRate The new keyboard dolly rate.\n     */\n    set keyboardDollyRate(keyboardDollyRate) {\n        this._configs.keyboardDollyRate = (keyboardDollyRate !== null && keyboardDollyRate !== undefined) ? keyboardDollyRate : 15.0;\n    }\n\n    /**\n     * Gets how much the {@link Camera} dollys each second with keyboard input.\n     *\n     * Default is ````15.0````.\n     *\n     * @returns {Number} The current keyboard dolly rate.\n     */\n    get keyboardDollyRate() {\n        return this._configs.keyboardDollyRate;\n    }\n\n    /**\n     * Sets how much the {@link Camera} dollys with touch input.\n     *\n     * Default is ````0.2````\n     *\n     * @param {Number} touchDollyRate The new touch dolly rate.\n     */\n    set touchDollyRate(touchDollyRate) {\n        this._configs.touchDollyRate = (touchDollyRate !== null && touchDollyRate !== undefined) ? touchDollyRate : 0.2;\n    }\n\n    /**\n     * Gets how much the {@link Camera} dollys each second with touch input.\n     *\n     * Default is ````0.2````.\n     *\n     * @returns {Number} The current touch dolly rate.\n     */\n    get touchDollyRate() {\n        return this._configs.touchDollyRate;\n    }\n\n    /**\n     * Sets how much the {@link Camera} dollys each second while the mouse wheel is spinning.\n     *\n     * Default is ````100.0````, to dolly the {@link Camera} ````10.0```` World-space units per second as we spin\n     * the mouse wheel.\n     *\n     * @param {Number} mouseWheelDollyRate The new mouse wheel dolly rate.\n     */\n    set mouseWheelDollyRate(mouseWheelDollyRate) {\n        this._configs.mouseWheelDollyRate = (mouseWheelDollyRate !== null && mouseWheelDollyRate !== undefined) ? mouseWheelDollyRate : 100.0;\n    }\n\n    /**\n     * Gets how much the {@link Camera} dollys each second while the mouse wheel is spinning.\n     *\n     * Default is ````100.0````.\n     *\n     * @returns {Number} The current mouseWheel dolly rate.\n     */\n    get mouseWheelDollyRate() {\n        return this._configs.mouseWheelDollyRate;\n    }\n\n    /**\n     * Sets the dolly inertia factor.\n     *\n     * This factor configures how much the {@link Camera} keeps moving after you finish dollying it.\n     *\n     * This factor is a value in range ````[0..1]````. A value of ````0.0```` causes dollying to immediately stop,\n     * ````0.5```` causes dollying to decay 50% on each animation frame, while ````1.0```` causes no decay, which allows dollying\n     * to continue until further input stops it.\n     *\n     * You might set ````dollyInertia```` to zero when you want be able to precisely position or rotate the Camera,\n     * without interference from inertia. This also means that xeokit renders less frames while dollying the Camera,\n     * which can improve rendering performance.\n     *\n     * Default is ````0````.\n     *\n     * @param {Number} dollyInertia New dolly inertia factor.\n     */\n    set dollyInertia(dollyInertia) {\n        this._configs.dollyInertia = (dollyInertia !== undefined && dollyInertia !== null) ? dollyInertia : 0;\n    }\n\n    /**\n     * Gets the dolly inertia factor.\n     *\n     * Default is ````0````.\n     *\n     * @returns {Number} The current dolly inertia factor.\n     */\n    get dollyInertia() {\n        return this._configs.dollyInertia;\n    }\n\n    /**\n     * Sets the proximity to the closest object below which dolly speed decreases, and above which dolly speed increases.\n     *\n     * Default is ````35.0````.\n     *\n     * @param {Number} dollyProximityThreshold New dolly proximity threshold.\n     */\n    set dollyProximityThreshold(dollyProximityThreshold) {\n        this._configs.dollyProximityThreshold = (dollyProximityThreshold !== undefined && dollyProximityThreshold !== null) ? dollyProximityThreshold : 35.0;\n    }\n\n    /**\n     * Gets the proximity to the closest object below which dolly speed decreases, and above which dolly speed increases.\n     *\n     * Default is ````35.0````.\n     *\n     * @returns {Number} The current dolly proximity threshold.\n     */\n    get dollyProximityThreshold() {\n        return this._configs.dollyProximityThreshold;\n    }\n\n    /**\n     * Sets the minimum dolly speed.\n     *\n     * Default is ````0.04````.\n     *\n     * @param {Number} dollyMinSpeed New dolly minimum speed.\n     */\n    set dollyMinSpeed(dollyMinSpeed) {\n        this._configs.dollyMinSpeed = (dollyMinSpeed !== undefined && dollyMinSpeed !== null) ? dollyMinSpeed : 0.04;\n    }\n\n    /**\n     * Gets the minimum dolly speed.\n     *\n     * Default is ````0.04````.\n     *\n     * @returns {Number} The current minimum dolly speed.\n     */\n    get dollyMinSpeed() {\n        return this._configs.dollyMinSpeed;\n    }\n\n    /**\n     * Sets the pan inertia factor.\n     *\n     * This factor configures how much the {@link Camera} keeps moving after you finish panning it.\n     *\n     * This factor is a value in range ````[0..1]````. A value of ````0.0```` causes panning to immediately stop,\n     * ````0.5```` causes panning to decay 50% on each animation frame, while ````1.0```` causes no decay, which allows panning\n     * to continue until further input stops it.\n     *\n     * You might set ````panInertia```` to zero when you want be able to precisely position or rotate the Camera,\n     * without interference from inertia. This also means that xeokit renders less frames while panning the Camera,\n     * wich can improve rendering performance.\n     *\n     * Default is ````0.5````.\n     *\n     * @param {Number} panInertia New pan inertia factor.\n     */\n    set panInertia(panInertia) {\n        this._configs.panInertia = (panInertia !== undefined && panInertia !== null) ? panInertia : 0.5;\n    }\n\n    /**\n     * Gets the pan inertia factor.\n     *\n     * Default is ````0.5````.\n     *\n     * @returns {Number} The current pan inertia factor.\n     */\n    get panInertia() {\n        return this._configs.panInertia;\n    }\n\n    /**\n     * Sets the keyboard layout.\n     *\n     * Supported layouts are:\n     *\n     * * ````\"qwerty\"```` (default)\n     * * ````\"azerty\"````\n     *\n     * @deprecated\n     * @param {String} value Selects the keyboard layout.\n     */\n    set keyboardLayout(value) {\n        // this.warn(\"keyboardLayout property is deprecated - use keyMap property instead\");\n        value = value || \"qwerty\";\n        if (value !== \"qwerty\" && value !== \"azerty\") {\n            this.error(\"Unsupported value for keyboardLayout - defaulting to 'qwerty'\");\n            value = \"qwerty\";\n        }\n        this._configs.keyboardLayout = value;\n        this.keyMap = this._configs.keyboardLayout;\n    }\n\n    /**\n     * Gets the keyboard layout.\n     *\n     * Supported layouts are:\n     *\n     * * ````\"qwerty\"```` (default)\n     * * ````\"azerty\"````\n     *\n     * @deprecated\n     * @returns {String} The current keyboard layout.\n     */\n    get keyboardLayout() {\n        return this._configs.keyboardLayout;\n    }\n\n    /**\n     * Sets a sphere as the representation of the pivot position.\n     *\n     * @param {Object} [cfg] Sphere configuration.\n     * @param {String} [cfg.size=1] Optional size factor of the sphere. Defaults to 1.\n     * @param {String} [cfg.material=PhongMaterial] Optional size factor of the sphere. Defaults to a red opaque material.\n     */\n    enablePivotSphere(cfg = {}) {\n        this._controllers.pivotController.enablePivotSphere(cfg);\n    }\n\n    /**\n     * Remove the sphere as the representation of the pivot position.\n     *\n     */\n    disablePivotSphere() {\n        this._controllers.pivotController.disablePivotSphere();\n    }\n    \n    /**\n     * Sets whether smart default pivoting is enabled.\n     *\n     * When ````true````, we'll pivot by default about the 3D position of the mouse/touch pointer on an\n     * imaginary sphere that's centered at {@link Camera#eye} and sized to the {@link Scene} boundary.\n     *\n     * When ````false````, we'll pivot by default about {@link Camera#look}.\n     *\n     * Default is ````false````.\n     *\n     * @param {Boolean} enabled Set ````true```` to pivot by default about the selected point on the virtual sphere, or ````false```` to pivot by default about {@link Camera#look}.\n     */\n    set smartPivot(enabled) {\n        this._configs.smartPivot = (enabled !== false);\n    }\n\n    /**\n     * Gets whether smart default pivoting is enabled.\n     *\n     * When ````true````, we'll pivot by default about the 3D position of the mouse/touch pointer on an\n     * imaginary sphere that's centered at {@link Camera#eye} and sized to the {@link Scene} boundary.\n     *\n     * When ````false````, we'll pivot by default about {@link Camera#look}.\n     *\n     * Default is ````false````.\n     *\n     * @returns {Boolean} Returns ````true```` when pivoting by default about the selected point on the virtual sphere, or ````false```` when pivoting by default about {@link Camera#look}.\n     */\n    get smartPivot() {\n        return this._configs.smartPivot;\n    }\n\n    /**\n     * Sets the double click time frame length in milliseconds.\n     * \n     * If two mouse click events occur within this time frame, it is considered a double click. \n     * \n     * Default is ````250````\n     * \n     * @param {Number} value New double click time frame.\n     */\n    set doubleClickTimeFrame(value) {\n        this._configs.doubleClickTimeFrame = (value !== undefined && value !== null) ? value : 250;\n    }\n\n    /**\n     * Gets the double click time frame length in milliseconds.\n     *  \n     * Default is ````250````\n     * \n     * @param {Number} value Current double click time frame.\n     */\n    get doubleClickTimeFrame() {\n        return this._configs.doubleClickTimeFrame;\n    }\n\n    /**\n     * Sets whether to zoom the camera on mouse wheel\n     *\n     * Default is ````true````\n     *\n     * @param {Boolean} enabled\n     */\n    set zoomOnMouseWheel(enabled) {\n        this._configs.zoomOnMouseWheel = !!enabled;\n    }\n\n    /**\n     * Gets whether to zoom the camera on mouse wheel\n     *\n     * @returns {Boolean}\n     */\n    get zoomOnMouseWheel() {\n        return this._configs.zoomOnMouseWheel;\n    }\n\n    /**\n     * Destroys this ````CameraControl````.\n     * @private\n     */\n    destroy() {\n        this._destroyHandlers();\n        this._destroyControllers();\n        this._cameraUpdater.destroy();\n        super.destroy();\n    }\n\n    _destroyHandlers() {\n        for (let i = 0, len = this._handlers.length; i < len; i++) {\n            const handler = this._handlers[i];\n            if (handler.destroy) {\n                handler.destroy();\n            }\n        }\n    }\n\n    _destroyControllers() {\n        for (let i = 0, len = this._controllers.length; i < len; i++) {\n            const controller = this._controllers[i];\n            if (controller.destroy) {\n                controller.destroy();\n            }\n        }\n    }\n}\n\n/**\n * @desc A property within a {@link PropertySet}.\n *\n * @class Property\n */\nclass Property {\n\n    /**\n     * @private\n     */\n    constructor(name, value, type, valueType, description) {\n\n        /**\n         * The name of this property.\n         *\n         * @property name\n         * @type {String}\n         */\n        this.name = name;\n\n        /**\n         * The type of this property.\n         *\n         * @property type\n         * @type {Number|String}\n         */\n        this.type = type;\n\n        /**\n         * The value of this property.\n         *\n         * @property value\n         * @type {*}\n         */\n        this.value = value;\n\n        /**\n         * The type of this property's value.\n         *\n         * @property valueType\n         * @type {Number|String}\n         */\n        this.valueType = valueType;\n\n        /**\n         * Informative text to explain the property.\n         *\n         * @property name\n         * @type {String}\n         */\n        this.description = description;\n    }\n}\n\n/**\n * @desc A set of properties associated with one or more {@link MetaObject}s.\n *\n * A PropertySet is created within {@link MetaScene#createMetaModel} and belongs to a {@link MetaModel}.\n *\n * Each PropertySet is registered by {@link PropertySet#id} in {@link MetaScene#propertySets} and {@link MetaModel#propertySets}.\n *\n * @class PropertySet\n */\nclass PropertySet {\n\n    /**\n     * @private\n     */\n    constructor(params) {\n\n        /**\n         * Globally-unique ID for this PropertySet.\n         *\n         * PropertySet instances are registered by this ID in {@link MetaScene#propertySets} and {@link MetaModel#propertySets}.\n         *\n         * @property id\n         * @type {String}\n         */\n        this.id = params.id;\n\n        /**\n         * ID of the corresponding object within the originating system, if any.\n         *\n         * @type {String}\n         * @abstract\n         */\n        this.originalSystemId = params.originalSystemId;\n\n        /**\n         * The MetaModels that share this PropertySet.\n         * @type {MetaModel[]}\n         */\n        this.metaModels = [];\n\n        /**\n         * Human-readable name of this PropertySet.\n         *\n         * @property name\n         * @type {String}\n         */\n        this.name = params.name;\n\n        /**\n         * Type of this PropertySet.\n         *\n         * @property type\n         * @type {String}\n         */\n        this.type = params.type;\n\n        /**\n         * Properties within this PropertySet.\n         *\n         * @property properties\n         * @type {Property[]}\n         */\n        this.properties = [];\n\n        if (params.properties) {\n            const properties = params.properties;\n            for (let i = 0, len = properties.length; i < len; i++) {\n                const property = properties[i];\n                if (Number.isInteger(property)) { // Will decompress in MetaModel.finalize();\n                    this.properties.push(property);\n                } else {\n                    this.properties.push(new Property(property.name, property.value, property.type, property.valueType, property.description));\n                }\n            }\n        }\n    }\n}\n\n/**\n * @desc Metadata corresponding to an {@link Entity} that represents an object.\n *\n * An {@link Entity} represents an object when {@link Entity#isObject} is ````true````\n *\n * A MetaObject corresponds to an {@link Entity} by having the same {@link MetaObject#id} as the {@link Entity#id}.\n *\n * A MetaObject is created within {@link MetaScene#createMetaModel} and belongs to a {@link MetaModel}.\n *\n * Each MetaObject is registered by {@link MetaObject#id} in {@link MetaScene#metaObjects}.\n *\n * A {@link MetaModel} represents its object structure with a tree of MetaObjects, with {@link MetaModel#rootMetaObject} referencing\n * the root MetaObject.\n *\n * @class MetaObject\n */\nclass MetaObject {\n\n    /**\n     * @private\n     */\n    constructor(params) {\n\n        /**\n         * The MetaModels that share this MetaObject.\n         * @type {MetaModel[]}\n         */\n        this.metaModels = [];\n\n        /**\n         * Globally-unique ID.\n         *\n         * MetaObject instances are registered by this ID in {@link MetaScene#metaObjects}.\n         *\n         * @property id\n         * @type {String|Number}\n         */\n        this.id = params.id;\n\n        /**\n         * ID of the parent MetaObject.\n         * @type {String|Number}\n         */\n        this.parentId = params.parentId;\n\n        /**\n         * The parent MetaObject.\n         * @type {MetaObject | null}\n         */\n        this.parent = null;\n\n        /**\n         * ID of the corresponding object within the originating system, if any.\n         *\n         * @type {String}\n         * @abstract\n         */\n        this.originalSystemId = params.originalSystemId;\n\n        /**\n         * Human-readable name.\n         *\n         * @property name\n         * @type {String}\n         */\n        this.name = params.name;\n\n        /**\n         * Type - often an IFC product type.\n         *\n         * @property type\n         * @type {String}\n         */\n        this.type = params.type;\n\n        /**\n         * IDs of PropertySets associated with this MetaObject.\n         * @type {[]|*}\n         */\n        this.propertySetIds = params.propertySetIds;\n\n        /**\n         * The {@link PropertySet}s associated with this MetaObject.\n         *\n         * @property propertySets\n         * @type {PropertySet[]}\n         */\n        this.propertySets = [];\n\n        /**\n         * The attributes of this MetaObject.\n         * @type {{}}\n         */\n        this.attributes = params.attributes || {};\n\n        if (params.external !== undefined && params.external !== null) {\n        \n            /**\n             * External application-specific metadata\n             *\n             * Undefined when there are is no external application-specific metadata.\n             *\n             * @property external\n             * @type {*}\n             */\n            this.external = params.external;\n        }\n    }\n\n    /**\n     * Backwards compatibility with the object belonging to a single MetaModel.\n     * \n     * @property metaModel\n     * @type {MetaModel|null}\n     **/\n    get metaModel() {\n        if (this.metaModels.length == 1) {\n            return this.metaModels[0];\n        }\n\n        return null;\n    }\n\n    /**\n     * Gets the {@link MetaObject#id}s of the {@link MetaObject}s within the subtree.\n     *\n     * @returns {String[]} Array of {@link MetaObject#id}s.\n     */\n    getObjectIDsInSubtree() {\n        const objectIds = [];\n\n        function visit(metaObject) {\n            if (!metaObject) {\n                return;\n            }\n            objectIds.push(metaObject.id);\n            const children = metaObject.children;\n            if (children) {\n                for (var i = 0, len = children.length; i < len; i++) {\n                    visit(children[i]);\n                }\n            }\n        }\n\n        visit(this);\n        return objectIds;\n    }\n\n\n    /**\n     * Iterates over the {@link MetaObject}s within the subtree.\n     *\n     * @param {Function} callback Callback fired at each {@link MetaObject}.\n     */\n    withMetaObjectsInSubtree(callback) {\n\n        function visit(metaObject) {\n            if (!metaObject) {\n                return;\n            }\n            callback(metaObject);\n            const children = metaObject.children;\n            if (children) {\n                for (var i = 0, len = children.length; i < len; i++) {\n                    visit(children[i]);\n                }\n            }\n        }\n\n        visit(this);\n    }\n\n    /**\n     * Gets the {@link MetaObject#id}s of the {@link MetaObject}s within the subtree that have the given {@link MetaObject#type}s.\n     *\n     * @param {String[]} types {@link MetaObject#type} values.\n     * @returns {String[]} Array of {@link MetaObject#id}s.\n     */\n    getObjectIDsInSubtreeByType(types) {\n        const mask = {};\n        for (var i = 0, len = types.length; i < len; i++) {\n            mask[types[i]] = types[i];\n        }\n        const objectIds = [];\n\n        function visit(metaObject) {\n            if (!metaObject) {\n                return;\n            }\n            if (mask[metaObject.type]) {\n                objectIds.push(metaObject.id);\n            }\n            const children = metaObject.children;\n            if (children) {\n                for (var i = 0, len = children.length; i < len; i++) {\n                    visit(children[i]);\n                }\n            }\n        }\n\n        visit(this);\n        return objectIds;\n    }\n\n    /**\n     * Returns properties of this MeteObject as JSON.\n     *\n     * @returns {{id: (String|Number), type: String, name: String, parent: (String|Number|Undefined)}}\n     */\n    getJSON() {\n        var json = {\n            id: this.id,\n            type: this.type,\n            name: this.name\n        };\n        if (this.parent) {\n            json.parent = this.parent.id;\n        }\n        return json;\n    }\n}\n\n/**\n * @desc Metadata corresponding to an {@link Entity} that represents a model.\n *\n * An {@link Entity} represents a model when {@link Entity#isModel} is ````true````\n *\n * A MetaModel corresponds to an {@link Entity} by having the same {@link MetaModel#id} as the {@link Entity#id}.\n *\n * A MetaModel is created by {@link MetaScene#createMetaModel} and belongs to a {@link MetaScene}.\n *\n * Each MetaModel is registered by {@link MetaModel#id} in {@link MetaScene#metaModels}.\n *\n * A {@link MetaModel} represents its object structure with a tree of {@link MetaObject}s, with {@link MetaModel#rootMetaObject} referencing the root {@link MetaObject}.\n *\n * @class MetaModel\n */\nclass MetaModel {\n\n    /**\n     * Creates a new, unfinalized MetaModel.\n     *\n     * * The MetaModel is immediately registered by {@link MetaModel#id} in {@link MetaScene#metaModels}, even though it's not yet populated.\n     * * The MetaModel then needs to be populated with one or more calls to {@link metaModel#loadData}.\n     * * As we populate it, the MetaModel will create {@link MetaObject}s and {@link PropertySet}s in itself, and in the MetaScene.\n     * * When populated, call {@link MetaModel#finalize} to finish it off, which causes MetaScene to fire a \"metaModelCreated\" event.\n     */\n    constructor(params) {\n\n        /**\n         * Globally-unique ID.\n         *\n         * MetaModels are registered by ID in {@link MetaScene#metaModels}.\n         *\n         * When this MetaModel corresponds to an {@link Entity} then this ID will match the {@link Entity#id}.\n         *\n         * @property id\n         * @type {String|Number}\n         */\n        this.id = params.id;\n\n        /**\n         * The project ID\n         * @property projectId\n         * @type {String|Number}\n         */\n        this.projectId = params.projectId;\n\n        /**\n         * The revision ID, if available.\n         *\n         * Will be undefined if not available.\n         *\n         * @property revisionId\n         * @type {String|Number}\n         */\n        this.revisionId = params.revisionId;\n\n        /**\n         * The model author, if available.\n         *\n         * Will be undefined if not available.\n         *\n         * @property author\n         * @type {String}\n         */\n        this.author = params.author;\n\n        /**\n         * The date the model was created, if available.\n         *\n         * Will be undefined if not available.\n         *\n         * @property createdAt\n         * @type {String}\n         */\n        this.createdAt = params.createdAt;\n\n        /**\n         * The application that created the model, if available.\n         *\n         * Will be undefined if not available.\n         *\n         * @property creatingApplication\n         * @type {String}\n         */\n        this.creatingApplication = params.creatingApplication;\n\n        /**\n         * The model schema version, if available.\n         *\n         * Will be undefined if not available.\n         *\n         * @property schema\n         * @type {String}\n         */\n        this.schema = params.schema;\n\n        /**\n         * Metadata on the {@link Scene}.\n         *\n         * @property metaScene\n         * @type {MetaScene}\n         */\n        this.metaScene = params.metaScene;\n\n        /**\n         * The {@link PropertySet}s in this MetaModel.\n         *\n         * @property propertySets\n         * @type  {PropertySet[]}\n         */\n        this.propertySets = [];\n\n        /**\n         * The root {@link MetaObject}s in this MetaModel's composition structure hierarchy.\n         *\n         * @property rootMetaObject\n         * @type {MetaObject[]}\n         */\n        this.rootMetaObjects = [];\n\n        /**\n         * The {@link MetaObject}s in this MetaModel, each mapped to its ID.\n         *\n         * @property metaObjects\n         * @type  {{String:MetaObject}}\n         */\n        this.metaObjects = {};\n\n        /**\n         * Connectivity graph.\n         * @type {{}}\n         */\n        this.graph = params.graph || {};\n\n        this.metaScene.metaModels[this.id] = this;\n\n        this._propertyLookup = [];\n\n        /**\n         * True when this MetaModel has been finalized.\n         * @type {boolean}\n         */\n        this.finalized = false;\n    }\n\n    /**\n     * Backwards compatibility with the model having a single root MetaObject.\n     *\n     * @property rootMetaObject\n     * @type {MetaObject|null}\n     */\n    get rootMetaObject() {\n        if (this.rootMetaObjects.length === 1) {\n            return this.rootMetaObjects[0];\n        }\n        return null;\n    }\n\n    /**\n     * Load metamodel data into this MetaModel.\n     * @param metaModelData\n     */\n    loadData(metaModelData, options = {}) {\n\n        if (this.finalized) {\n            throw \"MetaScene already finalized - can't add more data\";\n        }\n\n        this._globalizeIDs(metaModelData, options);\n\n        const metaScene = this.metaScene;\n        const propertyLookup = metaModelData.properties;\n\n        if (propertyLookup) {\n            for (let i = 0, len = propertyLookup.length; i < len; i++) {\n                this._propertyLookup.push(propertyLookup[i]);\n            }\n        }\n\n        // Create global Property Sets\n\n        if (metaModelData.propertySets) {\n            for (let i = 0, len = metaModelData.propertySets.length; i < len; i++) {\n                const propertySetData = metaModelData.propertySets[i];\n                if (!propertySetData.properties) { // HACK: https://github.com/Creoox/creoox-ifc2gltfcxconverter/issues/8\n                    propertySetData.properties = [];\n                }\n                let propertySet = metaScene.propertySets[propertySetData.id];\n                if (!propertySet) {\n                    propertySet = new PropertySet({\n                        id: propertySetData.id,\n                        originalSystemId: propertySetData.originalSystemId || propertySetData.id,\n                        type: propertySetData.type,\n                        name: propertySetData.name,\n                        properties: propertySetData.properties\n                    });\n                    metaScene.propertySets[propertySet.id] = propertySet;\n                }\n                propertySet.metaModels.push(this);\n                this.propertySets.push(propertySet);\n            }\n        }\n\n        if (metaModelData.metaObjects) {\n            for (let i = 0, len = metaModelData.metaObjects.length; i < len; i++) {\n                const metaObjectData = metaModelData.metaObjects[i];\n                const id = metaObjectData.id;\n                let metaObject = metaScene.metaObjects[id];\n                if (!metaObject) {\n                    const type = metaObjectData.type;\n                    const originalSystemId = metaObjectData.originalSystemId;\n                    const propertySetIds = metaObjectData.propertySets || metaObjectData.propertySetIds;\n                    metaObject = new MetaObject({\n                        id,\n                        originalSystemId,\n                        parentId: metaObjectData.parent,\n                        type,\n                        name: metaObjectData.name,\n                        attributes: metaObjectData.attributes,\n                        propertySetIds,\n                        external: metaObjectData.external,\n                    });\n                    this.metaScene.metaObjects[id] = metaObject;\n                    metaObject.metaModels = [];\n                }\n                this.metaObjects[id] = metaObject;\n                if (!metaObjectData.parent) {\n                    this.rootMetaObjects.push(metaObject);\n                    metaScene.rootMetaObjects[id] = metaObject;\n                }\n                metaObject.metaModels.push(this);\n            }\n        }\n    }\n\n    _decompressProperties(propertyLookup, properties) {\n        const propsNotFound = [];\n        for (let i = 0, len = properties.length; i < len; i++) {\n            const property = properties[i];\n            if (Number.isInteger(property)) {\n                const lookupProperty = propertyLookup[property];\n                if (lookupProperty) {\n                    properties[i] = lookupProperty;\n                } else {\n                    propsNotFound.push(property);\n                }\n            }\n        }\n        if (propsNotFound.length > 0) {\n            console.error(`[MetaModel._decompressProperties] Properties not found: ${propsNotFound}`);\n        }\n    }\n\n    finalize() {\n\n        if (this.finalized) {\n            throw \"MetaScene already finalized - can't re-finalize\";\n        }\n\n        // Re-link MetaScene's entire MetaObject parent/child hierarchy\n\n        const metaScene = this.metaScene;\n\n        for (let objectId in metaScene.metaObjects) {\n            const metaObject = metaScene.metaObjects[objectId];\n            if (metaObject.children) {\n                metaObject.children = [];\n            }\n\n            // Re-link each MetaObject's property sets\n\n            if (metaObject.propertySets) {\n                metaObject.propertySets = [];\n            }\n            if (metaObject.propertySetIds) {\n                for (let i = 0, len = metaObject.propertySetIds.length; i < len; i++) {\n                    const propertySetId = metaObject.propertySetIds[i];\n                    const propertySet = metaScene.propertySets[propertySetId];\n                    metaObject.propertySets.push(propertySet);\n                }\n            }\n        }\n\n        for (let objectId in metaScene.metaObjects) {\n            const metaObject = metaScene.metaObjects[objectId];\n            if (metaObject.parentId) {\n                const parentMetaObject = metaScene.metaObjects[metaObject.parentId];\n                if (parentMetaObject) {\n                    metaObject.parent = parentMetaObject;\n                    (parentMetaObject.children || (parentMetaObject.children = [])).push(metaObject);\n                }\n            }\n        }\n\n        // Relink MetaObjects to their MetaModels\n\n        for (let objectId in metaScene.metaObjects) {\n            const metaObject = metaScene.metaObjects[objectId];\n            metaObject.metaModels = [];\n        }\n\n        for (let modelId in metaScene.metaModels) {\n            const metaModel = metaScene.metaModels[modelId];\n            for (let objectId in metaModel.metaObjects) {\n                const metaObject = metaModel.metaObjects[objectId];\n                metaObject.metaModels.push(metaModel);\n            }\n        }\n\n        // Rebuild MetaScene's MetaObjects-by-type lookup\n\n        metaScene.metaObjectsByType = {};\n        for (let objectId in metaScene.metaObjects) {\n            const metaObject = metaScene.metaObjects[objectId];\n            const type = metaObject.type;\n            (metaScene.metaObjectsByType[type] || (metaScene.metaObjectsByType[type] = {}))[objectId] = metaObject;\n        }\n\n        // Decompress properties\n\n        if (this.propertySets) {\n            for (let i = 0, len = this.propertySets.length; i < len; i++) {\n                const propertySet = this.propertySets[i];\n                this._decompressProperties(this._propertyLookup, propertySet.properties);\n            }\n        }\n\n\n        this._propertyLookup = [];\n\n        this.finalized = true;\n\n        this.metaScene.fire(\"metaModelCreated\", this.id);\n    }\n\n    /**\n     * Gets this MetaModel as JSON.\n     * @returns {{schema: (String|string|*), createdAt: (String|string|*), metaObjects: *[], author: (String|string|*), id: (String|Number|string|number|*), creatingApplication: (String|string|*), projectId: (String|Number|string|number|*), propertySets: *[]}}\n     */\n    getJSON() {\n        const json = {\n            id: this.id,\n            projectId: this.projectId,\n            author: this.author,\n            createdAt: this.createdAt,\n            schema: this.schema,\n            creatingApplication: this.creatingApplication,\n            metaObjects: [],\n            propertySets: []\n        };\n        const metaObjectsList = Object.values(this.metaObjects);\n        for (let i = 0, len = metaObjectsList.length; i < len; i++) {\n            const metaObject = metaObjectsList[i];\n            const metaObjectCfg = {\n                id: metaObject.id,\n                originalSystemId: metaObject.originalSystemId,\n                extId: metaObject.extId,\n                type: metaObject.type,\n                name: metaObject.name\n            };\n            if (metaObject.parent) {\n                metaObjectCfg.parent = metaObject.parent.id;\n            }\n            if (metaObject.attributes) {\n                metaObjectCfg.attributes = metaObject.attributes;\n            }\n            if (metaObject.propertySetIds) {\n                metaObjectCfg.propertySetIds = metaObject.propertySetIds;\n            }\n            json.metaObjects.push(metaObjectCfg);\n        }\n        for (let i = 0, len = this.propertySets.length; i < len; i++) {\n            const propertySet = this.propertySets[i];\n            const propertySetCfg = {\n                id: propertySet.id,\n                originalSystemId: propertySet.originalSystemId,\n                extId: propertySet.extId,\n                type: propertySet.type,\n                name: propertySet.name,\n                propertyies: []\n            };\n            for (let j = 0, lenj = propertySet.properties.length; j < lenj; j++) {\n                const property = propertySet.properties[j];\n                const propertyCfg = {\n                    id: property.id,\n                    description: property.description,\n                    type: property.type,\n                    name: property.name,\n                    value: property.value,\n                    valueType: property.valueType\n                };\n                propertySetCfg.properties.push(propertyCfg);\n            }\n            json.propertySets.push(propertySetCfg);\n        }\n        return json;\n    }\n\n    _globalizeIDs(metaModelData, options) {\n\n        const globalize = !!options.globalizeObjectIds;\n\n        if (metaModelData.metaObjects) {\n            for (let i = 0, len = metaModelData.metaObjects.length; i < len; i++) {\n                const metaObjectData = metaModelData.metaObjects[i];\n\n                // Globalize MetaObject IDs and parent IDs\n\n                metaObjectData.originalSystemId = metaObjectData.id;\n                if (metaObjectData.parent) {\n                    metaObjectData.originalParentSystemId = metaObjectData.parent;\n                }\n                if (globalize) {\n                    metaObjectData.id = math.globalizeObjectId(this.id, metaObjectData.id);\n                    if (metaObjectData.parent) {\n                        metaObjectData.parent = math.globalizeObjectId(this.id, metaObjectData.parent);\n                    }\n                }\n\n                // Globalize MetaObject property set IDs\n\n                if (globalize) {\n                    const propertySetIds = metaObjectData.propertySetIds;\n                    if (propertySetIds) {\n                        const propertySetGlobalIds = [];\n                        for (let j = 0, lenj = propertySetIds.length; j < lenj; j++) {\n                            propertySetGlobalIds.push(math.globalizeObjectId(this.id, propertySetIds[j]));\n                        }\n                        metaObjectData.propertySetIds = propertySetGlobalIds;\n                        metaObjectData.originalSystemPropertySetIds = propertySetIds;\n                    }\n                } else {\n                    metaObjectData.originalSystemPropertySetIds = metaObjectData.propertySetIds;\n                }\n            }\n        }\n\n        // Globalize global PropertySet IDs\n\n        if (metaModelData.propertySets) {\n            for (let i = 0, len = metaModelData.propertySets.length; i < len; i++) {\n                const propertySet = metaModelData.propertySets[i];\n                propertySet.originalSystemId = propertySet.id;\n                if (globalize) {\n                    propertySet.id = math.globalizeObjectId(this.id, propertySet.id);\n                }\n            }\n        }\n    }\n}\n\n/**\n * @desc Metadata corresponding to a {@link Scene}.\n *\n * * Located in {@link Viewer#metaScene}.\n * * Contains {@link MetaModel}s and {@link MetaObject}s.\n * * [Scene graph example with metadata](http://xeokit.github.io/xeokit-sdk/examples/index.html#sceneRepresentation_SceneGraph_metadata)\n */\nclass MetaScene {\n\n    /**\n     * @private\n     */\n    constructor(viewer, scene) {\n\n        /**\n         * The {@link Viewer}.\n         * @property viewer\n         * @type {Viewer}\n         */\n        this.viewer = viewer;\n\n        /**\n         * The {@link Scene}.\n         * @property scene\n         * @type {Scene}\n         */\n        this.scene = scene;\n\n        /**\n         * The {@link MetaModel}s belonging to this MetaScene, each mapped to its {@link MetaModel#modelId}.\n         *\n         * @type {{String:MetaModel}}\n         */\n        this.metaModels = {};\n\n        /**\n         * The {@link PropertySet}s belonging to this MetaScene, each mapped to its {@link PropertySet#id}.\n         *\n         * @type {{String:PropertySet}}\n         */\n        this.propertySets = {};\n\n        /**\n         * The {@link MetaObject}s belonging to this MetaScene, each mapped to its {@link MetaObject#id}.\n         *\n         * @type {{String:MetaObject}}\n         */\n        this.metaObjects = {};\n\n        /**\n         * The {@link MetaObject}s belonging to this MetaScene, each mapped to its {@link MetaObject#type}.\n         *\n         * @type {{String:MetaObject}}\n         */\n        this.metaObjectsByType = {};\n\n        /**\n         * The root {@link MetaObject}s belonging to this MetaScene, each mapped to its {@link MetaObject#id}.\n         *\n         * @type {{String:MetaObject}}\n         */\n        this.rootMetaObjects = {};\n\n        /**\n         * Subscriptions to events sent with {@link fire}.\n         * @private\n         */\n        this._eventSubs = {};\n    }\n\n    /**\n     * Subscribes to an event fired at this Viewer.\n     *\n     * @param {String} event The event\n     * @param {Function} callback Callback fired on the event\n     */\n    on(event, callback) {\n        let subs = this._eventSubs[event];\n        if (!subs) {\n            subs = [];\n            this._eventSubs[event] = subs;\n        }\n        subs.push(callback);\n    }\n\n    /**\n     * Fires an event at this Viewer.\n     *\n     * @param {String} event Event name\n     * @param {Object} value Event parameters\n     */\n    fire(event, value) {\n        const subs = this._eventSubs[event];\n        if (subs) {\n            for (let i = 0, len = subs.length; i < len; i++) {\n                subs[i](value);\n            }\n        }\n    }\n\n    /**\n     * Unsubscribes from an event fired at this Viewer.\n     * @param event\n     */\n    off(event) { // TODO\n\n    }\n\n    /**\n     * Creates a {@link MetaModel} in this MetaScene.\n     *\n     * The MetaModel will contain a hierarchy of {@link MetaObject}s, created from the\n     * meta objects in ````metaModelData````.\n     *\n     * The meta object hierarchy in ````metaModelData```` is expected to be non-cyclic, with a single root. If the meta\n     * objects are cyclic, then this method will log an error and attempt to recover by creating a dummy root MetaObject\n     * of type \"Model\" and connecting all other MetaObjects as its direct children. If the meta objects contain multiple\n     * roots, then this method similarly attempts to recover by creating a dummy root MetaObject of type \"Model\" and\n     * connecting all the root MetaObjects as its children.\n     *\n     * @param {String} modelId ID for the new {@link MetaModel}, which will have {@link MetaModel#id} set to this value.\n     * @param {Object} metaModelData Data for the {@link MetaModel}.\n     * @param {Object} [options] Options for creating the {@link MetaModel}.\n     * @param {Boolean} [options.globalizeObjectIds=false] Whether to globalize each {@link MetaObject#id}. Set this ````true```` when you need to load multiple instances of the same meta model, to avoid ID clashes between the meta objects in the different instances.\n     * @returns {MetaModel} The new MetaModel.\n     */\n    createMetaModel(modelId, metaModelData, options = {}) {\n\n        const metaModel = new MetaModel({ // Registers MetaModel in #metaModels\n            metaScene: this,\n            id: modelId,\n            projectId: metaModelData.projectId || \"none\",\n            revisionId: metaModelData.revisionId || \"none\",\n            author: metaModelData.author || \"none\",\n            createdAt: metaModelData.createdAt || \"none\",\n            creatingApplication: metaModelData.creatingApplication || \"none\",\n            schema: metaModelData.schema || \"none\",\n            propertySets: []\n        });\n\n        metaModel.loadData(metaModelData);\n\n        metaModel.finalize();\n\n        return metaModel;\n    }\n\n    /**\n     * Removes a {@link MetaModel} from this MetaScene.\n     *\n     * Fires a \"metaModelDestroyed\" event with the value of the {@link MetaModel#id}.\n     *\n     * @param {String} metaModelId ID of the target {@link MetaModel}.\n     */\n    destroyMetaModel(metaModelId) {\n\n        const metaModel = this.metaModels[metaModelId];\n        if (!metaModel) {\n            return;\n        }\n\n        // Remove global PropertySets\n\n        if (metaModel.propertySets) {\n            for (let i = 0, len = metaModel.propertySets.length; i < len; i++) {\n                const propertySet = metaModel.propertySets[i];\n                if (propertySet.metaModels.length === 1 && propertySet.metaModels[0].id === metaModelId) { // Property set owned only by this model, delete\n                    delete this.propertySets[propertySet.id];\n                } else {\n                    const newMetaModels = [];\n                    for (let j = 0, lenj = propertySet.metaModels.length; j < lenj; j++) {\n                        if (propertySet.metaModels[j].id !== metaModelId) {\n                            newMetaModels.push(propertySet.metaModels[j]);\n                        }\n                    }\n                    propertySet.metaModels = newMetaModels;\n                }\n            }\n        }\n\n        // Remove MetaObjects\n\n        if (metaModel.metaObjects) {\n            for (let objectId in metaModel.metaObjects) {\n                const metaObject = metaModel.metaObjects[objectId];\n                if (metaObject.metaModels.length === 1 && metaObject.metaModels[0].id === metaModelId) { // MetaObject owned only by this model, delete\n                    delete this.metaObjects[objectId];\n                    if (!metaObject.parent) {\n                        delete this.rootMetaObjects[objectId];\n                    }\n                } else {\n                    metaObject.metaModels = metaObject.metaModels.filter(metaModel => metaModel.id !== metaModelId);\n                }\n            }\n        }\n\n        // Re-link entire MetaObject parent/child hierarchy\n\n        for (let objectId in this.metaObjects) {\n            const metaObject = this.metaObjects[objectId];\n            if (metaObject.children) {\n                metaObject.children = [];\n            }\n\n            // Re-link each MetaObject's property sets\n\n            if (metaObject.propertySets) {\n                metaObject.propertySets = [];\n            }\n            if (metaObject.propertySetIds) {\n                for (let i = 0, len = metaObject.propertySetIds.length; i < len; i++) {\n                    const propertySetId = metaObject.propertySetIds[i];\n                    const propertySet = this.propertySets[propertySetId];\n                    metaObject.propertySets.push(propertySet);\n                }\n            }\n        }\n\n        this.metaObjectsByType = {};\n\n        for (let objectId in this.metaObjects) {\n            const metaObject = this.metaObjects[objectId];\n            const type = metaObject.type;\n            if (metaObject.children) {\n                metaObject.children = null;\n            }\n            (this.metaObjectsByType[type] || (this.metaObjectsByType[type] = {}))[objectId] = metaObject;\n        }\n\n        for (let objectId in this.metaObjects) {\n            const metaObject = this.metaObjects[objectId];\n            if (metaObject.parentId) {\n                const parentMetaObject = this.metaObjects[metaObject.parentId];\n                if (parentMetaObject) {\n                    metaObject.parent = parentMetaObject;\n                    (parentMetaObject.children || (parentMetaObject.children = [])).push(metaObject);\n                }\n            }\n        }\n\n        delete this.metaModels[metaModelId];\n\n        // Relink MetaObjects to their MetaModels\n\n        for (let objectId in this.metaObjects) {\n            const metaObject = this.metaObjects[objectId];\n            metaObject.metaModels = [];\n        }\n\n        for (let modelId in this.metaModels) {\n            const metaModel = this.metaModels[modelId];\n            for (let objectId in metaModel.metaObjects) {\n                const metaObject = metaModel.metaObjects[objectId];\n                metaObject.metaModels.push(metaModel);\n            }\n        }\n\n        this.fire(\"metaModelDestroyed\", metaModelId);\n    }\n\n    /**\n     * Gets the {@link MetaObject#id}s of the {@link MetaObject}s that have the given {@link MetaObject#type}.\n     *\n     * @param {String} type The type.\n     * @returns {String[]} Array of {@link MetaObject#id}s.\n     */\n    getObjectIDsByType(type) {\n        const metaObjects = this.metaObjectsByType[type];\n        return metaObjects ? Object.keys(metaObjects) : [];\n    }\n\n    /**\n     * Gets the {@link MetaObject#id}s of the {@link MetaObject}s within the given subtree.\n     *\n     * @param {String} id  ID of the root {@link MetaObject} of the given subtree.\n     * @param {String[]} [includeTypes] Optional list of types to include.\n     * @param {String[]} [excludeTypes] Optional list of types to exclude.\n     * @returns {String[]} Array of {@link MetaObject#id}s.\n     */\n    getObjectIDsInSubtree(id, includeTypes, excludeTypes) {\n\n        const list = [];\n        const metaObject = this.metaObjects[id];\n        const includeMask = (includeTypes && includeTypes.length > 0) ? arrayToMap(includeTypes) : null;\n        const excludeMask = (excludeTypes && excludeTypes.length > 0) ? arrayToMap(excludeTypes) : null;\n\n        const visit = (metaObject) => {\n            if (!metaObject) {\n                return;\n            }\n            var include = true;\n            if (excludeMask && excludeMask[metaObject.type]) {\n                include = false;\n            } else if (includeMask && (!includeMask[metaObject.type])) {\n                include = false;\n            }\n            if (include) {\n                list.push(metaObject.id);\n            }\n            const children = metaObject.children;\n            if (children) {\n                for (var i = 0, len = children.length; i < len; i++) {\n                    visit(children[i]);\n                }\n            }\n        };\n\n        visit(metaObject);\n        return list;\n    }\n\n    /**\n     * Iterates over the {@link MetaObject}s within the subtree.\n     *\n     * @param {String} id ID of root {@link MetaObject}.\n     * @param {Function} callback Callback fired at each {@link MetaObject}.\n     */\n    withMetaObjectsInSubtree(id, callback) {\n        const metaObject = this.metaObjects[id];\n        if (!metaObject) {\n            return;\n        }\n        metaObject.withMetaObjectsInSubtree(callback);\n    }\n}\n\nfunction arrayToMap(array) {\n    const map = {};\n    for (var i = 0, len = array.length; i < len; i++) {\n        map[array[i]] = true;\n    }\n    return map;\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n/**\n * Parses `data` using a specified loader\n * @param data\n * @param loaders\n * @param options\n * @param context\n */\n// implementation signature\nasync function parseFromContext(data, loaders, options, context) {\n    return context._parse(data, loaders, options, context);\n}\n\n/**\n * Throws an `Error` with the optional `message` if `condition` is falsy\n * @note Replacement for the external assert method to reduce bundle size\n */\nfunction assert$4(condition, message) {\n    if (!condition) {\n        throw new Error(message || 'loader assertion failed.');\n    }\n}\n\n// Purpose: include this in your module to avoid\n/** true if running in a browser */\nconst isBrowser$2 = \n// @ts-ignore process does not exist on browser\nBoolean(typeof process !== 'object' || String(process) !== '[object process]' || process.browser);\n// Extract node major version\nconst matches$1 = typeof process !== 'undefined' && process.version && /v([0-9]*)/.exec(process.version);\n/** Major Node version (as a number) */\n(matches$1 && parseFloat(matches$1[1])) || 0;\n\n// Do not name these variables the same as the global objects - will break bundling\nconst window_ = globalThis;\nconst process_ = globalThis.process || {};\n\n// based on https://github.com/cheton/is-electron\n// https://github.com/electron/electron/issues/2288\n/* eslint-disable complexity */\nfunction isElectron(mockUserAgent) {\n    // Renderer process\n    // @ts-expect-error\n    if (typeof window !== 'undefined' && window.process?.type === 'renderer') {\n        return true;\n    }\n    // Main process\n    // eslint-disable-next-line\n    if (typeof process !== 'undefined' && Boolean(process.versions?.['electron'])) {\n        return true;\n    }\n    // Detect the user agent when the `nodeIntegration` option is set to true\n    const realUserAgent = typeof navigator !== 'undefined' && navigator.userAgent;\n    const userAgent = mockUserAgent || realUserAgent;\n    return Boolean(userAgent && userAgent.indexOf('Electron') >= 0);\n}\n\n// This function is needed in initialization stages,\n/** Check if in browser by duck-typing Node context */\nfunction isBrowser$1() {\n    const isNode = \n    // @ts-expect-error\n    typeof process === 'object' && String(process) === '[object process]' && !process?.browser;\n    return !isNode || isElectron();\n}\n\n// Extract injected version from package.json (injected by babel plugin)\n// @ts-expect-error\nconst VERSION$7 = \"4.1.0\" ;\n// TODO - wish we could just export a constant\n// export const isBrowser = checkIfBrowser();\n\n// probe.gl, MIT license\nfunction getStorage(type) {\n    try {\n        const storage = window[type];\n        const x = '__storage_test__';\n        storage.setItem(x, x);\n        storage.removeItem(x);\n        return storage;\n    }\n    catch (e) {\n        return null;\n    }\n}\n// Store keys in local storage via simple interface\nclass LocalStorage {\n    constructor(id, defaultConfig, type = 'sessionStorage') {\n        this.storage = getStorage(type);\n        this.id = id;\n        this.config = defaultConfig;\n        this._loadConfiguration();\n    }\n    getConfiguration() {\n        return this.config;\n    }\n    setConfiguration(configuration) {\n        Object.assign(this.config, configuration);\n        if (this.storage) {\n            const serialized = JSON.stringify(this.config);\n            this.storage.setItem(this.id, serialized);\n        }\n    }\n    // Get config from persistent store, if available\n    _loadConfiguration() {\n        let configuration = {};\n        if (this.storage) {\n            const serializedConfiguration = this.storage.getItem(this.id);\n            configuration = serializedConfiguration ? JSON.parse(serializedConfiguration) : {};\n        }\n        Object.assign(this.config, configuration);\n        return this;\n    }\n}\n\n// probe.gl, MIT license\n/**\n * Format time\n */\nfunction formatTime(ms) {\n    let formatted;\n    if (ms < 10) {\n        formatted = `${ms.toFixed(2)}ms`;\n    }\n    else if (ms < 100) {\n        formatted = `${ms.toFixed(1)}ms`;\n    }\n    else if (ms < 1000) {\n        formatted = `${ms.toFixed(0)}ms`;\n    }\n    else {\n        formatted = `${(ms / 1000).toFixed(2)}s`;\n    }\n    return formatted;\n}\nfunction leftPad(string, length = 8) {\n    const padLength = Math.max(length - string.length, 0);\n    return `${' '.repeat(padLength)}${string}`;\n}\n\nvar COLOR;\n(function (COLOR) {\n    COLOR[COLOR[\"BLACK\"] = 30] = \"BLACK\";\n    COLOR[COLOR[\"RED\"] = 31] = \"RED\";\n    COLOR[COLOR[\"GREEN\"] = 32] = \"GREEN\";\n    COLOR[COLOR[\"YELLOW\"] = 33] = \"YELLOW\";\n    COLOR[COLOR[\"BLUE\"] = 34] = \"BLUE\";\n    COLOR[COLOR[\"MAGENTA\"] = 35] = \"MAGENTA\";\n    COLOR[COLOR[\"CYAN\"] = 36] = \"CYAN\";\n    COLOR[COLOR[\"WHITE\"] = 37] = \"WHITE\";\n    COLOR[COLOR[\"BRIGHT_BLACK\"] = 90] = \"BRIGHT_BLACK\";\n    COLOR[COLOR[\"BRIGHT_RED\"] = 91] = \"BRIGHT_RED\";\n    COLOR[COLOR[\"BRIGHT_GREEN\"] = 92] = \"BRIGHT_GREEN\";\n    COLOR[COLOR[\"BRIGHT_YELLOW\"] = 93] = \"BRIGHT_YELLOW\";\n    COLOR[COLOR[\"BRIGHT_BLUE\"] = 94] = \"BRIGHT_BLUE\";\n    COLOR[COLOR[\"BRIGHT_MAGENTA\"] = 95] = \"BRIGHT_MAGENTA\";\n    COLOR[COLOR[\"BRIGHT_CYAN\"] = 96] = \"BRIGHT_CYAN\";\n    COLOR[COLOR[\"BRIGHT_WHITE\"] = 97] = \"BRIGHT_WHITE\";\n})(COLOR || (COLOR = {}));\nconst BACKGROUND_INCREMENT = 10;\nfunction getColor(color) {\n    if (typeof color !== 'string') {\n        return color;\n    }\n    color = color.toUpperCase();\n    return COLOR[color] || COLOR.WHITE;\n}\nfunction addColor(string, color, background) {\n    if (!isBrowser$1 && typeof string === 'string') {\n        if (color) {\n            const colorCode = getColor(color);\n            string = `\\u001b[${colorCode}m${string}\\u001b[39m`;\n        }\n        if (background) {\n            // background colors values are +10\n            const colorCode = getColor(background);\n            string = `\\u001b[${colorCode + BACKGROUND_INCREMENT}m${string}\\u001b[49m`;\n        }\n    }\n    return string;\n}\n\n// Copyright (c) 2015 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n/**\n * Binds the \"this\" argument of all functions on a class instance to the instance\n * @param obj - class instance (typically a react component)\n */\nfunction autobind(obj, predefined = ['constructor']) {\n    const proto = Object.getPrototypeOf(obj);\n    const propNames = Object.getOwnPropertyNames(proto);\n    const object = obj;\n    for (const key of propNames) {\n        const value = object[key];\n        if (typeof value === 'function') {\n            if (!predefined.find((name) => key === name)) {\n                object[key] = value.bind(obj);\n            }\n        }\n    }\n}\n\nfunction assert$3(condition, message) {\n    if (!condition) {\n        throw new Error(message || 'Assertion failed');\n    }\n}\n\n// probe.gl, MIT license\n/** Get best timer available. */\nfunction getHiResTimestamp() {\n    let timestamp;\n    if (isBrowser$1() && window_.performance) {\n        timestamp = window_?.performance?.now?.();\n    }\n    else if ('hrtime' in process_) {\n        // @ts-ignore\n        const timeParts = process_?.hrtime?.();\n        timestamp = timeParts[0] * 1000 + timeParts[1] / 1e6;\n    }\n    else {\n        timestamp = Date.now();\n    }\n    return timestamp;\n}\n\n// probe.gl, MIT license\n// Instrumentation in other packages may override console methods, so preserve them here\nconst originalConsole = {\n    debug: isBrowser$1() ? console.debug || console.log : console.log,\n    log: console.log,\n    info: console.info,\n    warn: console.warn,\n    error: console.error\n};\nconst DEFAULT_LOG_CONFIGURATION = {\n    enabled: true,\n    level: 0\n};\nfunction noop() { } // eslint-disable-line @typescript-eslint/no-empty-function\nconst cache = {};\nconst ONCE = { once: true };\n/** A console wrapper */\nclass Log {\n    constructor({ id } = { id: '' }) {\n        this.VERSION = VERSION$7;\n        this._startTs = getHiResTimestamp();\n        this._deltaTs = getHiResTimestamp();\n        this.userData = {};\n        // TODO - fix support from throttling groups\n        this.LOG_THROTTLE_TIMEOUT = 0; // Time before throttled messages are logged again\n        this.id = id;\n        this.userData = {};\n        this._storage = new LocalStorage(`__probe-${this.id}__`, DEFAULT_LOG_CONFIGURATION);\n        this.timeStamp(`${this.id} started`);\n        autobind(this);\n        Object.seal(this);\n    }\n    set level(newLevel) {\n        this.setLevel(newLevel);\n    }\n    get level() {\n        return this.getLevel();\n    }\n    isEnabled() {\n        return this._storage.config.enabled;\n    }\n    getLevel() {\n        return this._storage.config.level;\n    }\n    /** @return milliseconds, with fractions */\n    getTotal() {\n        return Number((getHiResTimestamp() - this._startTs).toPrecision(10));\n    }\n    /** @return milliseconds, with fractions */\n    getDelta() {\n        return Number((getHiResTimestamp() - this._deltaTs).toPrecision(10));\n    }\n    /** @deprecated use logLevel */\n    set priority(newPriority) {\n        this.level = newPriority;\n    }\n    /** @deprecated use logLevel */\n    get priority() {\n        return this.level;\n    }\n    /** @deprecated use logLevel */\n    getPriority() {\n        return this.level;\n    }\n    // Configure\n    enable(enabled = true) {\n        this._storage.setConfiguration({ enabled });\n        return this;\n    }\n    setLevel(level) {\n        this._storage.setConfiguration({ level });\n        return this;\n    }\n    /** return the current status of the setting */\n    get(setting) {\n        return this._storage.config[setting];\n    }\n    // update the status of the setting\n    set(setting, value) {\n        this._storage.setConfiguration({ [setting]: value });\n    }\n    /** Logs the current settings as a table */\n    settings() {\n        if (console.table) {\n            console.table(this._storage.config);\n        }\n        else {\n            console.log(this._storage.config);\n        }\n    }\n    // Unconditional logging\n    assert(condition, message) {\n        if (!condition) {\n            throw new Error(message || 'Assertion failed');\n        }\n    }\n    warn(message) {\n        return this._getLogFunction(0, message, originalConsole.warn, arguments, ONCE);\n    }\n    error(message) {\n        return this._getLogFunction(0, message, originalConsole.error, arguments);\n    }\n    /** Print a deprecation warning */\n    deprecated(oldUsage, newUsage) {\n        return this.warn(`\\`${oldUsage}\\` is deprecated and will be removed \\\nin a later version. Use \\`${newUsage}\\` instead`);\n    }\n    /** Print a removal warning */\n    removed(oldUsage, newUsage) {\n        return this.error(`\\`${oldUsage}\\` has been removed. Use \\`${newUsage}\\` instead`);\n    }\n    probe(logLevel, message) {\n        return this._getLogFunction(logLevel, message, originalConsole.log, arguments, {\n            time: true,\n            once: true\n        });\n    }\n    log(logLevel, message) {\n        return this._getLogFunction(logLevel, message, originalConsole.debug, arguments);\n    }\n    info(logLevel, message) {\n        return this._getLogFunction(logLevel, message, console.info, arguments);\n    }\n    once(logLevel, message) {\n        return this._getLogFunction(logLevel, message, originalConsole.debug || originalConsole.info, arguments, ONCE);\n    }\n    /** Logs an object as a table */\n    table(logLevel, table, columns) {\n        if (table) {\n            return this._getLogFunction(logLevel, table, console.table || noop, (columns && [columns]), {\n                tag: getTableHeader(table)\n            });\n        }\n        return noop;\n    }\n    time(logLevel, message) {\n        return this._getLogFunction(logLevel, message, console.time ? console.time : console.info);\n    }\n    timeEnd(logLevel, message) {\n        return this._getLogFunction(logLevel, message, console.timeEnd ? console.timeEnd : console.info);\n    }\n    timeStamp(logLevel, message) {\n        return this._getLogFunction(logLevel, message, console.timeStamp || noop);\n    }\n    group(logLevel, message, opts = { collapsed: false }) {\n        const options = normalizeArguments({ logLevel, message, opts });\n        const { collapsed } = opts;\n        // @ts-expect-error\n        options.method = (collapsed ? console.groupCollapsed : console.group) || console.info;\n        return this._getLogFunction(options);\n    }\n    groupCollapsed(logLevel, message, opts = {}) {\n        return this.group(logLevel, message, Object.assign({}, opts, { collapsed: true }));\n    }\n    groupEnd(logLevel) {\n        return this._getLogFunction(logLevel, '', console.groupEnd || noop);\n    }\n    // EXPERIMENTAL\n    withGroup(logLevel, message, func) {\n        this.group(logLevel, message)();\n        try {\n            func();\n        }\n        finally {\n            this.groupEnd(logLevel)();\n        }\n    }\n    trace() {\n        if (console.trace) {\n            console.trace();\n        }\n    }\n    // PRIVATE METHODS\n    /** Deduces log level from a variety of arguments */\n    _shouldLog(logLevel) {\n        return this.isEnabled() && this.getLevel() >= normalizeLogLevel(logLevel);\n    }\n    _getLogFunction(logLevel, message, method, args, opts) {\n        if (this._shouldLog(logLevel)) {\n            // normalized opts + timings\n            opts = normalizeArguments({ logLevel, message, args, opts });\n            method = method || opts.method;\n            assert$3(method);\n            opts.total = this.getTotal();\n            opts.delta = this.getDelta();\n            // reset delta timer\n            this._deltaTs = getHiResTimestamp();\n            const tag = opts.tag || opts.message;\n            if (opts.once && tag) {\n                if (!cache[tag]) {\n                    cache[tag] = getHiResTimestamp();\n                }\n                else {\n                    return noop;\n                }\n            }\n            // TODO - Make throttling work with groups\n            // if (opts.nothrottle || !throttle(tag, this.LOG_THROTTLE_TIMEOUT)) {\n            //   return noop;\n            // }\n            message = decorateMessage(this.id, opts.message, opts);\n            // Bind console function so that it can be called after being returned\n            return method.bind(console, message, ...opts.args);\n        }\n        return noop;\n    }\n}\nLog.VERSION = VERSION$7;\n/**\n * Get logLevel from first argument:\n * - log(logLevel, message, args) => logLevel\n * - log(message, args) => 0\n * - log({logLevel, ...}, message, args) => logLevel\n * - log({logLevel, message, args}) => logLevel\n */\nfunction normalizeLogLevel(logLevel) {\n    if (!logLevel) {\n        return 0;\n    }\n    let resolvedLevel;\n    switch (typeof logLevel) {\n        case 'number':\n            resolvedLevel = logLevel;\n            break;\n        case 'object':\n            // Backward compatibility\n            // TODO - deprecate `priority`\n            // @ts-expect-error\n            resolvedLevel = logLevel.logLevel || logLevel.priority || 0;\n            break;\n        default:\n            return 0;\n    }\n    // 'log level must be a number'\n    assert$3(Number.isFinite(resolvedLevel) && resolvedLevel >= 0);\n    return resolvedLevel;\n}\n/**\n * \"Normalizes\" the various argument patterns into an object with known types\n * - log(logLevel, message, args) => {logLevel, message, args}\n * - log(message, args) => {logLevel: 0, message, args}\n * - log({logLevel, ...}, message, args) => {logLevel, message, args}\n * - log({logLevel, message, args}) => {logLevel, message, args}\n */\nfunction normalizeArguments(opts) {\n    const { logLevel, message } = opts;\n    opts.logLevel = normalizeLogLevel(logLevel);\n    // We use `arguments` instead of rest parameters (...args) because IE\n    // does not support the syntax. Rest parameters is transpiled to code with\n    // perf impact. Doing it here instead avoids constructing args when logging is\n    // disabled.\n    // TODO - remove when/if IE support is dropped\n    const args = opts.args ? Array.from(opts.args) : [];\n    // args should only contain arguments that appear after `message`\n    // eslint-disable-next-line no-empty\n    while (args.length && args.shift() !== message) { }\n    switch (typeof logLevel) {\n        case 'string':\n        case 'function':\n            if (message !== undefined) {\n                args.unshift(message);\n            }\n            opts.message = logLevel;\n            break;\n        case 'object':\n            Object.assign(opts, logLevel);\n            break;\n    }\n    // Resolve functions into strings by calling them\n    if (typeof opts.message === 'function') {\n        opts.message = opts.message();\n    }\n    const messageType = typeof opts.message;\n    // 'log message must be a string' or object\n    assert$3(messageType === 'string' || messageType === 'object');\n    // original opts + normalized opts + opts arg + fixed up message\n    return Object.assign(opts, { args }, opts.opts);\n}\nfunction decorateMessage(id, message, opts) {\n    if (typeof message === 'string') {\n        const time = opts.time ? leftPad(formatTime(opts.total)) : '';\n        message = opts.time ? `${id}: ${time}  ${message}` : `${id}: ${message}`;\n        message = addColor(message, opts.color, opts.background);\n    }\n    return message;\n}\nfunction getTableHeader(table) {\n    for (const key in table) {\n        for (const title in table[key]) {\n            return title || 'untitled';\n        }\n    }\n    return 'empty';\n}\n\n// loaders.gl\n// Version constant cannot be imported, it needs to correspond to the build version of **this** module.\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION$6 = \"4.3.3\" ;\nconst version = VERSION$6[0] >= '0' && VERSION$6[0] <= '9' ? `v${VERSION$6}` : '';\n// Make sure we set the global variable\nfunction createLog() {\n    const log = new Log({ id: 'loaders.gl' });\n    globalThis.loaders = globalThis.loaders || {};\n    globalThis.loaders.log = log;\n    globalThis.loaders.version = version;\n    globalThis.probe = globalThis.probe || {};\n    globalThis.probe.loaders = log;\n    return log;\n}\nconst log = createLog();\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n/**\n *\n * @param baseOptions Can be undefined, in which case a fresh options object will be minted\n * @param newOptions\n * @returns\n */\nfunction mergeLoaderOptions(baseOptions, newOptions) {\n    return mergeOptionsRecursively(baseOptions || {}, newOptions);\n}\nfunction mergeOptionsRecursively(baseOptions, newOptions, level = 0) {\n    // Sanity check (jest test runner overwrites the console object which can lead to infinite recursion)\n    if (level > 3) {\n        return newOptions;\n    }\n    const options = { ...baseOptions };\n    for (const [key, newValue] of Object.entries(newOptions)) {\n        if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n            options[key] = mergeOptionsRecursively(options[key] || {}, newOptions[key], level + 1);\n            // Object.assign(options[key] as object, newOptions[key]);\n        }\n        else {\n            options[key] = newOptions[key];\n        }\n    }\n    return options;\n}\n\n// loaders.gl\n/**\n * Register application-imported modules\n * These modules are typically to big to bundle, or may have issues on some bundlers/environments\n */\nfunction registerJSModules(modules) {\n    globalThis.loaders ||= {};\n    globalThis.loaders.modules ||= {};\n    Object.assign(globalThis.loaders.modules, modules);\n}\n/**\n * Get a pre-registered application-imported module, return null if not present\n */\nfunction getJSModuleOrNull(name) {\n    const module = globalThis.loaders?.modules?.[name];\n    return module || null;\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n// Version constant cannot be imported, it needs to correspond to the build version of **this** module.\n/**\n * TODO - unpkg.com doesn't seem to have a `latest` specifier for alpha releases...\n * 'beta' on beta branch, 'latest' on prod branch\n */\nconst NPM_TAG = 'latest';\nfunction getVersion() {\n    if (!globalThis._loadersgl_?.version) {\n        globalThis._loadersgl_ = globalThis._loadersgl_ || {};\n        // __VERSION__ is injected by babel-plugin-version-inline\n        {\n            globalThis._loadersgl_.version = \"4.3.3\";\n        }\n    }\n    return globalThis._loadersgl_.version;\n}\nconst VERSION$5 = getVersion();\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n// Replacement for the external assert method to reduce bundle size\n// Note: We don't use the second \"message\" argument in calling code,\n// so no need to support it here\n/** Throws an `Error` with the optional `message` if `condition` is falsy */\nfunction assert$2(condition, message) {\n    if (!condition) {\n        throw new Error(message || 'loaders.gl assertion failed.');\n    }\n}\n\n// loaders.gl\n/** true if running in the browser, false if running in Node.js */\nconst isBrowser = \n// @ts-ignore process.browser\ntypeof process !== 'object' || String(process) !== '[object process]' || process.browser;\n/** true if running on a worker thread */\nconst isWorker = typeof importScripts === 'function';\n/** true if running on a mobile device */\nconst isMobile = typeof window !== 'undefined' && typeof window.orientation !== 'undefined';\n// Extract node major version\nconst matches = typeof process !== 'undefined' && process.version && /v([0-9]*)/.exec(process.version);\n/** Version of Node.js if running under Node, otherwise 0 */\n(matches && parseFloat(matches[1])) || 0;\n\n// loaders.gl\n/**\n * Represents one Job handled by a WorkerPool or WorkerFarm\n */\nclass WorkerJob {\n    name;\n    workerThread;\n    isRunning = true;\n    /** Promise that resolves when Job is done */\n    result;\n    _resolve = () => { };\n    _reject = () => { };\n    constructor(jobName, workerThread) {\n        this.name = jobName;\n        this.workerThread = workerThread;\n        this.result = new Promise((resolve, reject) => {\n            this._resolve = resolve;\n            this._reject = reject;\n        });\n    }\n    /**\n     * Send a message to the job's worker thread\n     * @param data any data structure, ideally consisting mostly of transferrable objects\n     */\n    postMessage(type, payload) {\n        this.workerThread.postMessage({\n            source: 'loaders.gl', // Lets worker ignore unrelated messages\n            type,\n            payload\n        });\n    }\n    /**\n     * Call to resolve the `result` Promise with the supplied value\n     */\n    done(value) {\n        assert$2(this.isRunning);\n        this.isRunning = false;\n        this._resolve(value);\n    }\n    /**\n     * Call to reject the `result` Promise with the supplied error\n     */\n    error(error) {\n        assert$2(this.isRunning);\n        this.isRunning = false;\n        this._reject(error);\n    }\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n/** Browser polyfill for Node.js built-in `worker_threads` module.\n * These fills are non-functional, and just intended to ensure that\n * `import 'worker_threads` doesn't break browser builds.\n * The replacement is done in package.json browser field\n */\nclass NodeWorker {\n    terminate() { }\n}\n\n// loaders.gl\nconst workerURLCache = new Map();\n/**\n * Creates a loadable URL from worker source or URL\n * that can be used to create `Worker` instances.\n * Due to CORS issues it may be necessary to wrap a URL in a small importScripts\n * @param props\n * @param props.source Worker source\n * @param props.url Worker URL\n * @returns loadable url\n */\nfunction getLoadableWorkerURL(props) {\n    assert$2((props.source && !props.url) || (!props.source && props.url)); // Either source or url must be defined\n    let workerURL = workerURLCache.get(props.source || props.url);\n    if (!workerURL) {\n        // Differentiate worker urls from worker source code\n        if (props.url) {\n            workerURL = getLoadableWorkerURLFromURL(props.url);\n            workerURLCache.set(props.url, workerURL);\n        }\n        if (props.source) {\n            workerURL = getLoadableWorkerURLFromSource(props.source);\n            workerURLCache.set(props.source, workerURL);\n        }\n    }\n    assert$2(workerURL);\n    return workerURL;\n}\n/**\n * Build a loadable worker URL from worker URL\n * @param url\n * @returns loadable URL\n */\nfunction getLoadableWorkerURLFromURL(url) {\n    // A local script url, we can use it to initialize a Worker directly\n    if (!url.startsWith('http')) {\n        return url;\n    }\n    // A remote script, we need to use `importScripts` to load from different origin\n    const workerSource = buildScriptSource(url);\n    return getLoadableWorkerURLFromSource(workerSource);\n}\n/**\n * Build a loadable worker URL from worker source\n * @param workerSource\n * @returns loadable url\n */\nfunction getLoadableWorkerURLFromSource(workerSource) {\n    const blob = new Blob([workerSource], { type: 'application/javascript' });\n    return URL.createObjectURL(blob);\n}\n/**\n * Per spec, worker cannot be initialized with a script from a different origin\n * However a local worker script can still import scripts from other origins,\n * so we simply build a wrapper script.\n *\n * @param workerUrl\n * @returns source\n */\nfunction buildScriptSource(workerUrl) {\n    return `\\\ntry {\n  importScripts('${workerUrl}');\n} catch (error) {\n  console.error(error);\n  throw error;\n}`;\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n// NOTE - there is a copy of this function is both in core and loader-utils\n// core does not need all the utils in loader-utils, just this one.\n/**\n * Returns an array of Transferrable objects that can be used with postMessage\n * https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage\n * @param object data to be sent via postMessage\n * @param recursive - not for application use\n * @param transfers - not for application use\n * @returns a transfer list that can be passed to postMessage\n */\nfunction getTransferList(object, recursive = true, transfers) {\n    // Make sure that items in the transfer list is unique\n    const transfersSet = transfers || new Set();\n    if (!object) ;\n    else if (isTransferable(object)) {\n        transfersSet.add(object);\n    }\n    else if (isTransferable(object.buffer)) {\n        // Typed array\n        transfersSet.add(object.buffer);\n    }\n    else if (ArrayBuffer.isView(object)) ;\n    else if (recursive && typeof object === 'object') {\n        for (const key in object) {\n            // Avoid perf hit - only go one level deep\n            getTransferList(object[key], recursive, transfersSet);\n        }\n    }\n    // If transfers is defined, is internal recursive call\n    // Otherwise it's called by the user\n    return transfers === undefined ? Array.from(transfersSet) : [];\n}\n// https://developer.mozilla.org/en-US/docs/Web/API/Transferable\nfunction isTransferable(object) {\n    if (!object) {\n        return false;\n    }\n    if (object instanceof ArrayBuffer) {\n        return true;\n    }\n    if (typeof MessagePort !== 'undefined' && object instanceof MessagePort) {\n        return true;\n    }\n    if (typeof ImageBitmap !== 'undefined' && object instanceof ImageBitmap) {\n        return true;\n    }\n    // @ts-ignore\n    if (typeof OffscreenCanvas !== 'undefined' && object instanceof OffscreenCanvas) {\n        return true;\n    }\n    return false;\n}\n\n// loaders.gl\nconst NOOP = () => { };\n/**\n * Represents one worker thread\n */\nclass WorkerThread {\n    name;\n    source;\n    url;\n    terminated = false;\n    worker;\n    onMessage;\n    onError;\n    _loadableURL = '';\n    /** Checks if workers are supported on this platform */\n    static isSupported() {\n        return ((typeof Worker !== 'undefined' && isBrowser) ||\n            (typeof NodeWorker !== 'undefined' && !isBrowser));\n    }\n    constructor(props) {\n        const { name, source, url } = props;\n        assert$2(source || url); // Either source or url must be defined\n        this.name = name;\n        this.source = source;\n        this.url = url;\n        this.onMessage = NOOP;\n        this.onError = (error) => console.log(error); // eslint-disable-line\n        this.worker = isBrowser ? this._createBrowserWorker() : this._createNodeWorker();\n    }\n    /**\n     * Terminate this worker thread\n     * @note Can free up significant memory\n     */\n    destroy() {\n        this.onMessage = NOOP;\n        this.onError = NOOP;\n        this.worker.terminate(); // eslint-disable-line @typescript-eslint/no-floating-promises\n        this.terminated = true;\n    }\n    get isRunning() {\n        return Boolean(this.onMessage);\n    }\n    /**\n     * Send a message to this worker thread\n     * @param data any data structure, ideally consisting mostly of transferrable objects\n     * @param transferList If not supplied, calculated automatically by traversing data\n     */\n    postMessage(data, transferList) {\n        transferList = transferList || getTransferList(data);\n        // @ts-ignore\n        this.worker.postMessage(data, transferList);\n    }\n    // PRIVATE\n    /**\n     * Generate a standard Error from an ErrorEvent\n     * @param event\n     */\n    _getErrorFromErrorEvent(event) {\n        // Note Error object does not have the expected fields if loading failed completely\n        // https://developer.mozilla.org/en-US/docs/Web/API/Worker#Event_handlers\n        // https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent\n        let message = 'Failed to load ';\n        message += `worker ${this.name} from ${this.url}. `;\n        if (event.message) {\n            message += `${event.message} in `;\n        }\n        // const hasFilename = event.filename && !event.filename.startsWith('blob:');\n        // message += hasFilename ? event.filename : this.source.slice(0, 100);\n        if (event.lineno) {\n            message += `:${event.lineno}:${event.colno}`;\n        }\n        return new Error(message);\n    }\n    /**\n     * Creates a worker thread on the browser\n     */\n    _createBrowserWorker() {\n        this._loadableURL = getLoadableWorkerURL({ source: this.source, url: this.url });\n        const worker = new Worker(this._loadableURL, { name: this.name });\n        worker.onmessage = (event) => {\n            if (!event.data) {\n                this.onError(new Error('No data received'));\n            }\n            else {\n                this.onMessage(event.data);\n            }\n        };\n        // This callback represents an uncaught exception in the worker thread\n        worker.onerror = (error) => {\n            this.onError(this._getErrorFromErrorEvent(error));\n            this.terminated = true;\n        };\n        // TODO - not clear when this would be called, for now just log in case it happens\n        worker.onmessageerror = (event) => console.error(event); // eslint-disable-line\n        return worker;\n    }\n    /**\n     * Creates a worker thread in node.js\n     * @todo https://nodejs.org/api/async_hooks.html#async-resource-worker-pool\n     */\n    _createNodeWorker() {\n        let worker;\n        if (this.url) {\n            // Make sure relative URLs start with './'\n            const absolute = this.url.includes(':/') || this.url.startsWith('/');\n            const url = absolute ? this.url : `./${this.url}`;\n            // console.log('Starting work from', url);\n            worker = new NodeWorker(url, { eval: false });\n        }\n        else if (this.source) {\n            worker = new NodeWorker(this.source, { eval: true });\n        }\n        else {\n            throw new Error('no worker');\n        }\n        worker.on('message', (data) => {\n            // console.error('message', data);\n            this.onMessage(data);\n        });\n        worker.on('error', (error) => {\n            // console.error('error', error);\n            this.onError(error);\n        });\n        worker.on('exit', (code) => {\n            // console.error('exit', code);\n        });\n        return worker;\n    }\n}\n\n// loaders.gl\n/**\n * Process multiple data messages with small pool of identical workers\n */\nclass WorkerPool {\n    name = 'unnamed';\n    source; // | Function;\n    url;\n    maxConcurrency = 1;\n    maxMobileConcurrency = 1;\n    onDebug = () => { };\n    reuseWorkers = true;\n    props = {};\n    jobQueue = [];\n    idleQueue = [];\n    count = 0;\n    isDestroyed = false;\n    /** Checks if workers are supported on this platform */\n    static isSupported() {\n        return WorkerThread.isSupported();\n    }\n    /**\n     * @param processor - worker function\n     * @param maxConcurrency - max count of workers\n     */\n    constructor(props) {\n        this.source = props.source;\n        this.url = props.url;\n        this.setProps(props);\n    }\n    /**\n     * Terminates all workers in the pool\n     * @note Can free up significant memory\n     */\n    destroy() {\n        // Destroy idle workers, active Workers will be destroyed on completion\n        this.idleQueue.forEach((worker) => worker.destroy());\n        this.isDestroyed = true;\n    }\n    setProps(props) {\n        this.props = { ...this.props, ...props };\n        if (props.name !== undefined) {\n            this.name = props.name;\n        }\n        if (props.maxConcurrency !== undefined) {\n            this.maxConcurrency = props.maxConcurrency;\n        }\n        if (props.maxMobileConcurrency !== undefined) {\n            this.maxMobileConcurrency = props.maxMobileConcurrency;\n        }\n        if (props.reuseWorkers !== undefined) {\n            this.reuseWorkers = props.reuseWorkers;\n        }\n        if (props.onDebug !== undefined) {\n            this.onDebug = props.onDebug;\n        }\n    }\n    async startJob(name, onMessage = (job, type, data) => job.done(data), onError = (job, error) => job.error(error)) {\n        // Promise resolves when thread starts working on this job\n        const startPromise = new Promise((onStart) => {\n            // Promise resolves when thread completes or fails working on this job\n            this.jobQueue.push({ name, onMessage, onError, onStart });\n            return this;\n        });\n        this._startQueuedJob(); // eslint-disable-line @typescript-eslint/no-floating-promises\n        return await startPromise;\n    }\n    // PRIVATE\n    /**\n     * Starts first queued job if worker is available or can be created\n     * Called when job is started and whenever a worker returns to the idleQueue\n     */\n    async _startQueuedJob() {\n        if (!this.jobQueue.length) {\n            return;\n        }\n        const workerThread = this._getAvailableWorker();\n        if (!workerThread) {\n            return;\n        }\n        // We have a worker, dequeue and start the job\n        const queuedJob = this.jobQueue.shift();\n        if (queuedJob) {\n            // Emit a debug event\n            // @ts-ignore\n            this.onDebug({\n                message: 'Starting job',\n                name: queuedJob.name,\n                workerThread,\n                backlog: this.jobQueue.length\n            });\n            // Create a worker job to let the app access thread and manage job completion\n            const job = new WorkerJob(queuedJob.name, workerThread);\n            // Set the worker thread's message handlers\n            workerThread.onMessage = (data) => queuedJob.onMessage(job, data.type, data.payload);\n            workerThread.onError = (error) => queuedJob.onError(job, error);\n            // Resolve the start promise so that the app can start sending messages to worker\n            queuedJob.onStart(job);\n            // Wait for the app to signal that the job is complete, then return worker to queue\n            try {\n                await job.result;\n            }\n            catch (error) {\n                // eslint-disable-next-line no-console\n                console.error(`Worker exception: ${error}`);\n            }\n            finally {\n                this.returnWorkerToQueue(workerThread);\n            }\n        }\n    }\n    /**\n     * Returns a worker to the idle queue\n     * Destroys the worker if\n     *  - pool is destroyed\n     *  - if this pool doesn't reuse workers\n     *  - if maxConcurrency has been lowered\n     * @param worker\n     */\n    returnWorkerToQueue(worker) {\n        const shouldDestroyWorker = \n        // Workers on Node.js prevent the process from exiting.\n        // Until we figure out how to close them before exit, we always destroy them\n        !isBrowser ||\n            // If the pool is destroyed, there is no reason to keep the worker around\n            this.isDestroyed ||\n            // If the app has disabled worker reuse, any completed workers should be destroyed\n            !this.reuseWorkers ||\n            // If concurrency has been lowered, this worker might be surplus to requirements\n            this.count > this._getMaxConcurrency();\n        if (shouldDestroyWorker) {\n            worker.destroy();\n            this.count--;\n        }\n        else {\n            this.idleQueue.push(worker);\n        }\n        if (!this.isDestroyed) {\n            this._startQueuedJob(); // eslint-disable-line @typescript-eslint/no-floating-promises\n        }\n    }\n    /**\n     * Returns idle worker or creates new worker if maxConcurrency has not been reached\n     */\n    _getAvailableWorker() {\n        // If a worker has completed and returned to the queue, it can be used\n        if (this.idleQueue.length > 0) {\n            return this.idleQueue.shift() || null;\n        }\n        // Create fresh worker if we haven't yet created the max amount of worker threads for this worker source\n        if (this.count < this._getMaxConcurrency()) {\n            this.count++;\n            const name = `${this.name.toLowerCase()} (#${this.count} of ${this.maxConcurrency})`;\n            return new WorkerThread({ name, source: this.source, url: this.url });\n        }\n        // No worker available, have to wait\n        return null;\n    }\n    _getMaxConcurrency() {\n        return isMobile ? this.maxMobileConcurrency : this.maxConcurrency;\n    }\n}\n\n// loaders.gl\nconst DEFAULT_PROPS = {\n    maxConcurrency: 3,\n    maxMobileConcurrency: 1,\n    reuseWorkers: true,\n    onDebug: () => { }\n};\n/**\n * Process multiple jobs with a \"farm\" of different workers in worker pools.\n */\nclass WorkerFarm {\n    props;\n    workerPools = new Map();\n    // singleton\n    static _workerFarm;\n    /** Checks if workers are supported on this platform */\n    static isSupported() {\n        return WorkerThread.isSupported();\n    }\n    /** Get the singleton instance of the global worker farm */\n    static getWorkerFarm(props = {}) {\n        WorkerFarm._workerFarm = WorkerFarm._workerFarm || new WorkerFarm({});\n        WorkerFarm._workerFarm.setProps(props);\n        return WorkerFarm._workerFarm;\n    }\n    /** get global instance with WorkerFarm.getWorkerFarm() */\n    constructor(props) {\n        this.props = { ...DEFAULT_PROPS };\n        this.setProps(props);\n        /** @type Map<string, WorkerPool>} */\n        this.workerPools = new Map();\n    }\n    /**\n     * Terminate all workers in the farm\n     * @note Can free up significant memory\n     */\n    destroy() {\n        for (const workerPool of this.workerPools.values()) {\n            workerPool.destroy();\n        }\n        this.workerPools = new Map();\n    }\n    /**\n     * Set props used when initializing worker pools\n     * @param props\n     */\n    setProps(props) {\n        this.props = { ...this.props, ...props };\n        // Update worker pool props\n        for (const workerPool of this.workerPools.values()) {\n            workerPool.setProps(this._getWorkerPoolProps());\n        }\n    }\n    /**\n     * Returns a worker pool for the specified worker\n     * @param options - only used first time for a specific worker name\n     * @param options.name - the name of the worker - used to identify worker pool\n     * @param options.url -\n     * @param options.source -\n     * @example\n     *   const job = WorkerFarm.getWorkerFarm().getWorkerPool({name, url}).startJob(...);\n     */\n    getWorkerPool(options) {\n        const { name, source, url } = options;\n        let workerPool = this.workerPools.get(name);\n        if (!workerPool) {\n            workerPool = new WorkerPool({\n                name,\n                source,\n                url\n            });\n            workerPool.setProps(this._getWorkerPoolProps());\n            this.workerPools.set(name, workerPool);\n        }\n        return workerPool;\n    }\n    _getWorkerPoolProps() {\n        return {\n            maxConcurrency: this.props.maxConcurrency,\n            maxMobileConcurrency: this.props.maxMobileConcurrency,\n            reuseWorkers: this.props.reuseWorkers,\n            onDebug: this.props.onDebug\n        };\n    }\n}\n\n// loaders.gl\n/**\n * Generate a worker URL based on worker object and options\n * @returns A URL to one of the following:\n * - a published worker on unpkg CDN\n * - a local test worker\n * - a URL provided by the user in options\n */\nfunction getWorkerURL(worker, options = {}) {\n    const workerOptions = options[worker.id] || {};\n    const workerFile = isBrowser ? `${worker.id}-worker.js` : `${worker.id}-worker-node.js`;\n    let url = workerOptions.workerUrl;\n    // HACK: Allow for non-nested workerUrl for the CompressionWorker.\n    // For the compression worker, workerOptions is currently not nested correctly. For most loaders,\n    // you'd have options within an object, i.e. `{mvt: {coordinates: ...}}` but the CompressionWorker\n    // puts options at the top level, not within a `compression` key (its `id`). For this reason, the\n    // above `workerOptions` will always be a string (i.e. `'gzip'`) for the CompressionWorker. To not\n    // break backwards compatibility, we allow the CompressionWorker to have options at the top level.\n    if (!url && worker.id === 'compression') {\n        url = options.workerUrl;\n    }\n    // If URL is test, generate local loaders.gl url\n    // @ts-ignore _workerType\n    if (options._workerType === 'test') {\n        if (isBrowser) {\n            url = `modules/${worker.module}/dist/${workerFile}`;\n        }\n        else {\n            // In the test environment the ts-node loader requires TypeScript code\n            url = `modules/${worker.module}/src/workers/${worker.id}-worker-node.ts`;\n        }\n    }\n    // If url override is not provided, generate a URL to published version on npm CDN unpkg.com\n    if (!url) {\n        // GENERATE\n        let version = worker.version;\n        // On master we need to load npm alpha releases published with the `beta` tag\n        if (version === 'latest') {\n            // throw new Error('latest worker version specified');\n            version = NPM_TAG;\n        }\n        const versionTag = version ? `@${version}` : '';\n        url = `https://unpkg.com/@loaders.gl/${worker.module}${versionTag}/dist/${workerFile}`;\n    }\n    assert$2(url);\n    // Allow user to override location\n    return url;\n}\n\n// loaders.gl\n/**\n * Check if worker is compatible with this library version\n * @param worker\n * @param libVersion\n * @returns `true` if the two versions are compatible\n */\nfunction validateWorkerVersion(worker, coreVersion = VERSION$5) {\n    assert$2(worker, 'no worker provided');\n    const workerVersion = worker.version;\n    if (!coreVersion || !workerVersion) {\n        return false;\n    }\n    // TODO enable when fix the __version__ injection\n    // const coreVersions = parseVersion(coreVersion);\n    // const workerVersions = parseVersion(workerVersion);\n    // assert(\n    //   coreVersion.major === workerVersion.major && coreVersion.minor <= workerVersion.minor,\n    //   `worker: ${worker.name} is not compatible. ${coreVersion.major}.${\n    //     coreVersion.minor\n    //   }+ is required.`\n    // );\n    return true;\n}\n\n// loaders.gl\nconst loadLibraryPromises = {}; // promises\n/**\n * Dynamically loads a library (\"module\")\n *\n * - wasm library: Array buffer is returned\n * - js library: Parse JS is returned\n *\n * Method depends on environment\n * - browser - script element is created and installed on document\n * - worker - eval is called on global context\n * - node - file is required\n *\n * @param libraryUrl\n * @param moduleName\n * @param options\n */\nasync function loadLibrary(libraryUrl, moduleName = null, options = {}, libraryName = null) {\n    if (moduleName) {\n        libraryUrl = getLibraryUrl(libraryUrl, moduleName, options, libraryName);\n    }\n    // Ensure libraries are only loaded once\n    loadLibraryPromises[libraryUrl] =\n        // eslint-disable-next-line @typescript-eslint/no-misused-promises\n        loadLibraryPromises[libraryUrl] || loadLibraryFromFile(libraryUrl);\n    return await loadLibraryPromises[libraryUrl];\n}\n// TODO - sort out how to resolve paths for main/worker and dev/prod\nfunction getLibraryUrl(library, moduleName, options = {}, libraryName = null) {\n    // Check if already a URL\n    if (!options.useLocalLibraries && library.startsWith('http')) {\n        return library;\n    }\n    libraryName = libraryName || library;\n    // Allow application to import and supply libraries through `options.modules`\n    // TODO - See js-module-utils in loader-utils\n    const modules = options.modules || {};\n    if (modules[libraryName]) {\n        return modules[libraryName];\n    }\n    // Load from local files, not from CDN scripts in Node.js\n    // TODO - needs to locate the modules directory when installed!\n    if (!isBrowser) {\n        return `modules/${moduleName}/dist/libs/${libraryName}`;\n    }\n    // In browser, load from external scripts\n    if (options.CDN) {\n        assert$2(options.CDN.startsWith('http'));\n        return `${options.CDN}/${moduleName}@${VERSION$5}/dist/libs/${libraryName}`;\n    }\n    // TODO - loading inside workers requires paths relative to worker script location...\n    if (isWorker) {\n        return `../src/libs/${libraryName}`;\n    }\n    return `modules/${moduleName}/src/libs/${libraryName}`;\n}\nasync function loadLibraryFromFile(libraryUrl) {\n    if (libraryUrl.endsWith('wasm')) {\n        return await loadAsArrayBuffer(libraryUrl);\n    }\n    if (!isBrowser) {\n        // TODO - Node doesn't yet support dynamic import from https URLs\n        // try {\n        //   return await import(libraryUrl);\n        // } catch (error) {\n        //   console.error(error);\n        // }\n        try {\n            const { requireFromFile } = globalThis.loaders || {};\n            return await requireFromFile?.(libraryUrl);\n        }\n        catch (error) {\n            console.error(error); // eslint-disable-line no-console\n            return null;\n        }\n    }\n    if (isWorker) {\n        return importScripts(libraryUrl);\n    }\n    // TODO - fix - should be more secure than string parsing since observes CORS\n    // if (isBrowser) {\n    //   return await loadScriptFromFile(libraryUrl);\n    // }\n    const scriptSource = await loadAsText(libraryUrl);\n    return loadLibraryFromString(scriptSource, libraryUrl);\n}\n/*\nasync function loadScriptFromFile(libraryUrl) {\n  const script = document.createElement('script');\n  script.src = libraryUrl;\n  return await new Promise((resolve, reject) => {\n    script.onload = data => {\n      resolve(data);\n    };\n    script.onerror = reject;\n  });\n}\n*/\n// TODO - Needs security audit...\n//  - Raw eval call\n//  - Potentially bypasses CORS\n// Upside is that this separates fetching and parsing\n// we could create a`LibraryLoader` or`ModuleLoader`\nfunction loadLibraryFromString(scriptSource, id) {\n    if (!isBrowser) {\n        const { requireFromString } = globalThis.loaders || {};\n        return requireFromString?.(scriptSource, id);\n    }\n    if (isWorker) {\n        // Use lvalue trick to make eval run in global scope\n        eval.call(globalThis, scriptSource); // eslint-disable-line no-eval\n        // https://stackoverflow.com/questions/9107240/1-evalthis-vs-evalthis-in-javascript\n        // http://perfectionkills.com/global-eval-what-are-the-options/\n        return null;\n    }\n    const script = document.createElement('script');\n    script.id = id;\n    // most browsers like a separate text node but some throw an error. The second method covers those.\n    try {\n        script.appendChild(document.createTextNode(scriptSource));\n    }\n    catch (e) {\n        script.text = scriptSource;\n    }\n    document.body.appendChild(script);\n    return null;\n}\n// TODO - technique for module injection into worker, from THREE.DracoLoader...\n/*\nfunction combineWorkerWithLibrary(worker, jsContent) {\n  var fn = wWorker.toString();\n  var body = [\n    '// injected',\n    jsContent,\n    '',\n    '// worker',\n    fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))\n  ].join('\\n');\n  this.workerSourceURL = URL.createObjectURL(new Blob([body]));\n}\n*/\nasync function loadAsArrayBuffer(url) {\n    const { readFileAsArrayBuffer } = globalThis.loaders || {};\n    if (isBrowser || !readFileAsArrayBuffer || url.startsWith('http')) {\n        const response = await fetch(url);\n        return await response.arrayBuffer();\n    }\n    return await readFileAsArrayBuffer(url);\n}\n/**\n * Load a file from local file system\n * @param filename\n * @returns\n */\nasync function loadAsText(url) {\n    const { readFileAsText } = globalThis.loaders || {};\n    if (isBrowser || !readFileAsText || url.startsWith('http')) {\n        const response = await fetch(url);\n        return await response.text();\n    }\n    return await readFileAsText(url);\n}\n\n/**\n * Determines if a loader can parse with worker\n * @param loader\n * @param options\n */\nfunction canParseWithWorker(loader, options) {\n    if (!WorkerFarm.isSupported()) {\n        return false;\n    }\n    // Node workers are still experimental\n    if (!isBrowser && !options?._nodeWorkers) {\n        return false;\n    }\n    return loader.worker && options?.worker;\n}\n/**\n * this function expects that the worker function sends certain messages,\n * this can be automated if the worker is wrapper by a call to createLoaderWorker in @loaders.gl/loader-utils.\n */\nasync function parseWithWorker(loader, data, options, context, parseOnMainThread) {\n    const name = loader.id; // TODO\n    const url = getWorkerURL(loader, options);\n    const workerFarm = WorkerFarm.getWorkerFarm(options);\n    const workerPool = workerFarm.getWorkerPool({ name, url });\n    // options.log object contains functions which cannot be transferred\n    // context.fetch & context.parse functions cannot be transferred\n    // TODO - decide how to handle logging on workers\n    options = JSON.parse(JSON.stringify(options));\n    context = JSON.parse(JSON.stringify(context || {}));\n    const job = await workerPool.startJob('process-on-worker', \n    // @ts-expect-error\n    onMessage.bind(null, parseOnMainThread) // eslint-disable-line @typescript-eslint/no-misused-promises\n    );\n    job.postMessage('process', {\n        // @ts-ignore\n        input: data,\n        options,\n        context\n    });\n    const result = await job.result;\n    // TODO - what is going on here?\n    return await result.result;\n}\n/**\n * Handle worker's responses to the main thread\n * @param job\n * @param type\n * @param payload\n */\nasync function onMessage(parseOnMainThread, job, type, payload) {\n    switch (type) {\n        case 'done':\n            job.done(payload);\n            break;\n        case 'error':\n            job.error(new Error(payload.error));\n            break;\n        case 'process':\n            // Worker is asking for main thread to parseO\n            const { id, input, options } = payload;\n            try {\n                const result = await parseOnMainThread(input, options);\n                job.postMessage('done', { id, result });\n            }\n            catch (error) {\n                const message = error instanceof Error ? error.message : 'unknown error';\n                job.postMessage('error', { id, error: message });\n            }\n            break;\n        default:\n            // eslint-disable-next-line\n            console.warn(`parse-with-worker unknown message ${type}`);\n    }\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n/**\n * Get the first characters from a binary file (interpret the first bytes as an ASCII string)\n * @param data\n * @param length\n * @returns\n */\nfunction getFirstCharacters$1(data, length = 5) {\n    if (typeof data === 'string') {\n        return data.slice(0, length);\n    }\n    else if (ArrayBuffer.isView(data)) {\n        // Typed Arrays can have offsets into underlying buffer\n        return getMagicString$2(data.buffer, data.byteOffset, length);\n    }\n    else if (data instanceof ArrayBuffer) {\n        const byteOffset = 0;\n        return getMagicString$2(data, byteOffset, length);\n    }\n    return '';\n}\n/**\n * Gets a magic string from a \"file\"\n * Typically used to check or detect file format\n * @param arrayBuffer\n * @param byteOffset\n * @param length\n * @returns\n */\nfunction getMagicString$2(arrayBuffer, byteOffset, length) {\n    if (arrayBuffer.byteLength <= byteOffset + length) {\n        return '';\n    }\n    const dataView = new DataView(arrayBuffer);\n    let magic = '';\n    for (let i = 0; i < length; i++) {\n        magic += String.fromCharCode(dataView.getUint8(byteOffset + i));\n    }\n    return magic;\n}\n\n/**\n * Minimal JSON parser that throws more meaningful error messages\n */\nfunction parseJSON(string) {\n    try {\n        return JSON.parse(string);\n    }\n    catch (_) {\n        throw new Error(`Failed to parse JSON from data starting with \"${getFirstCharacters$1(string)}\"`);\n    }\n}\n\n/**\n * compare two binary arrays for equality\n * @param a\n * @param b\n * @param byteLength\n */\nfunction compareArrayBuffers(arrayBuffer1, arrayBuffer2, byteLength) {\n    byteLength = byteLength || arrayBuffer1.byteLength;\n    if (arrayBuffer1.byteLength < byteLength || arrayBuffer2.byteLength < byteLength) {\n        return false;\n    }\n    const array1 = new Uint8Array(arrayBuffer1);\n    const array2 = new Uint8Array(arrayBuffer2);\n    for (let i = 0; i < array1.length; ++i) {\n        if (array1[i] !== array2[i]) {\n            return false;\n        }\n    }\n    return true;\n}\n/**\n * Concatenate a sequence of ArrayBuffers from arguments\n * @return A concatenated ArrayBuffer\n */\nfunction concatenateArrayBuffers(...sources) {\n    return concatenateArrayBuffersFromArray(sources);\n}\n/**\n * Concatenate a sequence of ArrayBuffers from array\n * @return A concatenated ArrayBuffer\n */\nfunction concatenateArrayBuffersFromArray(sources) {\n    // Make sure all inputs are wrapped in typed arrays\n    const sourceArrays = sources.map((source2) => source2 instanceof ArrayBuffer ? new Uint8Array(source2) : source2);\n    // Get length of all inputs\n    const byteLength = sourceArrays.reduce((length, typedArray) => length + typedArray.byteLength, 0);\n    // Allocate array with space for all inputs\n    const result = new Uint8Array(byteLength);\n    // Copy the subarrays\n    let offset = 0;\n    for (const sourceArray of sourceArrays) {\n        result.set(sourceArray, offset);\n        offset += sourceArray.byteLength;\n    }\n    // We work with ArrayBuffers, discard the typed array wrapper\n    return result.buffer;\n}\n/**\n * Copy a view of an ArrayBuffer into new ArrayBuffer with byteOffset = 0\n * @param arrayBuffer\n * @param byteOffset\n * @param byteLength\n */\nfunction sliceArrayBuffer(arrayBuffer, byteOffset, byteLength) {\n    const subArray = byteLength !== undefined\n        ? new Uint8Array(arrayBuffer).subarray(byteOffset, byteOffset + byteLength)\n        : new Uint8Array(arrayBuffer).subarray(byteOffset);\n    const arrayCopy = new Uint8Array(subArray);\n    return arrayCopy.buffer;\n}\n\n/**\n * Calculate new size of an arrayBuffer to be aligned to an n-byte boundary\n * This function increases `byteLength` by the minimum delta,\n * allowing the total length to be divided by `padding`\n * @param byteLength\n * @param padding\n */\nfunction padToNBytes(byteLength, padding) {\n    assert$4(byteLength >= 0); // `Incorrect 'byteLength' value: ${byteLength}`\n    assert$4(padding > 0); // `Incorrect 'padding' value: ${padding}`\n    return (byteLength + (padding - 1)) & ~(padding - 1);\n}\n/**\n * Copy from source to target at the targetOffset\n *\n * @param source - The data to copy\n * @param target - The destination to copy data into\n * @param targetOffset - The start offset into target to place the copied data\n * @returns the new offset taking into account proper padding\n */\nfunction copyToArray(source, target, targetOffset) {\n    let sourceArray;\n    if (source instanceof ArrayBuffer) {\n        sourceArray = new Uint8Array(source);\n    }\n    else {\n        // Pack buffer onto the big target array\n        //\n        // 'source.data.buffer' could be a view onto a larger buffer.\n        // We MUST use this constructor to ensure the byteOffset and byteLength is\n        // set to correct values from 'source.data' and not the underlying\n        // buffer for target.set() to work properly.\n        const srcByteOffset = source.byteOffset;\n        const srcByteLength = source.byteLength;\n        // In gltf parser it is set as \"arrayBuffer\" instead of \"buffer\"\n        // https://github.com/visgl/loaders.gl/blob/1e3a82a0a65d7b6a67b1e60633453e5edda2960a/modules/gltf/src/lib/parse-gltf.js#L85\n        sourceArray = new Uint8Array(source.buffer || source.arrayBuffer, srcByteOffset, srcByteLength);\n    }\n    // Pack buffer onto the big target array\n    target.set(sourceArray, targetOffset);\n    return targetOffset + padToNBytes(sourceArray.byteLength, 4);\n}\n\n// Breaking big data into iterable chunks, concatenating iterable chunks into big data objects\n/**\n * Concatenates all data chunks yielded by an (async) iterator\n * This function can e.g. be used to enable atomic parsers to work on (async) iterator inputs\n */\nasync function concatenateArrayBuffersAsync(asyncIterator) {\n    const arrayBuffers = [];\n    for await (const chunk of asyncIterator) {\n        arrayBuffers.push(chunk);\n    }\n    return concatenateArrayBuffers(...arrayBuffers);\n}\n\n// Simple file alias mechanisms for tests.\nlet pathPrefix = '';\nconst fileAliases = {};\n/**\n * Resolves aliases and adds path-prefix to paths\n */\nfunction resolvePath(filename) {\n    for (const alias in fileAliases) {\n        if (filename.startsWith(alias)) {\n            const replacement = fileAliases[alias];\n            filename = filename.replace(alias, replacement);\n        }\n    }\n    if (!filename.startsWith('http://') && !filename.startsWith('https://')) {\n        filename = `${pathPrefix}${filename}`;\n    }\n    return filename;\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n// Isolates Buffer references to ensure they are only bundled under Node.js (avoids big webpack polyfill)\n// this file is selected by the package.json \"browser\" field).\n/**\n * Convert Buffer to ArrayBuffer\n * Converts Node.js `Buffer` to `ArrayBuffer` (without triggering bundler to include Buffer polyfill on browser)\n * @todo better data type\n */\nfunction toArrayBuffer$1(buffer) {\n    return buffer;\n}\n\n// loaders.gl\n/**\n * Check for Node.js `Buffer` (without triggering bundler to include Buffer polyfill on browser)\n */\nfunction isBuffer$1(value) {\n    return value && typeof value === 'object' && value.isBuffer;\n}\n/**\n * Convert an object to an array buffer\n */\nfunction toArrayBuffer(data) {\n    // Note: Should be called first, Buffers can trigger other detections below\n    if (isBuffer$1(data)) {\n        return toArrayBuffer$1(data);\n    }\n    if (data instanceof ArrayBuffer) {\n        return data;\n    }\n    // Careful - Node Buffers look like Uint8Arrays (keep after isBuffer)\n    if (ArrayBuffer.isView(data)) {\n        if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {\n            return data.buffer;\n        }\n        return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);\n    }\n    if (typeof data === 'string') {\n        const text = data;\n        const uint8Array = new TextEncoder().encode(text);\n        return uint8Array.buffer;\n    }\n    // HACK to support Blob polyfill\n    if (data && typeof data === 'object' && data._toArrayBuffer) {\n        return data._toArrayBuffer();\n    }\n    throw new Error('toArrayBuffer');\n}\n\n// Beginning of a minimal implementation of the Node.js path API, that doesn't pull in big polyfills.\n/**\n * Replacement for Node.js path.filename\n * @param url\n */\nfunction filename(url) {\n    const slashIndex = url ? url.lastIndexOf('/') : -1;\n    return slashIndex >= 0 ? url.substr(slashIndex + 1) : '';\n}\n/**\n * Replacement for Node.js path.dirname\n * @param url\n */\nfunction dirname(url) {\n    const slashIndex = url ? url.lastIndexOf('/') : -1;\n    return slashIndex >= 0 ? url.substr(0, slashIndex) : '';\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nconst isBoolean = (x) => typeof x === 'boolean';\nconst isFunction = (x) => typeof x === 'function';\nconst isObject = (x) => x !== null && typeof x === 'object';\nconst isPureObject = (x) => isObject(x) && x.constructor === {}.constructor;\nconst isIterable = (x) => Boolean(x) && typeof x[Symbol.iterator] === 'function';\nconst isAsyncIterable = (x) => x && typeof x[Symbol.asyncIterator] === 'function';\nconst isResponse = (x) => (typeof Response !== 'undefined' && x instanceof Response) ||\n    (x && x.arrayBuffer && x.text && x.json);\nconst isBlob = (x) => typeof Blob !== 'undefined' && x instanceof Blob;\n/** Check for Node.js `Buffer` without triggering bundler to include buffer polyfill */\nconst isBuffer = (x) => x && typeof x === 'object' && x.isBuffer;\nconst isReadableDOMStream = (x) => (typeof ReadableStream !== 'undefined' && x instanceof ReadableStream) ||\n    (isObject(x) && isFunction(x.tee) && isFunction(x.cancel) && isFunction(x.getReader));\nconst isReadableNodeStream = (x) => isObject(x) && isFunction(x.read) && isFunction(x.pipe) && isBoolean(x.readable);\nconst isReadableStream = (x) => isReadableDOMStream(x) || isReadableNodeStream(x);\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nclass FetchError extends Error {\n    constructor(message, info) {\n        super(message);\n        this.reason = info.reason;\n        this.url = info.url;\n        this.response = info.response;\n    }\n    /** A best effort reason for why the fetch failed */\n    reason;\n    /** The URL that failed to load. Empty string if not available. */\n    url;\n    /** The Response object, if any. */\n    response;\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n// TODO - build/integrate proper MIME type parsing\n// https://mimesniff.spec.whatwg.org/\nconst DATA_URL_PATTERN = /^data:([-\\w.]+\\/[-\\w.+]+)(;|,)/;\nconst MIME_TYPE_PATTERN = /^([-\\w.]+\\/[-\\w.+]+)/;\n/**\n * Compare two MIME types, case insensitively etc.\n * @param mimeType1\n * @param mimeType2\n * @returns true if the MIME types are equivalent\n * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#structure_of_a_mime_type\n */\nfunction compareMIMETypes(mimeType1, mimeType2) {\n    if (mimeType1.toLowerCase() === mimeType2.toLowerCase()) {\n        return true;\n    }\n    return false;\n}\n/**\n * Remove extra data like `charset` from MIME types\n * @param mimeString\n * @returns A clean MIME type, or an empty string\n *\n * @todo - handle more advanced MIMETYpes, multiple types\n * @todo - extract charset etc\n */\nfunction parseMIMEType(mimeString) {\n    // If resource is a data url, extract any embedded mime type\n    const matches = MIME_TYPE_PATTERN.exec(mimeString);\n    if (matches) {\n        return matches[1];\n    }\n    return mimeString;\n}\n/**\n * Extract MIME type from data URL\n *\n * @param mimeString\n * @returns A clean MIME type, or an empty string\n *\n * @todo - handle more advanced MIMETYpes, multiple types\n * @todo - extract charset etc\n */\nfunction parseMIMETypeFromURL(url) {\n    // If resource is a data URL, extract any embedded mime type\n    const matches = DATA_URL_PATTERN.exec(url);\n    if (matches) {\n        return matches[1];\n    }\n    return '';\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nconst QUERY_STRING_PATTERN = /\\?.*/;\nfunction extractQueryString(url) {\n    const matches = url.match(QUERY_STRING_PATTERN);\n    return matches && matches[0];\n}\nfunction stripQueryString(url) {\n    return url.replace(QUERY_STRING_PATTERN, '');\n}\nfunction shortenUrlForDisplay(url) {\n    if (url.length < 50) {\n        return url;\n    }\n    const urlEnd = url.slice(url.length - 15);\n    const urlStart = url.substr(0, 32);\n    return `${urlStart}...${urlEnd}`;\n}\n\n// loaders.gl\n/**\n * Returns the URL associated with this resource.\n * The returned value may include a query string and need further processing.\n * If it cannot determine url, the corresponding value will be an empty string\n *\n * @todo string parameters are assumed to be URLs\n */\nfunction getResourceUrl(resource) {\n    // If resource is a `Response`, it contains the information directly as a field\n    if (isResponse(resource)) {\n        const response = resource;\n        return response.url;\n    }\n    // If the resource is a Blob or a File (subclass of Blob)\n    if (isBlob(resource)) {\n        const blob = resource;\n        // File objects have a \"name\" property. Blob objects don't have any\n        // url (name) information\n        return blob.name || '';\n    }\n    if (typeof resource === 'string') {\n        return resource;\n    }\n    // Unknown\n    return '';\n}\n/**\n * Returns the URL associated with this resource.\n * The returned value may include a query string and need further processing.\n * If it cannot determine url, the corresponding value will be an empty string\n *\n * @todo string parameters are assumed to be URLs\n */\nfunction getResourceMIMEType(resource) {\n    // If resource is a response, it contains the information directly\n    if (isResponse(resource)) {\n        const response = resource;\n        const contentTypeHeader = response.headers.get('content-type') || '';\n        const noQueryUrl = stripQueryString(response.url);\n        return parseMIMEType(contentTypeHeader) || parseMIMETypeFromURL(noQueryUrl);\n    }\n    // If the resource is a Blob or a File (subclass of Blob)\n    if (isBlob(resource)) {\n        const blob = resource;\n        return blob.type || '';\n    }\n    if (typeof resource === 'string') {\n        return parseMIMETypeFromURL(resource);\n    }\n    // Unknown\n    return '';\n}\n/**\n  * Returns (approximate) content length for a resource if it can be determined.\n  * Returns -1 if content length cannot be determined.\n  * @param resource\n\n  * @note string parameters are NOT assumed to be URLs\n  */\nfunction getResourceContentLength(resource) {\n    if (isResponse(resource)) {\n        const response = resource;\n        return response.headers['content-length'] || -1;\n    }\n    if (isBlob(resource)) {\n        const blob = resource;\n        return blob.size;\n    }\n    if (typeof resource === 'string') {\n        // TODO - handle data URL?\n        return resource.length;\n    }\n    if (resource instanceof ArrayBuffer) {\n        return resource.byteLength;\n    }\n    if (ArrayBuffer.isView(resource)) {\n        return resource.byteLength;\n    }\n    return -1;\n}\n\n// loaders.gl\n/**\n * Returns a Response object\n * Adds content-length header when possible\n *\n * @param resource\n */\nasync function makeResponse(resource) {\n    if (isResponse(resource)) {\n        return resource;\n    }\n    // Add content-length header if possible\n    const headers = {};\n    const contentLength = getResourceContentLength(resource);\n    if (contentLength >= 0) {\n        headers['content-length'] = String(contentLength);\n    }\n    // `new Response(File)` does not preserve content-type and URL\n    // so we add them here\n    const url = getResourceUrl(resource);\n    const type = getResourceMIMEType(resource);\n    if (type) {\n        headers['content-type'] = type;\n    }\n    // Add a custom header with initial bytes if available\n    const initialDataUrl = await getInitialDataUrl(resource);\n    if (initialDataUrl) {\n        headers['x-first-bytes'] = initialDataUrl;\n    }\n    // TODO - is this the best way of handling strings?\n    // Maybe package as data URL instead?\n    if (typeof resource === 'string') {\n        // Convert to ArrayBuffer to avoid Response treating it as a URL\n        resource = new TextEncoder().encode(resource);\n    }\n    // Attempt to create a Response from the resource, adding headers and setting url\n    const response = new Response(resource, { headers });\n    // We can't control `Response.url` via constructor, use a property override to record URL.\n    Object.defineProperty(response, 'url', { value: url });\n    return response;\n}\n/**\n * Checks response status (async) and throws a helpful error message if status is not OK.\n * @param response\n */\nasync function checkResponse(response) {\n    if (!response.ok) {\n        const error = await getResponseError(response);\n        throw error;\n    }\n}\n// HELPERS\nasync function getResponseError(response) {\n    const shortUrl = shortenUrlForDisplay(response.url);\n    let message = `Failed to fetch resource (${response.status}) ${response.statusText}: ${shortUrl}`;\n    message = message.length > 100 ? `${message.slice(0, 100)}...` : message;\n    const info = {\n        reason: response.statusText,\n        url: response.url,\n        response\n    };\n    // See if we got an error message in the body\n    try {\n        const contentType = response.headers.get('Content-Type');\n        info.reason =\n            !response.bodyUsed && contentType?.includes('application/json')\n                ? await response.json()\n                : await response.text();\n    }\n    catch (error) {\n        // eslint forbids return in a finally statement, so we just catch here\n    }\n    return new FetchError(message, info);\n}\nasync function getInitialDataUrl(resource) {\n    const INITIAL_DATA_LENGTH = 5;\n    if (typeof resource === 'string') {\n        return `data:,${resource.slice(0, INITIAL_DATA_LENGTH)}`;\n    }\n    if (resource instanceof Blob) {\n        const blobSlice = resource.slice(0, 5);\n        return await new Promise((resolve) => {\n            const reader = new FileReader();\n            reader.onload = (event) => resolve(event?.target?.result);\n            reader.readAsDataURL(blobSlice);\n        });\n    }\n    if (resource instanceof ArrayBuffer) {\n        const slice = resource.slice(0, INITIAL_DATA_LENGTH);\n        const base64 = arrayBufferToBase64(slice);\n        return `data:base64,${base64}`;\n    }\n    return null;\n}\n// https://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string\nfunction arrayBufferToBase64(buffer) {\n    let binary = '';\n    const bytes = new Uint8Array(buffer);\n    for (let i = 0; i < bytes.byteLength; i++) {\n        binary += String.fromCharCode(bytes[i]);\n    }\n    return btoa(binary);\n}\n\n// loaders.gl\n// import {FetchError} from './fetch-error';\nfunction isNodePath(url) {\n    return !isRequestURL(url) && !isDataURL(url);\n}\nfunction isRequestURL(url) {\n    return url.startsWith('http:') || url.startsWith('https:');\n}\nfunction isDataURL(url) {\n    return url.startsWith('data:');\n}\n/**\n * fetch API compatible function\n * - Supports fetching from Node.js local file system paths\n * - Respects pathPrefix and file aliases\n */\nasync function fetchFile$1(urlOrData, fetchOptions) {\n    if (typeof urlOrData === 'string') {\n        const url = resolvePath(urlOrData);\n        // Support fetching from local file system\n        if (isNodePath(url)) {\n            if (globalThis.loaders?.fetchNode) {\n                return globalThis.loaders?.fetchNode(url, fetchOptions);\n            }\n            // throw new Error(\n            //   'fetchFile: globalThis.loaders.fetchNode not defined. Install @loaders.gl/polyfills'\n            // );\n        }\n        // Call global fetch\n        return await fetch(url, fetchOptions);\n    }\n    // TODO - should we still call fetch on non-URL inputs?\n    return await makeResponse(urlOrData);\n}\n\n// loaders.gl\nconst probeLog = new Log({ id: 'loaders.gl' });\n// Logs nothing\nclass NullLog {\n    log() {\n        return () => { };\n    }\n    info() {\n        return () => { };\n    }\n    warn() {\n        return () => { };\n    }\n    error() {\n        return () => { };\n    }\n}\n// Logs to console\nclass ConsoleLog {\n    console;\n    constructor() {\n        this.console = console; // eslint-disable-line\n    }\n    log(...args) {\n        return this.console.log.bind(this.console, ...args);\n    }\n    info(...args) {\n        return this.console.info.bind(this.console, ...args);\n    }\n    warn(...args) {\n        return this.console.warn.bind(this.console, ...args);\n    }\n    error(...args) {\n        return this.console.error.bind(this.console, ...args);\n    }\n}\n\n// loaders.gl\nconst DEFAULT_LOADER_OPTIONS = {\n    // baseUri\n    fetch: null,\n    mimeType: undefined,\n    nothrow: false,\n    log: new ConsoleLog(), // A probe.gl compatible (`log.log()()` syntax) that just logs to console\n    useLocalLibraries: false,\n    CDN: 'https://unpkg.com/@loaders.gl',\n    worker: true, // By default, use worker if provided by loader.\n    maxConcurrency: 3, // How many worker instances should be created for each loader.\n    maxMobileConcurrency: 1, // How many worker instances should be created for each loader on mobile devices.\n    reuseWorkers: isBrowser$2, // By default reuse workers in browser (Node.js refuses to terminate if browsers are running)\n    _nodeWorkers: false, // By default do not support node workers\n    _workerType: '', // 'test' to use locally generated workers\n    limit: 0,\n    _limitMB: 0,\n    batchSize: 'auto',\n    batchDebounceMs: 0,\n    metadata: false, // TODO - currently only implemented for parseInBatches, adds initial metadata batch,\n    transforms: []\n};\nconst REMOVED_LOADER_OPTIONS = {\n    throws: 'nothrow',\n    dataType: '(no longer used)',\n    uri: 'baseUri',\n    // Warn if fetch options are used on top-level\n    method: 'fetch.method',\n    headers: 'fetch.headers',\n    body: 'fetch.body',\n    mode: 'fetch.mode',\n    credentials: 'fetch.credentials',\n    cache: 'fetch.cache',\n    redirect: 'fetch.redirect',\n    referrer: 'fetch.referrer',\n    referrerPolicy: 'fetch.referrerPolicy',\n    integrity: 'fetch.integrity',\n    keepalive: 'fetch.keepalive',\n    signal: 'fetch.signal'\n};\n\n// loaders.gl\n/**\n * Helper for safely accessing global loaders.gl variables\n * Wraps initialization of global variable in function to defeat overly aggressive tree-shakers\n */\nfunction getGlobalLoaderState() {\n    // @ts-ignore\n    globalThis.loaders = globalThis.loaders || {};\n    // @ts-ignore\n    const { loaders } = globalThis;\n    // Add _state object to keep separate from modules added to globalThis.loaders\n    if (!loaders._state) {\n        loaders._state = {};\n    }\n    return loaders._state;\n}\n/**\n * Store global loader options on the global object to increase chances of cross loaders-version interoperability\n * NOTE: This use case is not reliable but can help when testing new versions of loaders.gl with existing frameworks\n * @returns global loader options merged with default loader options\n */\nfunction getGlobalLoaderOptions() {\n    const state = getGlobalLoaderState();\n    // Ensure all default loader options from this library are mentioned\n    state.globalOptions = state.globalOptions || { ...DEFAULT_LOADER_OPTIONS };\n    return state.globalOptions;\n}\n/**\n * Merges options with global opts and loader defaults, also injects baseUri\n * @param options\n * @param loader\n * @param loaders\n * @param url\n */\nfunction normalizeOptions(options, loader, loaders, url) {\n    loaders = loaders || [];\n    loaders = Array.isArray(loaders) ? loaders : [loaders];\n    validateOptions(options, loaders);\n    return normalizeOptionsInternal(loader, options, url);\n}\n// VALIDATE OPTIONS\n/**\n * Warn for unsupported options\n * @param options\n * @param loaders\n */\nfunction validateOptions(options, loaders) {\n    // Check top level options\n    validateOptionsObject(options, null, DEFAULT_LOADER_OPTIONS, REMOVED_LOADER_OPTIONS, loaders);\n    for (const loader of loaders) {\n        // Get the scoped, loader specific options from the user supplied options\n        const idOptions = ((options && options[loader.id]) || {});\n        // Get scoped, loader specific default and deprecated options from the selected loader\n        const loaderOptions = (loader.options && loader.options[loader.id]) || {};\n        const deprecatedOptions = (loader.deprecatedOptions && loader.deprecatedOptions[loader.id]) || {};\n        // Validate loader specific options\n        // @ts-ignore\n        validateOptionsObject(idOptions, loader.id, loaderOptions, deprecatedOptions, loaders);\n    }\n}\n// eslint-disable-next-line max-params, complexity\nfunction validateOptionsObject(options, id, defaultOptions, deprecatedOptions, loaders) {\n    const loaderName = id || 'Top level';\n    const prefix = id ? `${id}.` : '';\n    for (const key in options) {\n        // If top level option value is an object it could options for a loader, so ignore\n        const isSubOptions = !id && isObject(options[key]);\n        const isBaseUriOption = key === 'baseUri' && !id;\n        const isWorkerUrlOption = key === 'workerUrl' && id;\n        // <loader>.workerUrl requires special handling as it is now auto-generated and no longer specified as a default option.\n        if (!(key in defaultOptions) && !isBaseUriOption && !isWorkerUrlOption) {\n            // Issue deprecation warnings\n            if (key in deprecatedOptions) {\n                probeLog.warn(`${loaderName} loader option \\'${prefix}${key}\\' no longer supported, use \\'${deprecatedOptions[key]}\\'`)();\n            }\n            else if (!isSubOptions) {\n                const suggestion = findSimilarOption(key, loaders);\n                probeLog.warn(`${loaderName} loader option \\'${prefix}${key}\\' not recognized. ${suggestion}`)();\n            }\n        }\n    }\n}\nfunction findSimilarOption(optionKey, loaders) {\n    const lowerCaseOptionKey = optionKey.toLowerCase();\n    let bestSuggestion = '';\n    for (const loader of loaders) {\n        for (const key in loader.options) {\n            if (optionKey === key) {\n                return `Did you mean \\'${loader.id}.${key}\\'?`;\n            }\n            const lowerCaseKey = key.toLowerCase();\n            const isPartialMatch = lowerCaseOptionKey.startsWith(lowerCaseKey) || lowerCaseKey.startsWith(lowerCaseOptionKey);\n            if (isPartialMatch) {\n                bestSuggestion = bestSuggestion || `Did you mean \\'${loader.id}.${key}\\'?`;\n            }\n        }\n    }\n    return bestSuggestion;\n}\nfunction normalizeOptionsInternal(loader, options, url) {\n    const loaderDefaultOptions = loader.options || {};\n    const mergedOptions = { ...loaderDefaultOptions };\n    addUrlOptions(mergedOptions, url);\n    // LOGGING: options.log can be set to `null` to defeat logging\n    if (mergedOptions.log === null) {\n        mergedOptions.log = new NullLog();\n    }\n    mergeNestedFields(mergedOptions, getGlobalLoaderOptions());\n    mergeNestedFields(mergedOptions, options);\n    return mergedOptions;\n}\n// Merge nested options objects\nfunction mergeNestedFields(mergedOptions, options) {\n    for (const key in options) {\n        // Check for nested options\n        // object in options => either no key in defaultOptions or object in defaultOptions\n        if (key in options) {\n            const value = options[key];\n            if (isPureObject(value) && isPureObject(mergedOptions[key])) {\n                mergedOptions[key] = {\n                    ...mergedOptions[key],\n                    ...options[key]\n                };\n            }\n            else {\n                mergedOptions[key] = options[key];\n            }\n        }\n        // else: No need to merge nested opts, and the initial merge already copied over the nested options\n    }\n}\n/**\n * Harvest information from the url\n * @deprecated This is mainly there to support a hack in the GLTFLoader\n * TODO - baseUri should be a directory, i.e. remove file component from baseUri\n * TODO - extract extension?\n * TODO - extract query parameters?\n * TODO - should these be injected on context instead of options?\n */\nfunction addUrlOptions(options, url) {\n    if (url && !('baseUri' in options)) {\n        options.baseUri = url;\n    }\n}\n\n// loaders.gl\nfunction isLoaderObject(loader) {\n    if (!loader) {\n        return false;\n    }\n    if (Array.isArray(loader)) {\n        loader = loader[0];\n    }\n    const hasExtensions = Array.isArray(loader?.extensions);\n    /* Now handled by types and worker loaders do not have these\n    let hasParser =\n      loader.parseTextSync ||\n      loader.parseSync ||\n      loader.parse ||\n      loader.parseStream || // TODO Remove, Replace with parseInBatches\n      loader.parseInBatches;\n    */\n    return hasExtensions;\n}\nfunction normalizeLoader(loader) {\n    // This error is fairly easy to trigger by mixing up import statements etc\n    // So we make an exception and add a developer error message for this case\n    // To help new users from getting stuck here\n    assert$4(loader, 'null loader');\n    assert$4(isLoaderObject(loader), 'invalid loader');\n    // NORMALIZE [LOADER, OPTIONS] => LOADER\n    // If [loader, options], create a new loaders object with options merged in\n    let options;\n    if (Array.isArray(loader)) {\n        options = loader[1];\n        loader = loader[0];\n        loader = {\n            ...loader,\n            options: { ...loader.options, ...options }\n        };\n    }\n    // NORMALIZE text and binary flags\n    // Ensure at least one of text/binary flags are properly set\n    // @ts-expect-error\n    if (loader?.parseTextSync || loader?.parseText) {\n        loader.text = true;\n    }\n    if (!loader.text) {\n        loader.binary = true;\n    }\n    return loader;\n}\n\n// loaders.gl\n/**\n * Store global registered loaders on the global object to increase chances of cross loaders-version interoperability\n * This use case is not reliable but can help when testing new versions of loaders.gl with existing frameworks\n */\nconst getGlobalLoaderRegistry = () => {\n    const state = getGlobalLoaderState();\n    state.loaderRegistry = state.loaderRegistry || [];\n    return state.loaderRegistry;\n};\n/**\n * @deprecated It is recommended that applications manage loader registration. This function will likely be remove in loaders.gl v5\n */\nfunction getRegisteredLoaders() {\n    return getGlobalLoaderRegistry();\n}\n\n// loaders.gl\nconst EXT_PATTERN = /\\.([^.]+)$/;\n// TODO - Need a variant that peeks at streams for parseInBatches\n// TODO - Detect multiple matching loaders? Use heuristics to grade matches?\n// TODO - Allow apps to pass context to disambiguate between multiple matches (e.g. multiple .json formats)?\n/**\n * Find a loader that matches file extension and/or initial file content\n * Search the loaders array argument for a loader that matches url extension or initial data\n * Returns: a normalized loader\n * @param data data to assist\n * @param loaders\n * @param options\n * @param context used internally, applications should not provide this parameter\n */\nasync function selectLoader(data, loaders = [], options, context) {\n    if (!validHTTPResponse(data)) {\n        return null;\n    }\n    // First make a sync attempt, disabling exceptions\n    let loader = selectLoaderSync(data, loaders, { ...options, nothrow: true }, context);\n    if (loader) {\n        return loader;\n    }\n    // For Blobs and Files, try to asynchronously read a small initial slice and test again with that\n    // to see if we can detect by initial content\n    if (isBlob(data)) {\n        data = await data.slice(0, 10).arrayBuffer();\n        loader = selectLoaderSync(data, loaders, options, context);\n    }\n    // no loader available\n    if (!loader && !options?.nothrow) {\n        throw new Error(getNoValidLoaderMessage(data));\n    }\n    return loader;\n}\n/**\n * Find a loader that matches file extension and/or initial file content\n * Search the loaders array argument for a loader that matches url extension or initial data\n * Returns: a normalized loader\n * @param data data to assist\n * @param loaders\n * @param options\n * @param context used internally, applications should not provide this parameter\n */\nfunction selectLoaderSync(data, loaders = [], options, context) {\n    if (!validHTTPResponse(data)) {\n        return null;\n    }\n    // eslint-disable-next-line complexity\n    // if only a single loader was provided (not as array), force its use\n    // TODO - Should this behavior be kept and documented?\n    if (loaders && !Array.isArray(loaders)) {\n        // TODO - remove support for legacy loaders\n        return normalizeLoader(loaders);\n    }\n    // Build list of candidate loaders that will be searched in order for a match\n    let candidateLoaders = [];\n    // First search supplied loaders\n    if (loaders) {\n        candidateLoaders = candidateLoaders.concat(loaders);\n    }\n    // Then fall back to registered loaders\n    if (!options?.ignoreRegisteredLoaders) {\n        candidateLoaders.push(...getRegisteredLoaders());\n    }\n    // TODO - remove support for legacy loaders\n    normalizeLoaders(candidateLoaders);\n    const loader = selectLoaderInternal(data, candidateLoaders, options, context);\n    // no loader available\n    if (!loader && !options?.nothrow) {\n        throw new Error(getNoValidLoaderMessage(data));\n    }\n    return loader;\n}\n/** Implements loaders selection logic */\n// eslint-disable-next-line complexity\nfunction selectLoaderInternal(data, loaders, options, context) {\n    const url = getResourceUrl(data);\n    const type = getResourceMIMEType(data);\n    const testUrl = stripQueryString(url) || context?.url;\n    let loader = null;\n    let reason = '';\n    // if options.mimeType is supplied, it takes precedence\n    if (options?.mimeType) {\n        loader = findLoaderByMIMEType(loaders, options?.mimeType);\n        reason = `match forced by supplied MIME type ${options?.mimeType}`;\n    }\n    // Look up loader by url\n    loader = loader || findLoaderByUrl(loaders, testUrl);\n    reason = reason || (loader ? `matched url ${testUrl}` : '');\n    // Look up loader by mime type\n    loader = loader || findLoaderByMIMEType(loaders, type);\n    reason = reason || (loader ? `matched MIME type ${type}` : '');\n    // Look for loader via initial bytes (Note: not always accessible (e.g. Response, stream, async iterator)\n    // @ts-ignore Blob | Response\n    loader = loader || findLoaderByInitialBytes(loaders, data);\n    // @ts-ignore Blob | Response\n    reason = reason || (loader ? `matched initial data ${getFirstCharacters(data)}` : '');\n    // Look up loader by fallback mime type\n    if (options?.fallbackMimeType) {\n        loader = loader || findLoaderByMIMEType(loaders, options?.fallbackMimeType);\n        reason = reason || (loader ? `matched fallback MIME type ${type}` : '');\n    }\n    if (reason) {\n        log.log(1, `selectLoader selected ${loader?.name}: ${reason}.`);\n    }\n    return loader;\n}\n/** Check HTTP Response */\nfunction validHTTPResponse(data) {\n    // HANDLE HTTP status\n    if (data instanceof Response) {\n        // 204 - NO CONTENT. This handles cases where e.g. a tile server responds with 204 for a missing tile\n        if (data.status === 204) {\n            return false;\n        }\n    }\n    return true;\n}\n/** Generate a helpful message to help explain why loader selection failed. */\nfunction getNoValidLoaderMessage(data) {\n    const url = getResourceUrl(data);\n    const type = getResourceMIMEType(data);\n    let message = 'No valid loader found (';\n    message += url ? `${filename(url)}, ` : 'no url provided, ';\n    message += `MIME type: ${type ? `\"${type}\"` : 'not provided'}, `;\n    // First characters are only accessible when called on data (string or arrayBuffer).\n    // @ts-ignore Blob | Response\n    const firstCharacters = data ? getFirstCharacters(data) : '';\n    message += firstCharacters ? ` first bytes: \"${firstCharacters}\"` : 'first bytes: not available';\n    message += ')';\n    return message;\n}\nfunction normalizeLoaders(loaders) {\n    for (const loader of loaders) {\n        normalizeLoader(loader);\n    }\n}\n// TODO - Would be nice to support http://example.com/file.glb?parameter=1\n// E.g: x = new URL('http://example.com/file.glb?load=1'; x.pathname\nfunction findLoaderByUrl(loaders, url) {\n    // Get extension\n    const match = url && EXT_PATTERN.exec(url);\n    const extension = match && match[1];\n    return extension ? findLoaderByExtension(loaders, extension) : null;\n}\nfunction findLoaderByExtension(loaders, extension) {\n    extension = extension.toLowerCase();\n    for (const loader of loaders) {\n        for (const loaderExtension of loader.extensions) {\n            if (loaderExtension.toLowerCase() === extension) {\n                return loader;\n            }\n        }\n    }\n    return null;\n}\nfunction findLoaderByMIMEType(loaders, mimeType) {\n    for (const loader of loaders) {\n        if (loader.mimeTypes?.some((mimeType1) => compareMIMETypes(mimeType, mimeType1))) {\n            return loader;\n        }\n        // Support referring to loaders using the \"unregistered tree\"\n        // https://en.wikipedia.org/wiki/Media_type#Unregistered_tree\n        if (compareMIMETypes(mimeType, `application/x.${loader.id}`)) {\n            return loader;\n        }\n    }\n    return null;\n}\nfunction findLoaderByInitialBytes(loaders, data) {\n    if (!data) {\n        return null;\n    }\n    for (const loader of loaders) {\n        if (typeof data === 'string') {\n            if (testDataAgainstText(data, loader)) {\n                return loader;\n            }\n        }\n        else if (ArrayBuffer.isView(data)) {\n            // Typed Arrays can have offsets into underlying buffer\n            if (testDataAgainstBinary(data.buffer, data.byteOffset, loader)) {\n                return loader;\n            }\n        }\n        else if (data instanceof ArrayBuffer) {\n            const byteOffset = 0;\n            if (testDataAgainstBinary(data, byteOffset, loader)) {\n                return loader;\n            }\n        }\n        // TODO Handle streaming case (requires creating a new AsyncIterator)\n    }\n    return null;\n}\nfunction testDataAgainstText(data, loader) {\n    if (loader.testText) {\n        return loader.testText(data);\n    }\n    const tests = Array.isArray(loader.tests) ? loader.tests : [loader.tests];\n    return tests.some((test) => data.startsWith(test));\n}\nfunction testDataAgainstBinary(data, byteOffset, loader) {\n    const tests = Array.isArray(loader.tests) ? loader.tests : [loader.tests];\n    return tests.some((test) => testBinary(data, byteOffset, loader, test));\n}\nfunction testBinary(data, byteOffset, loader, test) {\n    if (test instanceof ArrayBuffer) {\n        return compareArrayBuffers(test, data, test.byteLength);\n    }\n    switch (typeof test) {\n        case 'function':\n            return test(data);\n        case 'string':\n            // Magic bytes check: If `test` is a string, check if binary data starts with that strings\n            const magic = getMagicString$1(data, byteOffset, test.length);\n            return test === magic;\n        default:\n            return false;\n    }\n}\nfunction getFirstCharacters(data, length = 5) {\n    if (typeof data === 'string') {\n        return data.slice(0, length);\n    }\n    else if (ArrayBuffer.isView(data)) {\n        // Typed Arrays can have offsets into underlying buffer\n        return getMagicString$1(data.buffer, data.byteOffset, length);\n    }\n    else if (data instanceof ArrayBuffer) {\n        const byteOffset = 0;\n        return getMagicString$1(data, byteOffset, length);\n    }\n    return '';\n}\nfunction getMagicString$1(arrayBuffer, byteOffset, length) {\n    if (arrayBuffer.byteLength < byteOffset + length) {\n        return '';\n    }\n    const dataView = new DataView(arrayBuffer);\n    let magic = '';\n    for (let i = 0; i < length; i++) {\n        magic += String.fromCharCode(dataView.getUint8(byteOffset + i));\n    }\n    return magic;\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nconst DEFAULT_CHUNK_SIZE$2 = 256 * 1024;\n/**\n * Returns an iterator that breaks a big string into chunks and yields them one-by-one as ArrayBuffers\n * @param blob string to iterate over\n * @param options\n * @param options.chunkSize\n */\nfunction* makeStringIterator(string, options) {\n    const chunkSize = options?.chunkSize || DEFAULT_CHUNK_SIZE$2;\n    let offset = 0;\n    const textEncoder = new TextEncoder();\n    while (offset < string.length) {\n        // Create a chunk of the right size\n        const chunkLength = Math.min(string.length - offset, chunkSize);\n        const chunk = string.slice(offset, offset + chunkLength);\n        offset += chunkLength;\n        // yield an ArrayBuffer chunk\n        yield textEncoder.encode(chunk);\n    }\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nconst DEFAULT_CHUNK_SIZE$1 = 256 * 1024;\n/**\n * Returns an iterator that breaks a big ArrayBuffer into chunks and yields them one-by-one\n * @param blob ArrayBuffer to iterate over\n * @param options\n * @param options.chunkSize\n */\nfunction* makeArrayBufferIterator(arrayBuffer, options = {}) {\n    const { chunkSize = DEFAULT_CHUNK_SIZE$1 } = options;\n    let byteOffset = 0;\n    while (byteOffset < arrayBuffer.byteLength) {\n        // Create a chunk of the right size\n        const chunkByteLength = Math.min(arrayBuffer.byteLength - byteOffset, chunkSize);\n        const chunk = new ArrayBuffer(chunkByteLength);\n        // Copy data from the big chunk\n        const sourceArray = new Uint8Array(arrayBuffer, byteOffset, chunkByteLength);\n        const chunkArray = new Uint8Array(chunk);\n        chunkArray.set(sourceArray);\n        // yield the chunk\n        byteOffset += chunkByteLength;\n        yield chunk;\n    }\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nconst DEFAULT_CHUNK_SIZE = 1024 * 1024; // 1MB — biggest value that keeps UI responsive\n/**\n * Returns an iterator that breaks a big Blob into chunks and yields them one-by-one\n * @param blob Blob or File object\n * @param options\n * @param options.chunkSize\n */\nasync function* makeBlobIterator(blob, options) {\n    const chunkSize = options?.chunkSize || DEFAULT_CHUNK_SIZE;\n    let offset = 0;\n    while (offset < blob.size) {\n        const end = offset + chunkSize;\n        const chunk = await blob.slice(offset, end).arrayBuffer();\n        offset = end;\n        yield chunk;\n    }\n}\n\n// loaders.gl\n/**\n * Returns an async iterable that reads from a stream (works in both Node.js and browsers)\n * @param stream stream to iterator over\n */\nfunction makeStreamIterator(stream, options) {\n    return isBrowser$2\n        ? makeBrowserStreamIterator(stream, options)\n        : makeNodeStreamIterator(stream);\n}\n/**\n * Returns an async iterable that reads from a DOM (browser) stream\n * @param stream stream to iterate from\n * @see https://jakearchibald.com/2017/async-iterators-and-generators/#making-streams-iterate\n */\nasync function* makeBrowserStreamIterator(stream, options) {\n    // WhatWG: stream is supposed to have a `getIterator` method\n    // if (typeof stream.getIterator === 'function') {\n    //   return stream.getIterator();\n    // }\n    // if (typeof stream[Symbol.asyncIterator] === 'function') {\n    //   return makeToArrayBufferIterator(stream);\n    // }\n    // In the browser, we first need to get a lock on the stream\n    const reader = stream.getReader();\n    let nextBatchPromise;\n    try {\n        // eslint-disable-next-line no-constant-condition\n        while (true) {\n            const currentBatchPromise = nextBatchPromise || reader.read();\n            // Issue a read for an additional batch, while we await the next batch\n            // Idea is to make fetching happen in parallel with processing / parsing\n            if (options?._streamReadAhead) {\n                nextBatchPromise = reader.read();\n            }\n            // Read from the stream\n            // value is a Uint8Array\n            const { done, value } = await currentBatchPromise;\n            // Exit if we're done\n            if (done) {\n                return;\n            }\n            // Else yield the chunk\n            yield toArrayBuffer(value);\n        }\n    }\n    catch (error) {\n        // TODO - examples makes it look like this should always be called,\n        // but that generates exceptions so only call it if we do not reach the end\n        reader.releaseLock();\n    }\n}\n/**\n * Returns an async iterable that reads from a DOM (browser) stream\n * @param stream stream to iterate from\n * @note Requires Node.js >= 10\n */\nasync function* makeNodeStreamIterator(stream, options) {\n    // Hacky test for node version to ensure we don't call bad polyfills\n    // NODE 10+: stream is an asyncIterator\n    for await (const chunk of stream) {\n        yield toArrayBuffer(chunk); // Coerce each chunk to ArrayBuffer\n    }\n}\n/* TODO - remove NODE < 10\n * @see https://github.com/bustle/streaming-iterables, MIT license\n *\n  if (typeof stream[Symbol.asyncIterator] === 'function') {\n    return;\n  }\n\n  // TODO - check if is this ever used in Node 10+?\n  // eslint-disable-next-line no-constant-condition\n  while (true) {\n    const data = stream.read();\n    if (data !== null) {\n      yield toArrayBuffer(data);\n      // eslint-disable-next-line no-continue\n      continue;\n    }\n    if (stream._readableState?.ended) {\n      return;\n    }\n    await onceReadable(stream);\n  }\n\nasync function onceReadable(stream: Readable): Promise<any> {\n  return new Promise((resolve) => {\n    stream.once('readable', resolve);\n  });\n}\n  */\n\n// loaders.gl\n/**\n * Returns an iterator that breaks its input into chunks and yields them one-by-one.\n * @param data\n * @param options\n * @returns\n * This function can e.g. be used to enable data sources that can only be read atomically\n * (such as `Blob` and `File` via `FileReader`) to still be parsed in batches.\n */\nfunction makeIterator(data, options) {\n    if (typeof data === 'string') {\n        // Note: Converts string chunks to binary\n        return makeStringIterator(data, options);\n    }\n    if (data instanceof ArrayBuffer) {\n        return makeArrayBufferIterator(data, options);\n    }\n    if (isBlob(data)) {\n        return makeBlobIterator(data, options);\n    }\n    if (isReadableStream(data)) {\n        return makeStreamIterator(data, options);\n    }\n    if (isResponse(data)) {\n        const response = data;\n        return makeStreamIterator(response.body, options);\n    }\n    throw new Error('makeIterator');\n}\n\n// loaders.gl\nconst ERR_DATA = 'Cannot convert supplied data type';\n// eslint-disable-next-line complexity\nfunction getArrayBufferOrStringFromDataSync(data, loader, options) {\n    if (loader.text && typeof data === 'string') {\n        return data;\n    }\n    if (isBuffer(data)) {\n        // @ts-ignore\n        data = data.buffer;\n    }\n    if (data instanceof ArrayBuffer) {\n        const arrayBuffer = data;\n        if (loader.text && !loader.binary) {\n            const textDecoder = new TextDecoder('utf8');\n            return textDecoder.decode(arrayBuffer);\n        }\n        return arrayBuffer;\n    }\n    // We may need to handle offsets\n    if (ArrayBuffer.isView(data)) {\n        // TextDecoder is invoked on typed arrays and will handle offsets\n        if (loader.text && !loader.binary) {\n            const textDecoder = new TextDecoder('utf8');\n            return textDecoder.decode(data);\n        }\n        let arrayBuffer = data.buffer;\n        // Since we are returning the underlying arrayBuffer, we must create a new copy\n        // if this typed array / Buffer is a partial view into the ArryayBuffer\n        // TODO - this is a potentially unnecessary copy\n        const byteLength = data.byteLength || data.length;\n        if (data.byteOffset !== 0 || byteLength !== arrayBuffer.byteLength) {\n            // console.warn(`loaders.gl copying arraybuffer of length ${byteLength}`);\n            arrayBuffer = arrayBuffer.slice(data.byteOffset, data.byteOffset + byteLength);\n        }\n        return arrayBuffer;\n    }\n    throw new Error(ERR_DATA);\n}\n// Convert async iterator to a promise\nasync function getArrayBufferOrStringFromData(data, loader, options) {\n    const isArrayBuffer = data instanceof ArrayBuffer || ArrayBuffer.isView(data);\n    if (typeof data === 'string' || isArrayBuffer) {\n        return getArrayBufferOrStringFromDataSync(data, loader);\n    }\n    // Blobs and files are FileReader compatible\n    if (isBlob(data)) {\n        data = await makeResponse(data);\n    }\n    if (isResponse(data)) {\n        const response = data;\n        await checkResponse(response);\n        return loader.binary ? await response.arrayBuffer() : await response.text();\n    }\n    if (isReadableStream(data)) {\n        // @ts-expect-error TS2559 options type\n        data = makeIterator(data, options);\n    }\n    if (isIterable(data) || isAsyncIterable(data)) {\n        // Assume arrayBuffer iterator - attempt to concatenate\n        return concatenateArrayBuffersAsync(data);\n    }\n    throw new Error(ERR_DATA);\n}\n\n// loaders.gl\n/**\n * Gets the current fetch function from options and context\n * @param options\n * @param context\n */\nfunction getFetchFunction(options, context) {\n    const globalOptions = getGlobalLoaderOptions();\n    const loaderOptions = options || globalOptions;\n    // options.fetch can be a function\n    if (typeof loaderOptions.fetch === 'function') {\n        return loaderOptions.fetch;\n    }\n    // options.fetch can be an options object\n    if (isObject(loaderOptions.fetch)) {\n        return (url) => fetchFile$1(url, loaderOptions.fetch);\n    }\n    // else refer to context (from parent loader) if available\n    if (context?.fetch) {\n        return context?.fetch;\n    }\n    // else return the default fetch function\n    return fetchFile$1;\n}\n\n// loaders.gl\n/**\n * \"sub\" loaders invoked by other loaders get a \"context\" injected on `this`\n * The context will inject core methods like `parse` and contain information\n * about loaders and options passed in to the top-level `parse` call.\n *\n * @param context\n * @param options\n * @param previousContext\n */\nfunction getLoaderContext(context, options, parentContext) {\n    // For recursive calls, we already have a context\n    // TODO - add any additional loaders to context?\n    if (parentContext) {\n        return parentContext;\n    }\n    const newContext = {\n        fetch: getFetchFunction(options, context),\n        ...context\n    };\n    // Parse URLs so that subloaders can easily generate correct strings\n    if (newContext.url) {\n        const baseUrl = stripQueryString(newContext.url);\n        newContext.baseUrl = baseUrl;\n        newContext.queryString = extractQueryString(newContext.url);\n        newContext.filename = filename(baseUrl);\n        newContext.baseUrl = dirname(baseUrl);\n    }\n    // Recursive loading does not use single loader\n    if (!Array.isArray(newContext.loaders)) {\n        newContext.loaders = null;\n    }\n    return newContext;\n}\n// eslint-disable-next-line complexity\nfunction getLoadersFromContext(loaders, context) {\n    // A single loader (non-array) indicates no selection desired. Force select.\n    if (loaders && !Array.isArray(loaders)) {\n        return loaders;\n    }\n    // Create a merged list\n    let candidateLoaders;\n    if (loaders) {\n        candidateLoaders = Array.isArray(loaders) ? loaders : [loaders];\n    }\n    if (context && context.loaders) {\n        const contextLoaders = Array.isArray(context.loaders) ? context.loaders : [context.loaders];\n        candidateLoaders = candidateLoaders ? [...candidateLoaders, ...contextLoaders] : contextLoaders;\n    }\n    // If no loaders, return null to look in globally registered loaders\n    return candidateLoaders && candidateLoaders.length ? candidateLoaders : undefined;\n}\n\n// loaders.gl\n/**\n * Parses `data` using a specified loader\n * @param data\n * @param loaders\n * @param options\n * @param context\n */\n// implementation signature\nasync function parse$4(data, loaders, options, context) {\n    // Signature: parse(data, options, context | url)\n    // Uses registered loaders\n    if (loaders && !Array.isArray(loaders) && !isLoaderObject(loaders)) {\n        context = undefined; // context not supported in short signature\n        options = loaders;\n        loaders = undefined;\n    }\n    data = await data; // Resolve any promise\n    options = options || {}; // Could be invalid...\n    // Extract a url for auto detection\n    const url = getResourceUrl(data);\n    // Chooses a loader (and normalizes it)\n    // Also use any loaders in the context, new loaders take priority\n    const typedLoaders = loaders;\n    const candidateLoaders = getLoadersFromContext(typedLoaders, context);\n    // todo hacky type cast\n    const loader = await selectLoader(data, candidateLoaders, options);\n    // Note: if no loader was found, if so just return null\n    if (!loader) {\n        return null;\n    }\n    // Normalize options\n    // @ts-expect-error\n    options = normalizeOptions(options, loader, candidateLoaders, url); // Could be invalid...\n    // Get a context (if already present, will be unchanged)\n    context = getLoaderContext(\n    // @ts-expect-error\n    { url, _parse: parse$4, loaders: candidateLoaders }, options, context || null);\n    return await parseWithLoader(loader, data, options, context);\n}\n// TODO: support progress and abort\n// TODO - should accept loader.parseAsyncIterator and concatenate.\nasync function parseWithLoader(loader, data, options, context) {\n    validateWorkerVersion(loader);\n    options = mergeLoaderOptions(loader.options, options);\n    if (isResponse(data)) {\n        // Serialize to support passing the response to web worker\n        const response = data;\n        const { ok, redirected, status, statusText, type, url } = response;\n        const headers = Object.fromEntries(response.headers.entries());\n        // @ts-expect-error TODO - fix this\n        context.response = { headers, ok, redirected, status, statusText, type, url };\n    }\n    data = await getArrayBufferOrStringFromData(data, loader, options);\n    const loaderWithParser = loader;\n    // First check for synchronous text parser, wrap results in promises\n    if (loaderWithParser.parseTextSync && typeof data === 'string') {\n        return loaderWithParser.parseTextSync(data, options, context);\n    }\n    // If we have a workerUrl and the loader can parse the given options efficiently in a worker\n    if (canParseWithWorker(loader, options)) {\n        return await parseWithWorker(loader, data, options, context, parse$4);\n    }\n    // Check for asynchronous parser\n    if (loaderWithParser.parseText && typeof data === 'string') {\n        return await loaderWithParser.parseText(data, options, context);\n    }\n    if (loaderWithParser.parse) {\n        return await loaderWithParser.parse(data, options, context);\n    }\n    // This should not happen, all sync loaders should also offer `parse` function\n    assert$2(!loaderWithParser.parseSync);\n    // TBD - If asynchronous parser not available, return null\n    throw new Error(`${loader.id} loader - no parser found and worker is disabled`);\n}\n\n// loaders.gl\n/**\n * Deduces a simple data type \"descriptor from a typed array instance\n */\nfunction getDataTypeFromTypedArray(array) {\n    switch (array.constructor) {\n        case Int8Array:\n            return 'int8';\n        case Uint8Array:\n        case Uint8ClampedArray:\n            return 'uint8';\n        case Int16Array:\n            return 'int16';\n        case Uint16Array:\n            return 'uint16';\n        case Int32Array:\n            return 'int32';\n        case Uint32Array:\n            return 'uint32';\n        case Float32Array:\n            return 'float32';\n        case Float64Array:\n            return 'float64';\n        default:\n            return 'null';\n    }\n}\n\n/**\n * Get number of vertices in mesh\n * @param attributes\n */\n/**\n * Get the (axis aligned) bounding box of a mesh\n * @param attributes\n * @returns array of two vectors representing the axis aligned bounding box\n */\n// eslint-disable-next-line complexity\nfunction getMeshBoundingBox(attributes) {\n    let minX = Infinity;\n    let minY = Infinity;\n    let minZ = Infinity;\n    let maxX = -Infinity;\n    let maxY = -Infinity;\n    let maxZ = -Infinity;\n    const positions = attributes.POSITION ? attributes.POSITION.value : [];\n    const len = positions && positions.length;\n    for (let i = 0; i < len; i += 3) {\n        const x = positions[i];\n        const y = positions[i + 1];\n        const z = positions[i + 2];\n        minX = x < minX ? x : minX;\n        minY = y < minY ? y : minY;\n        minZ = z < minZ ? z : minZ;\n        maxX = x > maxX ? x : maxX;\n        maxY = y > maxY ? y : maxY;\n        maxZ = z > maxZ ? z : maxZ;\n    }\n    return [\n        [minX, minY, minZ],\n        [maxX, maxY, maxZ]\n    ];\n}\n\n// loaders.gl\n/**\n * Create a schema for mesh attributes data\n * @param attributes\n * @param metadata\n * @returns\n */\nfunction deduceMeshSchema(attributes, metadata = {}) {\n    const fields = deduceMeshFields(attributes);\n    return { fields, metadata };\n}\n/**\n * Create arrow-like schema field for mesh attribute\n * @param attributeName\n * @param attribute\n * @param optionalMetadata\n * @returns\n */\nfunction deduceMeshField(name, attribute, optionalMetadata) {\n    const type = getDataTypeFromTypedArray(attribute.value);\n    const metadata = optionalMetadata ? optionalMetadata : makeMeshAttributeMetadata(attribute);\n    return {\n        name,\n        type: { type: 'fixed-size-list', listSize: attribute.size, children: [{ name: 'value', type }] },\n        nullable: false,\n        metadata\n    };\n}\n/**\n * Create fields array for mesh attributes\n * @param attributes\n * @returns\n */\nfunction deduceMeshFields(attributes) {\n    const fields = [];\n    for (const attributeName in attributes) {\n        const attribute = attributes[attributeName];\n        fields.push(deduceMeshField(attributeName, attribute));\n    }\n    return fields;\n}\n/**\n * Make metadata by mesh attribute properties\n * @param attribute\n * @returns\n */\nfunction makeMeshAttributeMetadata(attribute) {\n    const result = {};\n    if ('byteOffset' in attribute) {\n        result.byteOffset = attribute.byteOffset.toString(10);\n    }\n    if ('byteStride' in attribute) {\n        result.byteStride = attribute.byteStride.toString(10);\n    }\n    if ('normalized' in attribute) {\n        result.normalized = attribute.normalized.toString();\n    }\n    return result;\n}\n\n// Version constant cannot be imported, it needs to correspond to the build version of **this** module.\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION$4 = \"4.3.3\" ;\n\n// @ts-ignore TS2339: Property does not exist on type\nconst parseImageNode = globalThis.loaders?.parseImageNode;\nconst IMAGE_SUPPORTED = typeof Image !== 'undefined'; // NOTE: \"false\" positives if jsdom is installed\nconst IMAGE_BITMAP_SUPPORTED = typeof ImageBitmap !== 'undefined';\nconst NODE_IMAGE_SUPPORTED = Boolean(parseImageNode);\nconst DATA_SUPPORTED = isBrowser$2 ? true : NODE_IMAGE_SUPPORTED;\n/**\n * Checks if a loaders.gl image type is supported\n * @param type image type string\n */\nfunction isImageTypeSupported(type) {\n    switch (type) {\n        case 'auto':\n            // Should only ever be false in Node.js, if polyfills have not been installed...\n            return IMAGE_BITMAP_SUPPORTED || IMAGE_SUPPORTED || DATA_SUPPORTED;\n        case 'imagebitmap':\n            return IMAGE_BITMAP_SUPPORTED;\n        case 'image':\n            return IMAGE_SUPPORTED;\n        case 'data':\n            return DATA_SUPPORTED;\n        default:\n            throw new Error(`@loaders.gl/images: image ${type} not supported in this environment`);\n    }\n}\n/**\n * Returns the \"most performant\" supported image type on this platform\n * @returns image type string\n */\nfunction getDefaultImageType() {\n    if (IMAGE_BITMAP_SUPPORTED) {\n        return 'imagebitmap';\n    }\n    if (IMAGE_SUPPORTED) {\n        return 'image';\n    }\n    if (DATA_SUPPORTED) {\n        return 'data';\n    }\n    // This should only happen in Node.js\n    throw new Error('Install \\'@loaders.gl/polyfills\\' to parse images under Node.js');\n}\n\nfunction getImageType(image) {\n    const format = getImageTypeOrNull(image);\n    if (!format) {\n        throw new Error('Not an image');\n    }\n    return format;\n}\nfunction getImageData(image) {\n    switch (getImageType(image)) {\n        case 'data':\n            return image;\n        case 'image':\n        case 'imagebitmap':\n            // Extract the image data from the image via a canvas\n            const canvas = document.createElement('canvas');\n            // TODO - reuse the canvas?\n            const context = canvas.getContext('2d');\n            if (!context) {\n                throw new Error('getImageData');\n            }\n            // @ts-ignore\n            canvas.width = image.width;\n            // @ts-ignore\n            canvas.height = image.height;\n            // @ts-ignore\n            context.drawImage(image, 0, 0);\n            // @ts-ignore\n            return context.getImageData(0, 0, image.width, image.height);\n        default:\n            throw new Error('getImageData');\n    }\n}\n// PRIVATE\n// eslint-disable-next-line complexity\nfunction getImageTypeOrNull(image) {\n    if (typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {\n        return 'imagebitmap';\n    }\n    if (typeof Image !== 'undefined' && image instanceof Image) {\n        return 'image';\n    }\n    if (image && typeof image === 'object' && image.data && image.width && image.height) {\n        return 'data';\n    }\n    return null;\n}\n\n// SVG parsing has limitations, e.g:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=606319\nconst SVG_DATA_URL_PATTERN = /^data:image\\/svg\\+xml/;\nconst SVG_URL_PATTERN = /\\.svg((\\?|#).*)?$/;\nfunction isSVG$1(url) {\n    return url && (SVG_DATA_URL_PATTERN.test(url) || SVG_URL_PATTERN.test(url));\n}\nfunction getBlobOrSVGDataUrl(arrayBuffer, url) {\n    if (isSVG$1(url)) {\n        // Prepare a properly tagged data URL, and load using normal mechanism\n        const textDecoder = new TextDecoder();\n        let xmlText = textDecoder.decode(arrayBuffer);\n        // TODO Escape in browser to support e.g. Chinese characters\n        try {\n            if (typeof unescape === 'function' && typeof encodeURIComponent === 'function') {\n                xmlText = unescape(encodeURIComponent(xmlText));\n            }\n        }\n        catch (error) {\n            throw new Error(error.message);\n        }\n        // base64 encoding is safer. utf-8 fails in some browsers\n        const src = `data:image/svg+xml;base64,${btoa(xmlText)}`;\n        return src;\n    }\n    return getBlob(arrayBuffer, url);\n}\nfunction getBlob(arrayBuffer, url) {\n    if (isSVG$1(url)) {\n        // https://bugs.chromium.org/p/chromium/issues/detail?id=606319\n        // return new Blob([new Uint8Array(arrayBuffer)], {type: 'image/svg+xml'});\n        throw new Error('SVG cannot be parsed directly to imagebitmap');\n    }\n    // TODO - how to determine mime type? Param? Sniff here?\n    return new Blob([new Uint8Array(arrayBuffer)]); // MIME type not needed?\n}\n\n// Parses html image from array buffer\nasync function parseToImage(arrayBuffer, options, url) {\n    // Note: image parsing requires conversion to Blob (for createObjectURL).\n    // Potentially inefficient for not using `response.blob()` (and for File / Blob inputs)...\n    // But presumably not worth adding 'blob' flag to loader objects?\n    const blobOrDataUrl = getBlobOrSVGDataUrl(arrayBuffer, url);\n    const URL = self.URL || self.webkitURL;\n    const objectUrl = typeof blobOrDataUrl !== 'string' && URL.createObjectURL(blobOrDataUrl);\n    try {\n        return await loadToImage(objectUrl || blobOrDataUrl, options);\n    }\n    finally {\n        if (objectUrl) {\n            URL.revokeObjectURL(objectUrl);\n        }\n    }\n}\nasync function loadToImage(url, options) {\n    const image = new Image();\n    image.src = url;\n    // The `image.onload()` callback does not guarantee that the image has been decoded\n    // so a main thread \"freeze\" can be incurred when using the image for the first time.\n    // `Image.decode()` returns a promise that completes when image is decoded.\n    // https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decode\n    // Note: When calling `img.decode()`, we do not need to wait for `img.onload()`\n    // Note: `HTMLImageElement.decode()` is not available in Edge and IE11\n    if (options.image && options.image.decode && image.decode) {\n        await image.decode();\n        return image;\n    }\n    // Create a promise that tracks onload/onerror callbacks\n    return await new Promise((resolve, reject) => {\n        try {\n            image.onload = () => resolve(image);\n            image.onerror = (error) => {\n                const message = error instanceof Error ? error.message : 'error';\n                reject(new Error(message));\n            };\n        }\n        catch (error) {\n            reject(error);\n        }\n    });\n}\n\nconst EMPTY_OBJECT = {};\nlet imagebitmapOptionsSupported = true;\n/**\n * Asynchronously parses an array buffer into an ImageBitmap - this contains the decoded data\n * ImageBitmaps are supported on worker threads, but not supported on Edge, IE11 and Safari\n * https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap#Browser_compatibility\n *\n * TODO - createImageBitmap supports source rect (5 param overload), pass through?\n */\nasync function parseToImageBitmap(arrayBuffer, options, url) {\n    let blob;\n    // Cannot parse SVG directly to ImageBitmap, parse to Image first\n    if (isSVG$1(url)) {\n        // Note: this only works on main thread\n        const image = await parseToImage(arrayBuffer, options, url);\n        blob = image;\n    }\n    else {\n        // Create blob from the array buffer\n        blob = getBlob(arrayBuffer, url);\n    }\n    const imagebitmapOptions = options && options.imagebitmap;\n    return await safeCreateImageBitmap(blob, imagebitmapOptions);\n}\n/**\n * Safely creates an imageBitmap with options\n * *\n * Firefox crashes if imagebitmapOptions is supplied\n * Avoid supplying if not provided or supported, remember if not supported\n */\nasync function safeCreateImageBitmap(blob, imagebitmapOptions = null) {\n    if (isEmptyObject(imagebitmapOptions) || !imagebitmapOptionsSupported) {\n        imagebitmapOptions = null;\n    }\n    if (imagebitmapOptions) {\n        try {\n            // @ts-ignore Options\n            return await createImageBitmap(blob, imagebitmapOptions);\n        }\n        catch (error) {\n            console.warn(error); // eslint-disable-line\n            imagebitmapOptionsSupported = false;\n        }\n    }\n    return await createImageBitmap(blob);\n}\nfunction isEmptyObject(object) {\n    // @ts-ignore\n    for (const key in object || EMPTY_OBJECT) {\n        return false;\n    }\n    return true;\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n// code adapted from https://github.com/sindresorhus/file-type under MIT license\n/**\n * Tests if a buffer is in ISO base media file format (ISOBMFF) @see https://en.wikipedia.org/wiki/ISO_base_media_file_format\n * (ISOBMFF is a media container standard based on the Apple QuickTime container format)\n */\nfunction getISOBMFFMediaType(buffer) {\n    // Almost all ISO base media files start with `ftyp` box. (It's not required to be first, but it's recommended to be.)\n    if (!checkString(buffer, 'ftyp', 4)) {\n        return null;\n    }\n    // Extra check: test for 8859-1 printable characters (for simplicity, it's a mask which also catches one non-printable character).\n    if ((buffer[8] & 0x60) === 0x00) {\n        return null;\n    }\n    // `ftyp` box must contain a brand major identifier, which must consist of ISO 8859-1 printable characters.\n    return decodeMajorBrand(buffer);\n}\n/**\n * brands explained @see https://github.com/strukturag/libheif/issues/83\n * code adapted from @see https://github.com/sindresorhus/file-type/blob/main/core.js#L489-L492\n */\nfunction decodeMajorBrand(buffer) {\n    const brandMajor = getUTF8String(buffer, 8, 12).replace('\\0', ' ').trim();\n    switch (brandMajor) {\n        case 'avif':\n        case 'avis':\n            return { extension: 'avif', mimeType: 'image/avif' };\n        default:\n            return null;\n    }\n    // We don't need these now, but they are easy to add\n    // case 'mif1':\n    //   return {extension: 'heic', mimeType: 'image/heif'};\n    // case 'msf1':\n    //   return {extension: 'heic', mimeType: 'image/heif-sequence'};\n    // case 'heic':\n    // case 'heix':\n    //   return {extension: 'heic', mimeType: 'image/heic'};\n    // case 'hevc':\n    // case 'hevx':\n    //   return {extension: 'heic', mimeType: 'image/heic-sequence'};\n    // case 'qt':\n    //   return {ext: 'mov', mime: 'video/quicktime'};\n    // case 'M4V':\n    // case 'M4VH':\n    // case 'M4VP':\n    //   return {ext: 'm4v', mime: 'video/x-m4v'};\n    // case 'M4P':\n    //   return {ext: 'm4p', mime: 'video/mp4'};\n    // case 'M4B':\n    //   return {ext: 'm4b', mime: 'audio/mp4'};\n    // case 'M4A':\n    //   return {ext: 'm4a', mime: 'audio/x-m4a'};\n    // case 'F4V':\n    //   return {ext: 'f4v', mime: 'video/mp4'};\n    // case 'F4P':\n    //   return {ext: 'f4p', mime: 'video/mp4'};\n    // case 'F4A':\n    //   return {ext: 'f4a', mime: 'audio/mp4'};\n    // case 'F4B':\n    //   return {ext: 'f4b', mime: 'audio/mp4'};\n    // case 'crx':\n    //   return {ext: 'cr3', mime: 'image/x-canon-cr3'};\n    // default:\n    // if (brandMajor.startsWith('3g')) {\n    //   if (brandMajor.startsWith('3g2')) {\n    //     return {ext: '3g2', mime: 'video/3gpp2'};\n    //   }\n    //   return {ext: '3gp', mime: 'video/3gpp'};\n    // }\n    // return {ext: 'mp4', mime: 'video/mp4'};\n}\n/** Interpret a chunk of bytes as a UTF8 string */\nfunction getUTF8String(array, start, end) {\n    return String.fromCharCode(...array.slice(start, end));\n}\nfunction stringToBytes(string) {\n    return [...string].map((character) => character.charCodeAt(0));\n}\nfunction checkString(buffer, header, offset = 0) {\n    const headerBytes = stringToBytes(header);\n    for (let i = 0; i < headerBytes.length; ++i) {\n        if (headerBytes[i] !== buffer[i + offset]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Attributions\nconst BIG_ENDIAN = false;\nconst LITTLE_ENDIAN$1 = true;\n/**\n * Extracts `{mimeType, width and height}` from a memory buffer containing a known image format\n * Currently supports `image/png`, `image/jpeg`, `image/bmp` and `image/gif`.\n * @param binaryData: DataView | ArrayBuffer image file memory to parse\n * @returns metadata or null if memory is not a valid image file format layout.\n */\nfunction getBinaryImageMetadata(binaryData) {\n    const dataView = toDataView(binaryData);\n    return (getPngMetadata(dataView) ||\n        getJpegMetadata(dataView) ||\n        getGifMetadata(dataView) ||\n        getBmpMetadata(dataView) ||\n        getISOBMFFMetadata(dataView));\n}\n// ISOBMFF\nfunction getISOBMFFMetadata(binaryData) {\n    const buffer = new Uint8Array(binaryData instanceof DataView ? binaryData.buffer : binaryData);\n    const mediaType = getISOBMFFMediaType(buffer);\n    if (!mediaType) {\n        return null;\n    }\n    return {\n        mimeType: mediaType.mimeType,\n        // TODO - decode width and height\n        width: 0,\n        height: 0\n    };\n}\n// PNG\nfunction getPngMetadata(binaryData) {\n    const dataView = toDataView(binaryData);\n    // Check file contains the first 4 bytes of the PNG signature.\n    const isPng = dataView.byteLength >= 24 && dataView.getUint32(0, BIG_ENDIAN) === 0x89504e47;\n    if (!isPng) {\n        return null;\n    }\n    // Extract size from a binary PNG file\n    return {\n        mimeType: 'image/png',\n        width: dataView.getUint32(16, BIG_ENDIAN),\n        height: dataView.getUint32(20, BIG_ENDIAN)\n    };\n}\n// GIF\n// Extract size from a binary GIF file\n// TODO: GIF is not this simple\nfunction getGifMetadata(binaryData) {\n    const dataView = toDataView(binaryData);\n    // Check first 4 bytes of the GIF signature (\"GIF8\").\n    const isGif = dataView.byteLength >= 10 && dataView.getUint32(0, BIG_ENDIAN) === 0x47494638;\n    if (!isGif) {\n        return null;\n    }\n    // GIF is little endian.\n    return {\n        mimeType: 'image/gif',\n        width: dataView.getUint16(6, LITTLE_ENDIAN$1),\n        height: dataView.getUint16(8, LITTLE_ENDIAN$1)\n    };\n}\n// BMP\n// TODO: BMP is not this simple\nfunction getBmpMetadata(binaryData) {\n    const dataView = toDataView(binaryData);\n    // Check magic number is valid (first 2 characters should be \"BM\").\n    // The mandatory bitmap file header is 14 bytes long.\n    const isBmp = dataView.byteLength >= 14 &&\n        dataView.getUint16(0, BIG_ENDIAN) === 0x424d &&\n        dataView.getUint32(2, LITTLE_ENDIAN$1) === dataView.byteLength;\n    if (!isBmp) {\n        return null;\n    }\n    // BMP is little endian.\n    return {\n        mimeType: 'image/bmp',\n        width: dataView.getUint32(18, LITTLE_ENDIAN$1),\n        height: dataView.getUint32(22, LITTLE_ENDIAN$1)\n    };\n}\n// JPEG\n// Extract width and height from a binary JPEG file\nfunction getJpegMetadata(binaryData) {\n    const dataView = toDataView(binaryData);\n    // Check file contains the JPEG \"start of image\" (SOI) marker\n    // followed by another marker.\n    const isJpeg = dataView.byteLength >= 3 &&\n        dataView.getUint16(0, BIG_ENDIAN) === 0xffd8 &&\n        dataView.getUint8(2) === 0xff;\n    if (!isJpeg) {\n        return null;\n    }\n    const { tableMarkers, sofMarkers } = getJpegMarkers();\n    // Exclude the two byte SOI marker.\n    let i = 2;\n    while (i + 9 < dataView.byteLength) {\n        const marker = dataView.getUint16(i, BIG_ENDIAN);\n        // The frame that contains the width and height of the JPEG image.\n        if (sofMarkers.has(marker)) {\n            return {\n                mimeType: 'image/jpeg',\n                height: dataView.getUint16(i + 5, BIG_ENDIAN), // Number of lines\n                width: dataView.getUint16(i + 7, BIG_ENDIAN) // Number of pixels per line\n            };\n        }\n        // Miscellaneous tables/data preceding the frame header.\n        if (!tableMarkers.has(marker)) {\n            return null;\n        }\n        // Length includes size of length parameter but not the two byte header.\n        i += 2;\n        i += dataView.getUint16(i, BIG_ENDIAN);\n    }\n    return null;\n}\nfunction getJpegMarkers() {\n    // Tables/misc header markers.\n    // DQT, DHT, DAC, DRI, COM, APP_n\n    const tableMarkers = new Set([0xffdb, 0xffc4, 0xffcc, 0xffdd, 0xfffe]);\n    for (let i = 0xffe0; i < 0xfff0; ++i) {\n        tableMarkers.add(i);\n    }\n    // SOF markers and DHP marker.\n    // These markers are after tables/misc data.\n    const sofMarkers = new Set([\n        0xffc0, 0xffc1, 0xffc2, 0xffc3, 0xffc5, 0xffc6, 0xffc7, 0xffc9, 0xffca, 0xffcb, 0xffcd, 0xffce,\n        0xffcf, 0xffde\n    ]);\n    return { tableMarkers, sofMarkers };\n}\n// TODO - move into image module?\nfunction toDataView(data) {\n    if (data instanceof DataView) {\n        return data;\n    }\n    if (ArrayBuffer.isView(data)) {\n        return new DataView(data.buffer);\n    }\n    // TODO: make these functions work for Node.js buffers?\n    // if (bufferToArrayBuffer) {\n    //   data = bufferToArrayBuffer(data);\n    // }\n    // Careful - Node Buffers will look like ArrayBuffers (keep after isBuffer)\n    if (data instanceof ArrayBuffer) {\n        return new DataView(data);\n    }\n    throw new Error('toDataView');\n}\n\n// Use polyfills if installed to parsed image using get-pixels\nasync function parseToNodeImage(arrayBuffer, options) {\n    const { mimeType } = getBinaryImageMetadata(arrayBuffer) || {};\n    // @ts-ignore\n    const parseImageNode = globalThis.loaders?.parseImageNode;\n    assert$4(parseImageNode); // '@loaders.gl/polyfills not installed'\n    // @ts-expect-error TODO should we throw error in this case?\n    return await parseImageNode(arrayBuffer, mimeType);\n}\n\n// Parse to platform defined image type (data on node, ImageBitmap or HTMLImage on browser)\n// eslint-disable-next-line complexity\nasync function parseImage(arrayBuffer, options, context) {\n    options = options || {};\n    const imageOptions = options.image || {};\n    // The user can request a specific output format via `options.image.type`\n    const imageType = imageOptions.type || 'auto';\n    const { url } = context || {};\n    // Note: For options.image.type === `data`, we may still need to load as `image` or `imagebitmap`\n    const loadType = getLoadableImageType(imageType);\n    let image;\n    switch (loadType) {\n        case 'imagebitmap':\n            image = await parseToImageBitmap(arrayBuffer, options, url);\n            break;\n        case 'image':\n            image = await parseToImage(arrayBuffer, options, url);\n            break;\n        case 'data':\n            // Node.js loads imagedata directly\n            image = await parseToNodeImage(arrayBuffer);\n            break;\n        default:\n            assert$4(false);\n    }\n    // Browser: if options.image.type === 'data', we can now extract data from the loaded image\n    if (imageType === 'data') {\n        image = getImageData(image);\n    }\n    return image;\n}\n// Get a loadable image type from image type\nfunction getLoadableImageType(type) {\n    switch (type) {\n        case 'auto':\n        case 'data':\n            // Browser: For image data we need still need to load using an image format\n            // Node: the default image type is `data`.\n            return getDefaultImageType();\n        default:\n            // Throw an error if not supported\n            isImageTypeSupported(type);\n            return type;\n    }\n}\n\n// import type { ImageType } from '@loaders.gl/schema';\nconst EXTENSIONS$1 = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'ico', 'svg', 'avif'];\nconst MIME_TYPES = [\n    'image/png',\n    'image/jpeg',\n    'image/gif',\n    'image/webp',\n    'image/avif',\n    'image/bmp',\n    'image/vnd.microsoft.icon',\n    'image/svg+xml'\n];\nconst DEFAULT_IMAGE_LOADER_OPTIONS = {\n    image: {\n        type: 'auto',\n        decode: true // if format is HTML\n    }\n    // imagebitmap: {} - passes (platform dependent) parameters to ImageBitmap constructor\n};\n/**\n * Loads a platform-specific image type\n * Note: This type can be used as input data to WebGL texture creation\n */\nconst ImageLoader = {\n    dataType: null,\n    batchType: null,\n    id: 'image',\n    module: 'images',\n    name: 'Images',\n    version: VERSION$4,\n    mimeTypes: MIME_TYPES,\n    extensions: EXTENSIONS$1,\n    parse: parseImage,\n    // TODO: byteOffset, byteLength;\n    tests: [(arrayBuffer) => Boolean(getBinaryImageMetadata(new DataView(arrayBuffer)))],\n    options: DEFAULT_IMAGE_LOADER_OPTIONS\n};\n\n// loaders.gl\n/** Cache sync values for speed */\nconst mimeTypeSupportedSync = {};\n/**\n * Check if image MIME type is supported. Result is cached to avoid repeated tests.\n */\nfunction isImageFormatSupported(mimeType) {\n    if (mimeTypeSupportedSync[mimeType] === undefined) {\n        const supported = isBrowser$2\n            ? checkBrowserImageFormatSupport(mimeType)\n            : checkNodeImageFormatSupport(mimeType);\n        mimeTypeSupportedSync[mimeType] = supported;\n    }\n    return mimeTypeSupportedSync[mimeType];\n}\n/**\n * Checks that polyfills are installed and that mimeType is supported by polyfills\n * @todo Ideally polyfills should declare what formats they support, instead of storing that data here.\n */\nfunction checkNodeImageFormatSupport(mimeType) {\n    const NODE_FORMAT_SUPPORT = ['image/png', 'image/jpeg', 'image/gif'];\n    const imageFormatsNode = globalThis.loaders?.imageFormatsNode || NODE_FORMAT_SUPPORT;\n    const parseImageNode = globalThis.loaders?.parseImageNode;\n    return Boolean(parseImageNode) && imageFormatsNode.includes(mimeType);\n}\n/** Checks image format support synchronously.\n * @note Unreliable, fails on AVIF\n */\nfunction checkBrowserImageFormatSupport(mimeType) {\n    switch (mimeType) {\n        case 'image/avif': // Will fail\n        case 'image/webp':\n            return testBrowserImageFormatSupport(mimeType);\n        default:\n            return true;\n    }\n}\n/**\n * Checks browser synchronously\n * Checks if toDataURL supports the mimeType.\n * @note Imperfect testOn Chrome this is true for WebP but not for AVIF\n */\nfunction testBrowserImageFormatSupport(mimeType) {\n    try {\n        const element = document.createElement('canvas');\n        const dataURL = element.toDataURL(mimeType);\n        return dataURL.indexOf(`data:${mimeType}`) === 0;\n    }\n    catch {\n        // Probably Safari...\n        return false;\n    }\n}\n\n// Replacement for the external assert method to reduce bundle size\n// Note: We don't use the second \"message\" argument in calling code,\n// so no need to support it here\nfunction assert$1(condition, message) {\n    if (!condition) {\n        throw new Error(message || 'assert failed: gltf');\n    }\n}\n\nconst COMPONENTS$1 = {\n    SCALAR: 1,\n    VEC2: 2,\n    VEC3: 3,\n    VEC4: 4,\n    MAT2: 4,\n    MAT3: 9,\n    MAT4: 16\n};\nconst BYTES$1 = {\n    5120: 1, // BYTE\n    5121: 1, // UNSIGNED_BYTE\n    5122: 2, // SHORT\n    5123: 2, // UNSIGNED_SHORT\n    5125: 4, // UNSIGNED_INT\n    5126: 4 // FLOAT\n};\n\nconst TYPES = ['SCALAR', 'VEC2', 'VEC3', 'VEC4'];\nconst ARRAY_CONSTRUCTOR_TO_WEBGL_CONSTANT = [\n    [Int8Array, 5120],\n    [Uint8Array, 5121],\n    [Int16Array, 5122],\n    [Uint16Array, 5123],\n    [Uint32Array, 5125],\n    [Float32Array, 5126],\n    [Float64Array, 5130]\n];\nconst ARRAY_TO_COMPONENT_TYPE = new Map(ARRAY_CONSTRUCTOR_TO_WEBGL_CONSTANT);\nconst ATTRIBUTE_TYPE_TO_COMPONENTS$1 = {\n    SCALAR: 1,\n    VEC2: 2,\n    VEC3: 3,\n    VEC4: 4,\n    MAT2: 4,\n    MAT3: 9,\n    MAT4: 16\n};\nconst ATTRIBUTE_COMPONENT_TYPE_TO_BYTE_SIZE$1 = {\n    5120: 1,\n    5121: 1,\n    5122: 2,\n    5123: 2,\n    5125: 4,\n    5126: 4\n};\nconst ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY$1 = {\n    5120: Int8Array,\n    5121: Uint8Array,\n    5122: Int16Array,\n    5123: Uint16Array,\n    5125: Uint32Array,\n    5126: Float32Array\n};\nfunction getAccessorTypeFromSize(size) {\n    const type = TYPES[size - 1];\n    return type || TYPES[0];\n}\nfunction getComponentTypeFromArray(typedArray) {\n    const componentType = ARRAY_TO_COMPONENT_TYPE.get(typedArray.constructor);\n    if (!componentType) {\n        throw new Error('Illegal typed array');\n    }\n    return componentType;\n}\nfunction getAccessorArrayTypeAndLength(accessor, bufferView) {\n    const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY$1[accessor.componentType];\n    const components = ATTRIBUTE_TYPE_TO_COMPONENTS$1[accessor.type];\n    const bytesPerComponent = ATTRIBUTE_COMPONENT_TYPE_TO_BYTE_SIZE$1[accessor.componentType];\n    const length = accessor.count * components;\n    const byteLength = accessor.count * components * bytesPerComponent;\n    assert$1(byteLength >= 0 && byteLength <= bufferView.byteLength);\n    const componentByteSize = BYTES$1[accessor.componentType];\n    const numberOfComponentsInElement = COMPONENTS$1[accessor.type];\n    return { ArrayType, length, byteLength, componentByteSize, numberOfComponentsInElement };\n}\n\n// TODO - GLTFScenegraph should use these\n// accepts buffer view index or buffer view object\n// returns a `Uint8Array`\nfunction getTypedArrayForBufferView(json, buffers, bufferViewIndex) {\n    const bufferView = json.bufferViews[bufferViewIndex];\n    assert$1(bufferView);\n    // Get hold of the arrayBuffer\n    const bufferIndex = bufferView.buffer;\n    const binChunk = buffers[bufferIndex];\n    assert$1(binChunk);\n    const byteOffset = (bufferView.byteOffset || 0) + binChunk.byteOffset;\n    return new Uint8Array(binChunk.arrayBuffer, byteOffset, bufferView.byteLength);\n}\n/**\n * Gets data pointed by the accessor.\n * @param json - json part of gltf content of a GLTF tile.\n * @param buffers - Array containing buffers of data.\n * @param accessor - accepts accessor index or accessor object.\n * @returns {TypedArray} Typed array with type matching the type of data poited by the accessor.\n */\n// eslint-disable-next-line complexity\nfunction getTypedArrayForAccessor(json, buffers, accessor) {\n    const gltfAccessor = typeof accessor === 'number' ? json.accessors?.[accessor] : accessor;\n    if (!gltfAccessor) {\n        throw new Error(`No gltf accessor ${JSON.stringify(accessor)}`);\n    }\n    const bufferView = json.bufferViews?.[gltfAccessor.bufferView || 0];\n    if (!bufferView) {\n        throw new Error(`No gltf buffer view for accessor ${bufferView}`);\n    }\n    // Get `arrayBuffer` the `bufferView` looks at\n    const { arrayBuffer, byteOffset: bufferByteOffset } = buffers[bufferView.buffer];\n    // Resulting byteOffset is sum of the buffer, accessor and bufferView byte offsets\n    const byteOffset = (bufferByteOffset || 0) + (gltfAccessor.byteOffset || 0) + (bufferView.byteOffset || 0);\n    // Deduce TypedArray type and its length from `accessor` and `bufferView` data\n    const { ArrayType, length, componentByteSize, numberOfComponentsInElement } = getAccessorArrayTypeAndLength(gltfAccessor, bufferView);\n    // 'length' is a whole number of components of all elements in the buffer pointed by the accessor\n    // Multiplier to calculate the address of the element in the arrayBuffer\n    const elementByteSize = componentByteSize * numberOfComponentsInElement;\n    const elementAddressScale = bufferView.byteStride || elementByteSize;\n    // Creare an array of component's type where all components (not just elements) will reside\n    if (typeof bufferView.byteStride === 'undefined' || bufferView.byteStride === elementByteSize) {\n        // No iterleaving\n        const result = new ArrayType(arrayBuffer, byteOffset, length);\n        return result;\n    }\n    // Iterleaving\n    const result = new ArrayType(length);\n    for (let i = 0; i < gltfAccessor.count; i++) {\n        const values = new ArrayType(arrayBuffer, byteOffset + i * elementAddressScale, numberOfComponentsInElement);\n        result.set(values, i * numberOfComponentsInElement);\n    }\n    return result;\n}\n\n// loaders.gl\nfunction makeDefaultGLTFJson() {\n    return {\n        asset: {\n            version: '2.0',\n            generator: 'loaders.gl'\n        },\n        buffers: [],\n        extensions: {},\n        extensionsRequired: [],\n        extensionsUsed: []\n    };\n}\n/**\n * Class for structured access to GLTF data\n */\nclass GLTFScenegraph {\n    // internal\n    gltf;\n    sourceBuffers;\n    byteLength;\n    // TODO - why is this not GLTFWithBuffers - what happens to images?\n    constructor(gltf) {\n        // Declare locally so\n        this.gltf = {\n            json: gltf?.json || makeDefaultGLTFJson(),\n            buffers: gltf?.buffers || [],\n            images: gltf?.images || []\n        };\n        this.sourceBuffers = [];\n        this.byteLength = 0;\n        // Initialize buffers\n        if (this.gltf.buffers && this.gltf.buffers[0]) {\n            this.byteLength = this.gltf.buffers[0].byteLength;\n            this.sourceBuffers = [this.gltf.buffers[0]];\n        }\n    }\n    // Accessors\n    get json() {\n        return this.gltf.json;\n    }\n    getApplicationData(key) {\n        // TODO - Data is already unpacked by GLBParser\n        const data = this.json[key];\n        return data;\n    }\n    getExtraData(key) {\n        // TODO - Data is already unpacked by GLBParser\n        const extras = (this.json.extras || {});\n        return extras[key];\n    }\n    hasExtension(extensionName) {\n        const isUsedExtension = this.getUsedExtensions().find((name) => name === extensionName);\n        const isRequiredExtension = this.getRequiredExtensions().find((name) => name === extensionName);\n        return typeof isUsedExtension === 'string' || typeof isRequiredExtension === 'string';\n    }\n    getExtension(extensionName) {\n        const isExtension = this.getUsedExtensions().find((name) => name === extensionName);\n        const extensions = this.json.extensions || {};\n        return isExtension ? extensions[extensionName] : null;\n    }\n    getRequiredExtension(extensionName) {\n        const isRequired = this.getRequiredExtensions().find((name) => name === extensionName);\n        return isRequired ? this.getExtension(extensionName) : null;\n    }\n    getRequiredExtensions() {\n        return this.json.extensionsRequired || [];\n    }\n    getUsedExtensions() {\n        return this.json.extensionsUsed || [];\n    }\n    getRemovedExtensions() {\n        return (this.json.extensionsRemoved || []);\n    }\n    getObjectExtension(object, extensionName) {\n        const extensions = object.extensions || {};\n        return extensions[extensionName];\n    }\n    getScene(index) {\n        return this.getObject('scenes', index);\n    }\n    getNode(index) {\n        return this.getObject('nodes', index);\n    }\n    getSkin(index) {\n        return this.getObject('skins', index);\n    }\n    getMesh(index) {\n        return this.getObject('meshes', index);\n    }\n    getMaterial(index) {\n        return this.getObject('materials', index);\n    }\n    getAccessor(index) {\n        return this.getObject('accessors', index);\n    }\n    // getCamera(index: number): object | null {\n    //   return null; // TODO: fix thi: object  as null;\n    // }\n    getTexture(index) {\n        return this.getObject('textures', index);\n    }\n    getSampler(index) {\n        return this.getObject('samplers', index);\n    }\n    getImage(index) {\n        return this.getObject('images', index);\n    }\n    getBufferView(index) {\n        return this.getObject('bufferViews', index);\n    }\n    getBuffer(index) {\n        return this.getObject('buffers', index);\n    }\n    getObject(array, index) {\n        // check if already resolved\n        if (typeof index === 'object') {\n            return index;\n        }\n        const object = this.json[array] && this.json[array][index];\n        if (!object) {\n            throw new Error(`glTF file error: Could not find ${array}[${index}]`); // eslint-disable-line\n        }\n        return object;\n    }\n    /**\n     * Accepts buffer view index or buffer view object\n     * @returns a `Uint8Array`\n     */\n    getTypedArrayForBufferView(bufferView) {\n        bufferView = this.getBufferView(bufferView);\n        // @ts-ignore\n        const bufferIndex = bufferView.buffer;\n        // Get hold of the arrayBuffer\n        // const buffer = this.getBuffer(bufferIndex);\n        const binChunk = this.gltf.buffers[bufferIndex];\n        assert$1(binChunk);\n        // @ts-ignore\n        const byteOffset = (bufferView.byteOffset || 0) + binChunk.byteOffset;\n        // @ts-ignore\n        return new Uint8Array(binChunk.arrayBuffer, byteOffset, bufferView.byteLength);\n    }\n    /** Accepts accessor index or accessor object\n     * @returns a typed array with type that matches the types\n     */\n    getTypedArrayForAccessor(accessor) {\n        // @ts-ignore\n        const gltfAccessor = this.getAccessor(accessor);\n        return getTypedArrayForAccessor(this.gltf.json, this.gltf.buffers, gltfAccessor);\n    }\n    /** accepts accessor index or accessor object\n     * returns a `Uint8Array`\n     */\n    getTypedArrayForImageData(image) {\n        // @ts-ignore\n        image = this.getAccessor(image);\n        // @ts-ignore\n        const bufferView = this.getBufferView(image.bufferView);\n        const buffer = this.getBuffer(bufferView.buffer);\n        // @ts-ignore\n        const arrayBuffer = buffer.data;\n        const byteOffset = bufferView.byteOffset || 0;\n        return new Uint8Array(arrayBuffer, byteOffset, bufferView.byteLength);\n    }\n    // MODIFERS\n    /**\n     * Add an extra application-defined key to the top-level data structure\n     */\n    addApplicationData(key, data) {\n        this.json[key] = data;\n        return this;\n    }\n    /**\n     * `extras` - Standard GLTF field for storing application specific data\n     */\n    addExtraData(key, data) {\n        this.json.extras = this.json.extras || {};\n        this.json.extras[key] = data;\n        return this;\n    }\n    addObjectExtension(object, extensionName, data) {\n        // @ts-ignore\n        object.extensions = object.extensions || {};\n        // TODO - clobber or merge?\n        // @ts-ignore\n        object.extensions[extensionName] = data;\n        this.registerUsedExtension(extensionName);\n        return this;\n    }\n    setObjectExtension(object, extensionName, data) {\n        const extensions = object.extensions || {};\n        extensions[extensionName] = data;\n        // TODO - add to usedExtensions...\n    }\n    removeObjectExtension(object, extensionName) {\n        const extensions = object?.extensions || {};\n        if (extensions[extensionName]) {\n            this.json.extensionsRemoved = this.json.extensionsRemoved || [];\n            const extensionsRemoved = this.json.extensionsRemoved;\n            if (!extensionsRemoved.includes(extensionName)) {\n                extensionsRemoved.push(extensionName);\n            }\n        }\n        delete extensions[extensionName];\n    }\n    /**\n     * Add to standard GLTF top level extension object, mark as used\n     */\n    addExtension(extensionName, extensionData = {}) {\n        assert$1(extensionData);\n        this.json.extensions = this.json.extensions || {};\n        this.json.extensions[extensionName] = extensionData;\n        this.registerUsedExtension(extensionName);\n        return extensionData;\n    }\n    /**\n     * Standard GLTF top level extension object, mark as used and required\n     */\n    addRequiredExtension(extensionName, extensionData = {}) {\n        assert$1(extensionData);\n        this.addExtension(extensionName, extensionData);\n        this.registerRequiredExtension(extensionName);\n        return extensionData;\n    }\n    /**\n     * Add extensionName to list of used extensions\n     */\n    registerUsedExtension(extensionName) {\n        this.json.extensionsUsed = this.json.extensionsUsed || [];\n        if (!this.json.extensionsUsed.find((ext) => ext === extensionName)) {\n            this.json.extensionsUsed.push(extensionName);\n        }\n    }\n    /**\n     * Add extensionName to list of required extensions\n     */\n    registerRequiredExtension(extensionName) {\n        this.registerUsedExtension(extensionName);\n        this.json.extensionsRequired = this.json.extensionsRequired || [];\n        if (!this.json.extensionsRequired.find((ext) => ext === extensionName)) {\n            this.json.extensionsRequired.push(extensionName);\n        }\n    }\n    /**\n     * Removes an extension from the top-level list\n     */\n    removeExtension(extensionName) {\n        if (this.json.extensions?.[extensionName]) {\n            this.json.extensionsRemoved = this.json.extensionsRemoved || [];\n            const extensionsRemoved = this.json.extensionsRemoved;\n            if (!extensionsRemoved.includes(extensionName)) {\n                extensionsRemoved.push(extensionName);\n            }\n        }\n        if (this.json.extensions) {\n            delete this.json.extensions[extensionName];\n        }\n        if (this.json.extensionsRequired) {\n            this._removeStringFromArray(this.json.extensionsRequired, extensionName);\n        }\n        if (this.json.extensionsUsed) {\n            this._removeStringFromArray(this.json.extensionsUsed, extensionName);\n        }\n    }\n    /**\n     *  Set default scene which is to be displayed at load time\n     */\n    setDefaultScene(sceneIndex) {\n        this.json.scene = sceneIndex;\n    }\n    /**\n     * @todo: add more properties for scene initialization:\n     *   name`, `extensions`, `extras`\n     *   https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#reference-scene\n     */\n    addScene(scene) {\n        const { nodeIndices } = scene;\n        this.json.scenes = this.json.scenes || [];\n        this.json.scenes.push({ nodes: nodeIndices });\n        return this.json.scenes.length - 1;\n    }\n    /**\n     * @todo: add more properties for node initialization:\n     *   `name`, `extensions`, `extras`, `camera`, `children`, `skin`, `rotation`, `scale`, `translation`, `weights`\n     *   https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#node\n     */\n    addNode(node) {\n        const { meshIndex, matrix } = node;\n        this.json.nodes = this.json.nodes || [];\n        const nodeData = { mesh: meshIndex };\n        if (matrix) {\n            // @ts-ignore\n            nodeData.matrix = matrix;\n        }\n        this.json.nodes.push(nodeData);\n        return this.json.nodes.length - 1;\n    }\n    /** Adds a mesh to the json part */\n    addMesh(mesh) {\n        const { attributes, indices, material, mode = 4 } = mesh;\n        const accessors = this._addAttributes(attributes);\n        const glTFMesh = {\n            primitives: [\n                {\n                    attributes: accessors,\n                    mode\n                }\n            ]\n        };\n        if (indices) {\n            const indicesAccessor = this._addIndices(indices);\n            // @ts-ignore\n            glTFMesh.primitives[0].indices = indicesAccessor;\n        }\n        if (Number.isFinite(material)) {\n            // @ts-ignore\n            glTFMesh.primitives[0].material = material;\n        }\n        this.json.meshes = this.json.meshes || [];\n        this.json.meshes.push(glTFMesh);\n        return this.json.meshes.length - 1;\n    }\n    addPointCloud(attributes) {\n        // @ts-ignore\n        const accessorIndices = this._addAttributes(attributes);\n        const glTFMesh = {\n            primitives: [\n                {\n                    attributes: accessorIndices,\n                    mode: 0 // GL.POINTS\n                }\n            ]\n        };\n        this.json.meshes = this.json.meshes || [];\n        this.json.meshes.push(glTFMesh);\n        return this.json.meshes.length - 1;\n    }\n    /**\n     * Adds a binary image. Builds glTF \"JSON metadata\" and saves buffer reference\n     * Buffer will be copied into BIN chunk during \"pack\"\n     * Currently encodes as glTF image\n     * @param imageData\n     * @param mimeType\n     */\n    addImage(imageData, mimeTypeOpt) {\n        // If image is referencing a bufferView instead of URI, mimeType must be defined:\n        //   https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#images\n        //   \"a reference to a bufferView; in that case mimeType must be defined.\"\n        const metadata = getBinaryImageMetadata(imageData);\n        const mimeType = mimeTypeOpt || metadata?.mimeType;\n        const bufferViewIndex = this.addBufferView(imageData);\n        const glTFImage = {\n            bufferView: bufferViewIndex,\n            mimeType\n        };\n        this.json.images = this.json.images || [];\n        this.json.images.push(glTFImage);\n        return this.json.images.length - 1;\n    }\n    /**\n     * Add one untyped source buffer, create a matching glTF `bufferView`, and return its index\n     * @param buffer\n     */\n    addBufferView(buffer, bufferIndex = 0, byteOffset = this.byteLength) {\n        const byteLength = buffer.byteLength;\n        assert$1(Number.isFinite(byteLength));\n        // Add this buffer to the list of buffers to be written to the body.\n        this.sourceBuffers = this.sourceBuffers || [];\n        this.sourceBuffers.push(buffer);\n        const glTFBufferView = {\n            buffer: bufferIndex,\n            // Write offset from the start of the binary body\n            byteOffset,\n            byteLength\n        };\n        // We've now added the contents to the body, so update the total length\n        // Every sub-chunk needs to be 4-byte align ed\n        this.byteLength += padToNBytes(byteLength, 4);\n        // Add a bufferView indicating start and length of this binary sub-chunk\n        this.json.bufferViews = this.json.bufferViews || [];\n        this.json.bufferViews.push(glTFBufferView);\n        return this.json.bufferViews.length - 1;\n    }\n    /**\n     * Adds an accessor to a bufferView\n     * @param bufferViewIndex\n     * @param accessor\n     */\n    addAccessor(bufferViewIndex, accessor) {\n        const glTFAccessor = {\n            bufferView: bufferViewIndex,\n            // @ts-ignore\n            type: getAccessorTypeFromSize(accessor.size),\n            // @ts-ignore\n            componentType: accessor.componentType,\n            // @ts-ignore\n            count: accessor.count,\n            // @ts-ignore\n            max: accessor.max,\n            // @ts-ignore\n            min: accessor.min\n        };\n        this.json.accessors = this.json.accessors || [];\n        this.json.accessors.push(glTFAccessor);\n        return this.json.accessors.length - 1;\n    }\n    /**\n     * Add a binary buffer. Builds glTF \"JSON metadata\" and saves buffer reference\n     * Buffer will be copied into BIN chunk during \"pack\"\n     * Currently encodes buffers as glTF accessors, but this could be optimized\n     * @param sourceBuffer\n     * @param accessor\n     */\n    addBinaryBuffer(sourceBuffer, accessor = { size: 3 }) {\n        const bufferViewIndex = this.addBufferView(sourceBuffer);\n        // @ts-ignore\n        let minMax = { min: accessor.min, max: accessor.max };\n        if (!minMax.min || !minMax.max) {\n            // @ts-ignore\n            minMax = this._getAccessorMinMax(sourceBuffer, accessor.size);\n        }\n        const accessorDefaults = {\n            // @ts-ignore\n            size: accessor.size,\n            componentType: getComponentTypeFromArray(sourceBuffer),\n            // @ts-ignore\n            count: Math.round(sourceBuffer.length / accessor.size),\n            min: minMax.min,\n            max: minMax.max\n        };\n        return this.addAccessor(bufferViewIndex, Object.assign(accessorDefaults, accessor));\n    }\n    /**\n     * Adds a texture to the json part\n     * @todo: add more properties for texture initialization\n     * `sampler`, `name`, `extensions`, `extras`\n     * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#texture\n     */\n    addTexture(texture) {\n        const { imageIndex } = texture;\n        const glTFTexture = {\n            source: imageIndex\n        };\n        this.json.textures = this.json.textures || [];\n        this.json.textures.push(glTFTexture);\n        return this.json.textures.length - 1;\n    }\n    /** Adds a material to the json part */\n    addMaterial(pbrMaterialInfo) {\n        this.json.materials = this.json.materials || [];\n        this.json.materials.push(pbrMaterialInfo);\n        return this.json.materials.length - 1;\n    }\n    /** Pack the binary chunk */\n    createBinaryChunk() {\n        // Allocate total array\n        const totalByteLength = this.byteLength;\n        const arrayBuffer = new ArrayBuffer(totalByteLength);\n        const targetArray = new Uint8Array(arrayBuffer);\n        // Copy each array into\n        let dstByteOffset = 0;\n        for (const sourceBuffer of this.sourceBuffers || []) {\n            dstByteOffset = copyToArray(sourceBuffer, targetArray, dstByteOffset);\n        }\n        // Update the glTF BIN CHUNK byte length\n        if (this.json?.buffers?.[0]) {\n            this.json.buffers[0].byteLength = totalByteLength;\n        }\n        else {\n            this.json.buffers = [{ byteLength: totalByteLength }];\n        }\n        // Save generated arrayBuffer\n        this.gltf.binary = arrayBuffer;\n        // Put arrayBuffer to sourceBuffers for possible additional writing data in the chunk\n        this.sourceBuffers = [arrayBuffer];\n        this.gltf.buffers = [{ arrayBuffer, byteOffset: 0, byteLength: arrayBuffer.byteLength }];\n    }\n    // PRIVATE\n    _removeStringFromArray(array, string) {\n        let found = true;\n        while (found) {\n            const index = array.indexOf(string);\n            if (index > -1) {\n                array.splice(index, 1);\n            }\n            else {\n                found = false;\n            }\n        }\n    }\n    /**\n     * Add attributes to buffers and create `attributes` object which is part of `mesh`\n     */\n    _addAttributes(attributes = {}) {\n        const result = {};\n        for (const attributeKey in attributes) {\n            const attributeData = attributes[attributeKey];\n            const attrName = this._getGltfAttributeName(attributeKey);\n            const accessor = this.addBinaryBuffer(attributeData.value, attributeData);\n            result[attrName] = accessor;\n        }\n        return result;\n    }\n    /**\n     * Add indices to buffers\n     */\n    _addIndices(indices) {\n        return this.addBinaryBuffer(indices, { size: 1 });\n    }\n    /**\n     * Deduce gltf specific attribue name from input attribute name\n     */\n    _getGltfAttributeName(attributeName) {\n        switch (attributeName.toLowerCase()) {\n            case 'position':\n            case 'positions':\n            case 'vertices':\n                return 'POSITION';\n            case 'normal':\n            case 'normals':\n                return 'NORMAL';\n            case 'color':\n            case 'colors':\n                return 'COLOR_0';\n            case 'texcoord':\n            case 'texcoords':\n                return 'TEXCOORD_0';\n            default:\n                return attributeName;\n        }\n    }\n    /**\n     * Calculate `min` and `max` arrays of accessor according to spec:\n     * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#reference-accessor\n     */\n    _getAccessorMinMax(buffer, size) {\n        const result = { min: null, max: null };\n        if (buffer.length < size) {\n            return result;\n        }\n        // @ts-ignore\n        result.min = [];\n        // @ts-ignore\n        result.max = [];\n        const initValues = buffer.subarray(0, size);\n        for (const value of initValues) {\n            // @ts-ignore\n            result.min.push(value);\n            // @ts-ignore\n            result.max.push(value);\n        }\n        for (let index = size; index < buffer.length; index += size) {\n            for (let componentIndex = 0; componentIndex < size; componentIndex++) {\n                // @ts-ignore\n                result.min[0 + componentIndex] = Math.min(\n                // @ts-ignore\n                result.min[0 + componentIndex], buffer[index + componentIndex]);\n                // @ts-ignore\n                result.max[0 + componentIndex] = Math.max(\n                // @ts-ignore\n                result.max[0 + componentIndex], buffer[index + componentIndex]);\n            }\n        }\n        return result;\n    }\n}\n\n/**\n * loaders.gl, MIT license\n *\n * Shared code for 3DTiles extensions:\n * * EXT_feature_metadata\n * * EXT_mesh_features\n * * EXT_structural_metadata\n */\nfunction emod(n) {\n    return ((n % 1) + 1) % 1;\n}\nconst ATTRIBUTE_TYPE_TO_COMPONENTS = {\n    SCALAR: 1,\n    VEC2: 2,\n    VEC3: 3,\n    VEC4: 4,\n    MAT2: 4,\n    MAT3: 9,\n    MAT4: 16,\n    BOOLEAN: 1,\n    STRING: 1,\n    ENUM: 1\n};\nconst ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY = {\n    INT8: Int8Array,\n    UINT8: Uint8Array,\n    INT16: Int16Array,\n    UINT16: Uint16Array,\n    INT32: Int32Array,\n    UINT32: Uint32Array,\n    INT64: BigInt64Array,\n    UINT64: BigUint64Array,\n    FLOAT32: Float32Array,\n    FLOAT64: Float64Array\n};\nconst ATTRIBUTE_COMPONENT_TYPE_TO_BYTE_SIZE = {\n    INT8: 1,\n    UINT8: 1,\n    INT16: 2,\n    UINT16: 2,\n    INT32: 4,\n    UINT32: 4,\n    INT64: 8,\n    UINT64: 8,\n    FLOAT32: 4,\n    FLOAT64: 8\n};\nfunction getArrayElementByteSize(attributeType, componentType) {\n    return (ATTRIBUTE_COMPONENT_TYPE_TO_BYTE_SIZE[componentType] *\n        ATTRIBUTE_TYPE_TO_COMPONENTS[attributeType]);\n}\n/**\n * Gets offset array from `arrayOffsets` or `stringOffsets`.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param bufferViewIndex - Buffer view index\n * @param offsetType - The type of values in `arrayOffsets` or `stringOffsets`.\n * @param numberOfElements - The number of elements in each property array.\n * @returns Array of values offsets. The number of offsets in the array is equal to `numberOfElements` plus one.\n */\nfunction getOffsetsForProperty(scenegraph, bufferViewIndex, offsetType, numberOfElements) {\n    if (offsetType !== 'UINT8' &&\n        offsetType !== 'UINT16' &&\n        offsetType !== 'UINT32' &&\n        offsetType !== 'UINT64') {\n        return null;\n    }\n    const arrayOffsetsBytes = scenegraph.getTypedArrayForBufferView(bufferViewIndex);\n    const arrayOffsets = convertRawBufferToMetadataArray(arrayOffsetsBytes, 'SCALAR', // offsets consist of ONE component\n    offsetType, numberOfElements + 1 // The number of offsets is equal to the property table `count` plus one.\n    );\n    // We don't support BigInt offsets at the moment. It requires additional logic and potential issues in Safari\n    if (arrayOffsets instanceof BigInt64Array || arrayOffsets instanceof BigUint64Array) {\n        return null;\n    }\n    return arrayOffsets;\n}\n/**\n * Converts raw bytes that are in the buffer to an array of the type defined by the schema.\n * @param data - Raw bytes in the buffer.\n * @param attributeType - SCALAR, VECN, MATN.\n * @param componentType - Type of the component in elements, e.g. 'UINT8' or 'FLOAT32'.\n * @param elementCount - Number of elements in the array. Default value is 1.\n * @returns Data array\n */\nfunction convertRawBufferToMetadataArray(data, attributeType, componentType, elementCount = 1) {\n    const numberOfComponents = ATTRIBUTE_TYPE_TO_COMPONENTS[attributeType];\n    const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[componentType];\n    const size = ATTRIBUTE_COMPONENT_TYPE_TO_BYTE_SIZE[componentType];\n    const length = elementCount * numberOfComponents;\n    const byteLength = length * size;\n    let buffer = data.buffer;\n    let offset = data.byteOffset;\n    if (offset % size !== 0) {\n        const bufferArray = new Uint8Array(buffer);\n        buffer = bufferArray.slice(offset, offset + byteLength).buffer;\n        offset = 0;\n    }\n    return new ArrayType(buffer, offset, length);\n}\n/**\n * Processes data encoded in the texture associated with the primitive.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param textureInfo - Reference to the texture where extension data are stored.\n * @param primitive - Primitive object in the mesh.\n * @returns Array of data taken. Null if data can't be taken from the texture.\n */\nfunction getPrimitiveTextureData(scenegraph, textureInfo, primitive) {\n    /*\n      texture.index is an index for the \"textures\" array.\n      The texture object referenced by this index looks like this:\n      {\n      \"sampler\": 0,\n      \"source\": 0\n      }\n      \"sampler\" is an index for the \"samplers\" array\n      \"source\" is an index for the \"images\" array that contains data stored in rgba channels of the image.\n  \n      texture.texCoord is a number-suffix (like 1) for an attribute like \"TEXCOORD_1\" in meshes.primitives\n      The value of \"TEXCOORD_1\" is an accessor that is used to get coordinates.\n      These coordinates are being used to get data from the image.\n      \n      Default for texture.texCoord is 0\n      @see https://github.com/CesiumGS/glTF/blob/3d-tiles-next/specification/2.0/schema/textureInfo.schema.json\n    */\n    const texCoordAccessorKey = `TEXCOORD_${textureInfo.texCoord || 0}`;\n    const texCoordAccessorIndex = primitive.attributes[texCoordAccessorKey];\n    const textureCoordinates = scenegraph.getTypedArrayForAccessor(texCoordAccessorIndex);\n    const json = scenegraph.gltf.json;\n    const textureIndex = textureInfo.index;\n    const imageIndex = json.textures?.[textureIndex]?.source;\n    if (typeof imageIndex !== 'undefined') {\n        const mimeType = json.images?.[imageIndex]?.mimeType;\n        const parsedImage = scenegraph.gltf.images?.[imageIndex];\n        // Checking for width is to prevent handling Un-processed images (e.g. [analyze] stage, where loadImages option is set to false)\n        if (parsedImage && typeof parsedImage.width !== 'undefined') {\n            const textureData = [];\n            for (let index = 0; index < textureCoordinates.length; index += 2) {\n                const value = getImageValueByCoordinates(parsedImage, mimeType, textureCoordinates, index, textureInfo.channels);\n                textureData.push(value);\n            }\n            return textureData;\n        }\n    }\n    return [];\n}\n/**\n * Puts property data to attributes.\n * It creates corresponding buffer, bufferView and accessor\n * so the data can be accessed like regular data stored in buffers.\n * @param scenegraph - Scenegraph object.\n * @param attributeName - Name of the attribute.\n * @param propertyData - Property data to store.\n * @param featureTable - Array where unique data from the property data are being stored.\n * @param primitive - Primitive object.\n */\nfunction primitivePropertyDataToAttributes(scenegraph, attributeName, propertyData, featureTable, primitive) {\n    // No reason to create an empty buffer if there is no property data to store.\n    if (!propertyData?.length) {\n        return;\n    }\n    /*\n      featureTable will contain unique values, e.g.\n      propertyData = [24, 35, 28, 24]\n      featureTable = [24, 35, 28]\n      featureIndices will contain indices that refer featureTextureTable, e.g.\n      featureIndices = [0, 1, 2, 0]\n    */\n    const featureIndices = [];\n    for (const texelData of propertyData) {\n        let index = featureTable.findIndex((item) => item === texelData);\n        if (index === -1) {\n            index = featureTable.push(texelData) - 1;\n        }\n        featureIndices.push(index);\n    }\n    const typedArray = new Uint32Array(featureIndices);\n    const bufferIndex = scenegraph.gltf.buffers.push({\n        arrayBuffer: typedArray.buffer,\n        byteOffset: typedArray.byteOffset,\n        byteLength: typedArray.byteLength\n    }) - 1;\n    const bufferViewIndex = scenegraph.addBufferView(typedArray, bufferIndex, 0);\n    const accessorIndex = scenegraph.addAccessor(bufferViewIndex, {\n        size: 1,\n        componentType: getComponentTypeFromArray(typedArray),\n        count: typedArray.length\n    });\n    primitive.attributes[attributeName] = accessorIndex;\n}\n/**\n * Gets the value from the texture by coordinates provided.\n * @param parsedImage - Image where the data are stored.\n * @param mimeType - MIME type.\n * @param textureCoordinates - uv coordinates to access data in the image.\n * @param index - Index of uv coordinates in the array textureCoordinates.\n * @param channels - Image channels where data are stored.\n *  Channels of an RGBA texture are numbered 0..3 respectively.\n *  For Ext_mesh_features and EXT_strucural_metadata the channels default is [0]\n *  @see https://github.com/CesiumGS/glTF/blob/3d-tiles-next/extensions/2.0/Vendor/EXT_mesh_features/schema/featureIdTexture.schema.json\n *  @see https://github.com/CesiumGS/glTF/blob/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata/schema/propertyTexture.property.schema.json\n * @returns Value taken from the image.\n */\nfunction getImageValueByCoordinates(parsedImage, mimeType, textureCoordinates, index, channels = [0]) {\n    const CHANNELS_MAP = {\n        r: { offset: 0, shift: 0 },\n        g: { offset: 1, shift: 8 },\n        b: { offset: 2, shift: 16 },\n        a: { offset: 3, shift: 24 }\n    };\n    const u = textureCoordinates[index];\n    const v = textureCoordinates[index + 1];\n    let components = 1;\n    if (mimeType && (mimeType.indexOf('image/jpeg') !== -1 || mimeType.indexOf('image/png') !== -1))\n        components = 4;\n    const offset = coordinatesToOffset(u, v, parsedImage, components);\n    let value = 0;\n    for (const c of channels) {\n        /*\n        According to the EXT_feature_metadata extension specification:\n          Channels are labeled by rgba and are swizzled with a string of 1-4 characters.\n        According to the EXT_mesh_features extension specification:\n          The channels array contains non-negative integer values corresponding to channels of the source texture that the feature ID consists of.\n          Channels of an RGBA texture are numbered 0–3 respectively.\n        Function getImageValueByCoordinates is used to process both extensions.\n        So, there should be possible to get the element of CHANNELS_MAP by either index (0, 1, 2, 3) or key (r, g, b, a).\n        */\n        const map = typeof c === 'number' ? Object.values(CHANNELS_MAP)[c] : CHANNELS_MAP[c];\n        const imageOffset = offset + map.offset;\n        const imageData = getImageData(parsedImage);\n        if (imageData.data.length <= imageOffset) {\n            throw new Error(`${imageData.data.length} <= ${imageOffset}`);\n        }\n        const imageValue = imageData.data[imageOffset];\n        value |= imageValue << map.shift;\n    }\n    return value;\n}\n/**\n * Retrieves the offset in the image where the data are stored.\n * @param u - u-coordinate.\n * @param v - v-coordinate.\n * @param parsedImage - Image where the data are stored.\n * @param componentsCount - Number of components the data consists of.\n * @returns Offset in the image where the data are stored.\n */\nfunction coordinatesToOffset(u, v, parsedImage, componentsCount = 1) {\n    const w = parsedImage.width;\n    const iX = emod(u) * (w - 1);\n    const indX = Math.round(iX);\n    const h = parsedImage.height;\n    const iY = emod(v) * (h - 1);\n    const indY = Math.round(iY);\n    const components = parsedImage.components ? parsedImage.components : componentsCount;\n    // components is a number of channels in the image\n    const offset = (indY * w + indX) * components;\n    return offset;\n}\n/**\n * Parses variable-length array data.\n * In this case every value of the property in the table will be an array\n * of arbitrary length.\n * @param valuesData - Values in a flat typed array.\n * @param numberOfElements - Number of rows in the property table.\n * @param arrayOffsets - Offsets of nested arrays in the flat values array.\n * @param valuesDataBytesLength - Data byte length.\n * @param valueSize - Value size in bytes.\n * @returns Array of typed arrays.\n */\nfunction parseVariableLengthArrayNumeric(valuesData, numberOfElements, arrayOffsets, valuesDataBytesLength, valueSize) {\n    const attributeValueArray = [];\n    for (let index = 0; index < numberOfElements; index++) {\n        const arrayOffset = arrayOffsets[index];\n        const arrayByteSize = arrayOffsets[index + 1] - arrayOffsets[index];\n        if (arrayByteSize + arrayOffset > valuesDataBytesLength) {\n            break;\n        }\n        const typedArrayOffset = arrayOffset / valueSize;\n        const elementCount = arrayByteSize / valueSize;\n        attributeValueArray.push(valuesData.slice(typedArrayOffset, typedArrayOffset + elementCount));\n    }\n    return attributeValueArray;\n}\n/**\n * Parses fixed-length array data.\n * In this case every value of the property in the table will be an array\n * of constant length equal to `arrayCount`.\n * @param valuesData - Values in a flat typed array.\n * @param numberOfElements - Number of rows in the property table.\n * @param arrayCount - Nested arrays length.\n * @returns Array of typed arrays.\n */\nfunction parseFixedLengthArrayNumeric(valuesData, numberOfElements, arrayCount) {\n    const attributeValueArray = [];\n    for (let index = 0; index < numberOfElements; index++) {\n        const elementOffset = index * arrayCount;\n        attributeValueArray.push(valuesData.slice(elementOffset, elementOffset + arrayCount));\n    }\n    return attributeValueArray;\n}\n/**\n * Decodes properties of string type from binary source.\n * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @param valuesDataBytes - Data taken from values property of the property table property.\n * @param arrayOffsets - Offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.\n * @param stringOffsets - Index of the buffer view containing offsets for strings. It should be available for string type.\n * @returns String property values\n */\nfunction getPropertyDataString(numberOfElements, valuesDataBytes, arrayOffsets, stringOffsets) {\n    if (arrayOffsets) {\n        // TODO: implement it as soon as we have the corresponding tileset\n        throw new Error('Not implemented - arrayOffsets for strings is specified');\n    }\n    if (stringOffsets) {\n        const stringsArray = [];\n        const textDecoder = new TextDecoder('utf8');\n        let stringOffset = 0;\n        for (let index = 0; index < numberOfElements; index++) {\n            const stringByteSize = stringOffsets[index + 1] - stringOffsets[index];\n            if (stringByteSize + stringOffset <= valuesDataBytes.length) {\n                const stringData = valuesDataBytes.subarray(stringOffset, stringByteSize + stringOffset);\n                const stringAttribute = textDecoder.decode(stringData);\n                stringsArray.push(stringAttribute);\n                stringOffset += stringByteSize;\n            }\n        }\n        return stringsArray;\n    }\n    return [];\n}\n\nconst EXT_MESH_FEATURES_NAME = 'EXT_mesh_features';\nconst name$a = EXT_MESH_FEATURES_NAME;\nasync function decode$b(gltfData, options) {\n    const scenegraph = new GLTFScenegraph(gltfData);\n    decodeExtMeshFeatures(scenegraph, options);\n}\nfunction encode$5(gltfData, options) {\n    const scenegraph = new GLTFScenegraph(gltfData);\n    encodeExtMeshFeatures(scenegraph);\n    scenegraph.createBinaryChunk();\n    return scenegraph.gltf;\n}\n/**\n * Decodes feature metadata from extension.\n * @param {GLTFScenegraph} scenegraph - Instance of the class for structured access to GLTF data.\n * @param {GLTFLoaderOptions} options - GLTFLoader options.\n */\nfunction decodeExtMeshFeatures(scenegraph, options) {\n    const json = scenegraph.gltf.json;\n    if (!json.meshes) {\n        return;\n    }\n    // Iterate through all meshes/primitives.\n    for (const mesh of json.meshes) {\n        for (const primitive of mesh.primitives) {\n            processMeshPrimitiveFeatures(scenegraph, primitive, options);\n        }\n    }\n}\n/**\n * Takes data from EXT_mesh_features and store it in 'data' property of featureIds.\n * If combined with EXT_structural_metadata, corresponding data are taken from the property tables of that extension.\n * @param {GLTFScenegraph} scenegraph - Instance of the class for structured access to GLTF data.\n * @param {GLTFMeshPrimitive} primitive - Primitive that contains extensions.\n * @param {GLTFLoaderOptions} options - GLTFLoader options.\n */\nfunction processMeshPrimitiveFeatures(scenegraph, primitive, options) {\n    // Processing of mesh primitive features requires buffers to be loaded.\n    if (!options?.gltf?.loadBuffers) {\n        return;\n    }\n    const extension = primitive.extensions?.[EXT_MESH_FEATURES_NAME];\n    const featureIds = extension?.featureIds;\n    if (!featureIds) {\n        return;\n    }\n    for (const featureId of featureIds) {\n        let featureIdData;\n        // Process \"Feature ID by Vertex\"\n        if (typeof featureId.attribute !== 'undefined') {\n            const accessorKey = `_FEATURE_ID_${featureId.attribute}`;\n            const accessorIndex = primitive.attributes[accessorKey];\n            featureIdData = scenegraph.getTypedArrayForAccessor(accessorIndex);\n        }\n        // Process \"Feature ID by Texture Coordinates\"\n        else if (typeof featureId.texture !== 'undefined' && options?.gltf?.loadImages) {\n            featureIdData = getPrimitiveTextureData(scenegraph, featureId.texture, primitive);\n        }\n        // Process \"Feature ID by Index\"\n        else {\n            /*\n            When both featureId.attribute and featureId.texture are undefined,\n            then the feature ID value for each vertex is given implicitly, via the index of the vertex.\n            In this case, the featureCount must match the number of vertices of the mesh primitive.\n            */\n            // TODO: At the moment of writing we don't have a tileset with the data of that kind. Implement it later.\n            featureIdData = [];\n        }\n        featureId.data = featureIdData;\n    }\n}\n/*\n  Encoding data\n*/\nfunction encodeExtMeshFeatures(scenegraph, options) {\n    const meshes = scenegraph.gltf.json.meshes;\n    if (!meshes) {\n        return;\n    }\n    // Iterate through all meshes/primitives.\n    for (const mesh of meshes) {\n        for (const primitive of mesh.primitives) {\n            encodeExtMeshFeaturesForPrimitive(scenegraph, primitive);\n        }\n    }\n}\n/**\n * Creates ExtMeshFeatures, creates a featureId containing feature ids provided.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param primitive - target primitive instance that will contain the extension\n * @param featureIdArray - Array of feature id\n * @param propertyTableIndex - index of the property table created by the ExtStructuralMetadata (optional).\n */\nfunction createExtMeshFeatures(scenegraph, primitive, featureIdArray, propertyTableIndex) {\n    if (!primitive.extensions) {\n        primitive.extensions = {};\n    }\n    let extension = primitive.extensions[EXT_MESH_FEATURES_NAME];\n    if (!extension) {\n        extension = { featureIds: [] };\n        primitive.extensions[EXT_MESH_FEATURES_NAME] = extension;\n    }\n    const { featureIds } = extension;\n    const featureId = {\n        featureCount: featureIdArray.length,\n        propertyTable: propertyTableIndex,\n        data: featureIdArray\n    };\n    featureIds.push(featureId);\n    scenegraph.addObjectExtension(primitive, EXT_MESH_FEATURES_NAME, extension);\n}\n/**\n * Encodes a feature ID set to extension.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param primitive - Primitive that the data encoded belongs to.\n * @see https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_mesh_features\n */\nfunction encodeExtMeshFeaturesForPrimitive(scenegraph, primitive) {\n    const extension = primitive.extensions?.[EXT_MESH_FEATURES_NAME];\n    if (!extension) {\n        return;\n    }\n    const featureIds = extension.featureIds;\n    featureIds.forEach((featureId, elementIndex) => {\n        if (featureId.data) {\n            const { accessorKey, index } = createAccessorKey(primitive.attributes);\n            const typedArray = new Uint32Array(featureId.data);\n            // Clean up featureId object.\n            // Everything that could come from the original extension in case of round-trip decode/encode operations should be deleted.\n            // We need make sure the featureId object is clean.\n            featureIds[elementIndex] = {\n                featureCount: typedArray.length,\n                propertyTable: featureId.propertyTable,\n                attribute: index\n            };\n            scenegraph.gltf.buffers.push({\n                arrayBuffer: typedArray.buffer,\n                byteOffset: typedArray.byteOffset,\n                byteLength: typedArray.byteLength\n            });\n            const bufferViewIndex = scenegraph.addBufferView(typedArray);\n            const accessorIndex = scenegraph.addAccessor(bufferViewIndex, {\n                size: 1,\n                componentType: getComponentTypeFromArray(typedArray),\n                count: typedArray.length\n            });\n            primitive.attributes[accessorKey] = accessorIndex;\n        }\n    });\n}\n/**\n * Creates an accessor key for the attribute array provided.\n * The generated key has a suffix (number) that is the next consequtive in the list of existing accessors.\n * @param attributes - attribute array\n * @returns accessor key and the key suffix (number) used in the key.\n */\nfunction createAccessorKey(attributes) {\n    const prefix = '_FEATURE_ID_';\n    // Search for all \"_FEATURE_ID_n\" attribures in the primitive provided if any.\n    // If there are some, e.g. \"_FEATURE_ID_0\", \"_FEATURE_ID_1\",\n    // we will add a new one with the name \"_FEATURE_ID_2\"\n    const attrs = Object.keys(attributes).filter((item) => item.indexOf(prefix) === 0);\n    let max = -1;\n    for (const a of attrs) {\n        const n = Number(a.substring(prefix.length));\n        if (n > max) {\n            max = n;\n        }\n    }\n    max++;\n    const accessorKey = `${prefix}${max}`;\n    return { accessorKey, index: max };\n}\n\nvar EXT_mesh_features = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$a,\n    decode: decode$b,\n    encode: encode$5,\n    createExtMeshFeatures: createExtMeshFeatures\n});\n\nconst EXT_STRUCTURAL_METADATA_NAME = 'EXT_structural_metadata';\nconst name$9 = EXT_STRUCTURAL_METADATA_NAME;\nasync function decode$a(gltfData, options) {\n    const scenegraph = new GLTFScenegraph(gltfData);\n    decodeExtStructuralMetadata(scenegraph, options);\n}\nfunction encode$4(gltfData, options) {\n    const scenegraph = new GLTFScenegraph(gltfData);\n    encodeExtStructuralMetadata(scenegraph);\n    scenegraph.createBinaryChunk();\n    return scenegraph.gltf;\n}\n/*\n// Example of the extension.\n// See more info at https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata\nconst extensions = {\n  \"extensions\": {\n    \"EXT_structural_metadata\": {\n      \"schema\": {\n        \"classes\": {\n          \"tree\": {\n            \"name\": \"Tree\",\n            \"description\": \"Woody, perennial plant.\",\n            \"properties\": {\n              \"species\": {\n                \"description\": \"Type of tree.\",\n                \"type\": \"ENUM\",\n                \"enumType\": \"speciesEnum\",\n                \"required\": true\n              },\n              \"age\": {\n                \"description\": \"The age of the tree, in years\",\n                \"type\": \"SCALAR\",\n                \"componentType\": \"UINT8\",\n                \"required\": true\n              }\n            }\n          }\n        },\n        \"enums\": {\n          \"speciesEnum\": {\n            \"name\": \"Species\",\n            \"description\": \"An example enum for tree species.\",\n            // valueType is not defined here. Default is \"UINT16\"\n            \"values\": [\n              { \"name\": \"Unspecified\", \"value\": 0 },\n              { \"name\": \"Oak\", \"value\": 1 }\n            ]\n          }\n        }\n      },\n      \"propertyTables\": [{\n        \"name\": \"tree_survey_2021-09-29\",\n        \"class\": \"tree\",\n        \"count\": 10,  // The number of elements in each property array (in `species`, in `age`).\n        \"properties\": {\n          \"species\": {\n            \"values\": 0, // It's an index of the buffer view containing property values.\n          },\n          \"age\": {\n            \"values\": 1\n          }\n        }\n      }]\n    }\n  }\n}\n*/\n/**\n * Decodes feature metadata from extension.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param options - GLTFLoader options.\n */\nfunction decodeExtStructuralMetadata(scenegraph, options) {\n    // Decoding metadata involves buffers processing.\n    // So, if buffers have not been loaded, there is no reason to process metadata.\n    if (!options.gltf?.loadBuffers) {\n        return;\n    }\n    const extension = scenegraph.getExtension(EXT_STRUCTURAL_METADATA_NAME);\n    if (!extension) {\n        return;\n    }\n    if (options.gltf?.loadImages) {\n        decodePropertyTextures$1(scenegraph, extension);\n    }\n    decodePropertyTables$1(scenegraph, extension);\n}\n/**\n * Processes the data stored in the textures\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param extension - Top-level extension.\n */\nfunction decodePropertyTextures$1(scenegraph, extension) {\n    const propertyTextures = extension.propertyTextures;\n    const json = scenegraph.gltf.json;\n    if (propertyTextures && json.meshes) {\n        // Iterate through all meshes/primitives.\n        for (const mesh of json.meshes) {\n            for (const primitive of mesh.primitives) {\n                processPrimitivePropertyTextures(scenegraph, propertyTextures, primitive, extension);\n            }\n        }\n    }\n}\n/**\n * Processes the data stored in the property tables.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param extension - Top-level extension.\n */\nfunction decodePropertyTables$1(scenegraph, extension) {\n    const schema = extension.schema;\n    if (!schema) {\n        return;\n    }\n    const schemaClasses = schema.classes;\n    const propertyTables = extension.propertyTables;\n    if (schemaClasses && propertyTables) {\n        for (const schemaName in schemaClasses) {\n            const propertyTable = findPropertyTableByClass$1(propertyTables, schemaName);\n            if (propertyTable) {\n                processPropertyTable$1(scenegraph, schema, propertyTable);\n            }\n        }\n    }\n}\n/**\n * Finds the property table by class name.\n * @param propertyTables - propertyTable definition taken from the top-level extension.\n * @param schemaClassName - class name in the extension schema.\n */\nfunction findPropertyTableByClass$1(propertyTables, schemaClassName) {\n    for (const propertyTable of propertyTables) {\n        if (propertyTable.class === schemaClassName) {\n            return propertyTable;\n        }\n    }\n    return null;\n}\n/**\n * Takes data from property textures reffered by the primitive.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param propertyTextures - propertyTexture definition taken from the top-level extention.\n * @param primitive - Primitive object.\n * @param extension - Top-level extension.\n */\nfunction processPrimitivePropertyTextures(scenegraph, propertyTextures, primitive, extension) {\n    if (!propertyTextures) {\n        return;\n    }\n    const primitiveExtension = primitive.extensions?.[EXT_STRUCTURAL_METADATA_NAME];\n    const primitivePropertyTextureIndices = primitiveExtension?.propertyTextures;\n    if (!primitivePropertyTextureIndices) {\n        return;\n    }\n    for (const primitivePropertyTextureIndex of primitivePropertyTextureIndices) {\n        const propertyTexture = propertyTextures[primitivePropertyTextureIndex];\n        processPrimitivePropertyTexture(scenegraph, propertyTexture, primitive, extension);\n    }\n}\n/**\n * Takes property data from the texture pointed by the primitive and appends them to `exension.data`.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param propertyTexture - propertyTexture definition taken from the top-level extension.\n * @param primitive - Primitive object.\n * @param extension - Top-level extension.\n */\nfunction processPrimitivePropertyTexture(scenegraph, propertyTexture, primitive, extension) {\n    if (!propertyTexture.properties) {\n        return;\n    }\n    if (!extension.dataAttributeNames) {\n        extension.dataAttributeNames = [];\n    }\n    /* Iterate through all properties defined in propertyTexture, e.g. \"speed\" and \"direction\":\n      {\n        \"class\": \"wind\",\n        \"properties\": {\n          \"speed\": {\n            \"index\": 0,\n            \"texCoord\": 0,\n            \"channels\": [0]\n          },\n          \"direction\": {\n            \"index\": 0,\n            \"texCoord\": 0,\n            \"channels\": [1, 2]\n          }\n        }\n      }\n    */\n    const className = propertyTexture.class;\n    for (const propertyName in propertyTexture.properties) {\n        // propertyName has values like \"speed\", \"direction\"\n        // Make attributeName as a combination of the class name and the propertyName like \"wind_speed\" or \"wind_direction\"\n        const attributeName = `${className}_${propertyName}`;\n        const textureInfoTopLevel = propertyTexture.properties?.[propertyName];\n        if (!textureInfoTopLevel) {\n            // eslint-disable-next-line no-continue\n            continue;\n        }\n        // The data taken from all meshes/primitives (the same property, e.g. \"speed\" or \"direction\") will be combined into one array and saved in textureInfoTopLevel.data\n        // Initially textureInfoTopLevel.data will be initialized with an empty array.\n        if (!textureInfoTopLevel.data) {\n            textureInfoTopLevel.data = [];\n        }\n        const featureTextureTable = textureInfoTopLevel.data;\n        const propertyData = getPrimitiveTextureData(scenegraph, textureInfoTopLevel, primitive);\n        if (propertyData === null) {\n            // eslint-disable-next-line no-continue\n            continue;\n        }\n        primitivePropertyDataToAttributes(scenegraph, attributeName, propertyData, featureTextureTable, primitive);\n        textureInfoTopLevel.data = featureTextureTable;\n        extension.dataAttributeNames.push(attributeName);\n    }\n}\n/**\n * Navigates through all properies in the property table, gets properties data,\n * and put the data to `propertyTable.data` as an array.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param schema - schema object.\n * @param propertyTable - propertyTable definition taken from the top-level extension.\n */\nfunction processPropertyTable$1(scenegraph, schema, propertyTable) {\n    const schemaClass = schema.classes?.[propertyTable.class];\n    if (!schemaClass) {\n        throw new Error(`Incorrect data in the EXT_structural_metadata extension: no schema class with name ${propertyTable.class}`);\n    }\n    const numberOfElements = propertyTable.count; // `propertyTable.count` is a number of elements in each property array.\n    for (const propertyName in schemaClass.properties) {\n        const classProperty = schemaClass.properties[propertyName];\n        const propertyTableProperty = propertyTable.properties?.[propertyName];\n        if (propertyTableProperty) {\n            // Getting all elements (`numberOfElements`) of the array in the `propertyTableProperty`\n            const data = getPropertyDataFromBinarySource$1(scenegraph, schema, classProperty, numberOfElements, propertyTableProperty);\n            propertyTableProperty.data = data;\n        }\n    }\n}\n/**\n * Decodes a propertyTable column from binary source based on property type.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param schema - Schema object.\n * @param classProperty - class property object.\n * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @param propertyTableProperty - propertyTable's property metadata.\n * @returns {string[] | number[] | string[][] | number[][]}\n */\nfunction getPropertyDataFromBinarySource$1(scenegraph, schema, classProperty, numberOfElements, propertyTableProperty) {\n    let data = [];\n    const valuesBufferView = propertyTableProperty.values;\n    const valuesDataBytes = scenegraph.getTypedArrayForBufferView(valuesBufferView);\n    const arrayOffsets = getArrayOffsetsForProperty$1(scenegraph, classProperty, propertyTableProperty, numberOfElements);\n    const stringOffsets = getStringOffsetsForProperty$1(scenegraph, propertyTableProperty, numberOfElements);\n    switch (classProperty.type) {\n        case 'SCALAR':\n        case 'VEC2':\n        case 'VEC3':\n        case 'VEC4':\n        case 'MAT2':\n        case 'MAT3':\n        case 'MAT4': {\n            data = getPropertyDataNumeric$1(classProperty, numberOfElements, valuesDataBytes, arrayOffsets);\n            break;\n        }\n        case 'BOOLEAN': {\n            // TODO: implement it as soon as we have the corresponding tileset\n            throw new Error(`Not implemented - classProperty.type=${classProperty.type}`);\n        }\n        case 'STRING': {\n            data = getPropertyDataString(numberOfElements, valuesDataBytes, arrayOffsets, stringOffsets);\n            break;\n        }\n        case 'ENUM': {\n            data = getPropertyDataENUM(schema, classProperty, numberOfElements, valuesDataBytes, arrayOffsets);\n            break;\n        }\n        default:\n            throw new Error(`Unknown classProperty type ${classProperty.type}`);\n    }\n    return data;\n}\n/**\n * Parses propertyTable.property.arrayOffsets that are offsets of sub-arrays in a flatten array of values.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param classProperty - class property object.\n * @param propertyTableProperty - propertyTable's property metadata.\n * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @returns Typed array with offset values.\n * @see https://github.com/CesiumGS/glTF/blob/2976f1183343a47a29e4059a70961371cd2fcee8/extensions/2.0/Vendor/EXT_structural_metadata/schema/propertyTable.property.schema.json#L21\n */\nfunction getArrayOffsetsForProperty$1(scenegraph, classProperty, propertyTableProperty, numberOfElements) {\n    if (classProperty.array &&\n        // `count` is a number of array elements. May only be defined when `array` is true.\n        // If `count` is NOT defined, it's a VARIABLE-length array\n        typeof classProperty.count === 'undefined' &&\n        // `arrayOffsets` is an index of the buffer view containing offsets for variable-length arrays.\n        typeof propertyTableProperty.arrayOffsets !== 'undefined') {\n        // Data are in a VARIABLE-length array\n        return getOffsetsForProperty(scenegraph, propertyTableProperty.arrayOffsets, propertyTableProperty.arrayOffsetType || 'UINT32', numberOfElements);\n    }\n    return null;\n}\n/**\n * Parses propertyTable.property.stringOffsets.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param propertyTableProperty - propertyTable's property metadata.\n * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @returns Typed array with offset values.\n * @see https://github.com/CesiumGS/glTF/blob/2976f1183343a47a29e4059a70961371cd2fcee8/extensions/2.0/Vendor/EXT_structural_metadata/schema/propertyTable.property.schema.json#L29C10-L29C23\n */\nfunction getStringOffsetsForProperty$1(scenegraph, propertyTableProperty, numberOfElements) {\n    if (typeof propertyTableProperty.stringOffsets !== 'undefined' // `stringOffsets` is an index of the buffer view containing offsets for strings.\n    ) {\n        // Data are in a FIXED-length array\n        return getOffsetsForProperty(scenegraph, propertyTableProperty.stringOffsets, propertyTableProperty.stringOffsetType || 'UINT32', numberOfElements);\n    }\n    return null;\n}\n/**\n * Decodes properties of SCALAR, VEC-N, MAT-N types from binary sourse.\n * @param classProperty - class property object.\n * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @param valuesDataBytes - Data taken from values property of the property table property.\n * @param arrayOffsets - Offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.\n * @returns Property values in a typed array or in an array of typed arrays.\n */\nfunction getPropertyDataNumeric$1(classProperty, numberOfElements, valuesDataBytes, arrayOffsets) {\n    const isArray = classProperty.array;\n    const arrayCount = classProperty.count;\n    const elementSize = getArrayElementByteSize(classProperty.type, classProperty.componentType);\n    const elementCount = valuesDataBytes.byteLength / elementSize;\n    let valuesData;\n    if (classProperty.componentType) {\n        valuesData = convertRawBufferToMetadataArray(valuesDataBytes, classProperty.type, \n        // The datatype of the element's components. Only applicable to `SCALAR`, `VECN`, and `MATN` types.\n        classProperty.componentType, elementCount);\n    }\n    else {\n        // The spec doesn't provide any info what to do if componentType is not set.\n        valuesData = valuesDataBytes;\n    }\n    if (isArray) {\n        if (arrayOffsets) {\n            // VARIABLE-length array\n            return parseVariableLengthArrayNumeric(valuesData, numberOfElements, arrayOffsets, valuesDataBytes.length, elementSize);\n        }\n        if (arrayCount) {\n            // FIXED-length array\n            return parseFixedLengthArrayNumeric(valuesData, numberOfElements, arrayCount);\n        }\n        return [];\n    }\n    return valuesData;\n}\n/**\n * Decodes properties of enum type from binary source.\n * @param schema - Schema object.\n * @param classProperty - Class property object.\n * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @param valuesDataBytes - Data taken from values property of the property table property.\n * @param arrayOffsets - Offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.\n * @returns Strings array of nested strings array.\n */\nfunction getPropertyDataENUM(schema, classProperty, numberOfElements, valuesDataBytes, arrayOffsets) {\n    const enumType = classProperty.enumType;\n    // Enum ID as declared in the `enums` dictionary. Required when `type` is `ENUM`.\n    if (!enumType) {\n        throw new Error('Incorrect data in the EXT_structural_metadata extension: classProperty.enumType is not set for type ENUM');\n    }\n    const enumEntry = schema.enums?.[enumType];\n    if (!enumEntry) {\n        throw new Error(`Incorrect data in the EXT_structural_metadata extension: schema.enums does't contain ${enumType}`);\n    }\n    const enumValueType = enumEntry.valueType || 'UINT16';\n    const elementSize = getArrayElementByteSize(classProperty.type, enumValueType);\n    const elementCount = valuesDataBytes.byteLength / elementSize;\n    let valuesData = convertRawBufferToMetadataArray(valuesDataBytes, classProperty.type, enumValueType, elementCount);\n    if (!valuesData) {\n        valuesData = valuesDataBytes;\n    }\n    if (classProperty.array) {\n        if (arrayOffsets) {\n            // VARIABLE-length array\n            return parseVariableLengthArrayENUM({\n                valuesData,\n                numberOfElements,\n                arrayOffsets,\n                valuesDataBytesLength: valuesDataBytes.length,\n                elementSize,\n                enumEntry\n            });\n        }\n        const arrayCount = classProperty.count;\n        if (arrayCount) {\n            // FIXED-length array\n            return parseFixedLengthArrayENUM(valuesData, numberOfElements, arrayCount, enumEntry);\n        }\n        return [];\n    }\n    // Single value (not an array)\n    return getEnumsArray(valuesData, 0, numberOfElements, enumEntry);\n}\n/**\n * Parses variable length nested ENUM arrays.\n * @param params.valuesData - Values in a flat typed array.\n * @param params.numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @param params.arrayOffsets - Offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.\n * @param params.valuesDataBytesLength - Byte length of values array.\n * @param params.elementSize - Single element byte size.\n * @param params.enumEntry - Enums dictionary.\n * @returns Nested strings array.\n */\nfunction parseVariableLengthArrayENUM(params) {\n    const { valuesData, numberOfElements, arrayOffsets, valuesDataBytesLength, elementSize, enumEntry } = params;\n    const attributeValueArray = [];\n    for (let index = 0; index < numberOfElements; index++) {\n        const arrayOffset = arrayOffsets[index];\n        const arrayByteSize = arrayOffsets[index + 1] - arrayOffsets[index];\n        if (arrayByteSize + arrayOffset > valuesDataBytesLength) {\n            break;\n        }\n        const typedArrayOffset = arrayOffset / elementSize;\n        const elementCount = arrayByteSize / elementSize;\n        const array = getEnumsArray(valuesData, typedArrayOffset, elementCount, enumEntry);\n        attributeValueArray.push(array);\n    }\n    return attributeValueArray;\n}\n/**\n * Parses fixed length ENUM arrays.\n * @param valuesData - Values in a flat typed array.\n * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @param arrayCount - Nested arrays length.\n * @param enumEntry - Enums dictionary.\n * @returns Nested strings array.\n */\nfunction parseFixedLengthArrayENUM(valuesData, numberOfElements, arrayCount, enumEntry) {\n    const attributeValueArray = [];\n    for (let index = 0; index < numberOfElements; index++) {\n        const elementOffset = arrayCount * index;\n        const array = getEnumsArray(valuesData, elementOffset, arrayCount, enumEntry);\n        attributeValueArray.push(array);\n    }\n    return attributeValueArray;\n}\n/**\n * Parses ENUM values into a string array.\n * @param valuesData - Values in a flat typed array.\n * @param offset - Offset to start parse from.\n * @param count - Values length to parse.\n * @param enumEntry - Enums dictionary.\n * @returns Array of strings with parsed ENUM names.\n */\nfunction getEnumsArray(valuesData, offset, count, enumEntry) {\n    const array = [];\n    for (let i = 0; i < count; i++) {\n        // At the moment we don't support BigInt. It requires additional calculations logic\n        // and might be an issue in Safari\n        if (valuesData instanceof BigInt64Array || valuesData instanceof BigUint64Array) {\n            array.push('');\n        }\n        else {\n            const value = valuesData[offset + i];\n            const enumObject = getEnumByValue(enumEntry, value);\n            if (enumObject) {\n                array.push(enumObject.name);\n            }\n            else {\n                array.push('');\n            }\n        }\n    }\n    return array;\n}\n/**\n * Looks up ENUM whose `value` property matches the specified number in the parameter `value`.\n * @param {GLTF_EXT_structural_metadata_Enum} enumEntry - ENUM entry containing the array of possible enums.\n * @param {number} value - The value of the ENUM to locate.\n * @returns {GLTF_EXT_structural_metadata_EnumValue | null} ENUM matcihng the specified value or null of no ENUM object was found.\n */\nfunction getEnumByValue(enumEntry, value) {\n    for (const enumValue of enumEntry.values) {\n        if (enumValue.value === value) {\n            return enumValue;\n        }\n    }\n    return null;\n}\nconst SCHEMA_CLASS_ID_DEFAULT = 'schemaClassId';\nfunction encodeExtStructuralMetadata(scenegraph, options) {\n    const extension = scenegraph.getExtension(EXT_STRUCTURAL_METADATA_NAME);\n    if (!extension) {\n        return;\n    }\n    if (extension.propertyTables) {\n        for (const table of extension.propertyTables) {\n            const classId = table.class;\n            const schemaClass = extension.schema?.classes?.[classId];\n            if (table.properties && schemaClass) {\n                encodeProperties(table, schemaClass, scenegraph);\n            }\n        }\n    }\n}\nfunction encodeProperties(table, schemaClass, scenegraph) {\n    for (const propertyName in table.properties) {\n        const data = table.properties[propertyName].data;\n        if (data) {\n            const classProperty = schemaClass.properties[propertyName];\n            if (classProperty) {\n                const tableProperty = createPropertyTableProperty(data, classProperty, scenegraph);\n                // Override table property that came with \"data\"\n                table.properties[propertyName] = tableProperty;\n            }\n        }\n    }\n}\n/**\n * Creates ExtStructuralMetadata, creates the schema and creates a property table containing feature data provided.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param propertyAttributes - property attributes\n * @param classId - classId to use for encoding metadata.\n * @returns Index of the table created.\n */\nfunction createExtStructuralMetadata(scenegraph, propertyAttributes, classId = SCHEMA_CLASS_ID_DEFAULT) {\n    let extension = scenegraph.getExtension(EXT_STRUCTURAL_METADATA_NAME);\n    if (!extension) {\n        extension = scenegraph.addExtension(EXT_STRUCTURAL_METADATA_NAME);\n    }\n    extension.schema = createSchema(propertyAttributes, classId, extension.schema);\n    const table = createPropertyTable(propertyAttributes, classId, extension.schema);\n    if (!extension.propertyTables) {\n        extension.propertyTables = [];\n    }\n    return extension.propertyTables.push(table) - 1; // index of the table\n}\nfunction createSchema(propertyAttributes, classId, schemaToUpdate) {\n    const schema = schemaToUpdate ?? {\n        id: 'schema_id'\n    };\n    const schemaClass = {\n        properties: {}\n    };\n    for (const attribute of propertyAttributes) {\n        const classProperty = {\n            type: attribute.elementType,\n            componentType: attribute.componentType\n        };\n        schemaClass.properties[attribute.name] = classProperty;\n    }\n    schema.classes = {};\n    schema.classes[classId] = schemaClass;\n    return schema;\n}\nfunction createPropertyTable(propertyAttributes, classId, schema) {\n    const table = {\n        class: classId,\n        count: 0\n    };\n    // count is a number of rows in the table\n    let count = 0;\n    const schemaClass = schema.classes?.[classId];\n    for (const attribute of propertyAttributes) {\n        if (count === 0) {\n            count = attribute.values.length;\n        }\n        // The number of elements in all propertyAttributes must be the same\n        if (count !== attribute.values.length && attribute.values.length) {\n            throw new Error('Illegal values in attributes');\n        }\n        const classProperty = schemaClass?.properties[attribute.name];\n        if (classProperty) {\n            // const tableProperty = createPropertyTableProperty(attribute, classProperty, scenegraph);\n            if (!table.properties) {\n                table.properties = {};\n            }\n            // values is a required field. Its real value will be set while encoding data\n            table.properties[attribute.name] = { values: 0, data: attribute.values };\n        }\n    }\n    table.count = count;\n    return table;\n}\nfunction createPropertyTableProperty(\n// attribute: PropertyAttribute,\nvalues, classProperty, scenegraph) {\n    const prop = { values: 0 };\n    if (classProperty.type === 'STRING') {\n        const { stringData, stringOffsets } = createPropertyDataString(values);\n        prop.stringOffsets = createBufferView(stringOffsets, scenegraph);\n        prop.values = createBufferView(stringData, scenegraph);\n    }\n    else if (classProperty.type === 'SCALAR' && classProperty.componentType) {\n        const data = createPropertyDataScalar(values, classProperty.componentType);\n        prop.values = createBufferView(data, scenegraph);\n    }\n    return prop;\n}\nconst COMPONENT_TYPE_TO_ARRAY_CONSTRUCTOR = {\n    INT8: Int8Array,\n    UINT8: Uint8Array,\n    INT16: Int16Array,\n    UINT16: Uint16Array,\n    INT32: Int32Array,\n    UINT32: Uint32Array,\n    INT64: Int32Array,\n    UINT64: Uint32Array,\n    FLOAT32: Float32Array,\n    FLOAT64: Float64Array\n};\nfunction createPropertyDataScalar(array, componentType) {\n    const numberArray = [];\n    for (const value of array) {\n        numberArray.push(Number(value));\n    }\n    const Construct = COMPONENT_TYPE_TO_ARRAY_CONSTRUCTOR[componentType];\n    if (!Construct) {\n        throw new Error('Illegal component type');\n    }\n    return new Construct(numberArray);\n}\nfunction createPropertyDataString(strings) {\n    const utf8Encode = new TextEncoder();\n    const arr = [];\n    let len = 0;\n    for (const str of strings) {\n        const uint8Array = utf8Encode.encode(str);\n        len += uint8Array.length;\n        arr.push(uint8Array);\n    }\n    const strArray = new Uint8Array(len);\n    const strOffsets = [];\n    let offset = 0;\n    for (const str of arr) {\n        strArray.set(str, offset);\n        strOffsets.push(offset);\n        offset += str.length;\n    }\n    strOffsets.push(offset); // The last offset represents the byte offset after the last string.\n    const stringOffsetsTypedArray = new Uint32Array(strOffsets); // Its length = len+1\n    return { stringData: strArray, stringOffsets: stringOffsetsTypedArray };\n}\nfunction createBufferView(typedArray, scenegraph) {\n    scenegraph.gltf.buffers.push({\n        arrayBuffer: typedArray.buffer,\n        byteOffset: typedArray.byteOffset,\n        byteLength: typedArray.byteLength\n    });\n    return scenegraph.addBufferView(typedArray);\n}\n\nvar EXT_structural_metadata = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$9,\n    decode: decode$a,\n    encode: encode$4,\n    createExtStructuralMetadata: createExtStructuralMetadata\n});\n\n/** Extension name */\nconst EXT_FEATURE_METADATA_NAME = 'EXT_feature_metadata';\nconst name$8 = EXT_FEATURE_METADATA_NAME;\nasync function decode$9(gltfData, options) {\n    const scenegraph = new GLTFScenegraph(gltfData);\n    decodeExtFeatureMetadata(scenegraph, options);\n}\n/**\n * Decodes feature metadata from extension.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param options - GLTFLoader options.\n */\nfunction decodeExtFeatureMetadata(scenegraph, options) {\n    // Decoding metadata involves buffers processing.\n    // So, if buffers have not been loaded, there is no reason to process metadata.\n    if (!options.gltf?.loadBuffers) {\n        return;\n    }\n    const extension = scenegraph.getExtension(EXT_FEATURE_METADATA_NAME);\n    if (!extension) {\n        return;\n    }\n    if (options.gltf?.loadImages) {\n        decodePropertyTextures(scenegraph, extension);\n    }\n    decodePropertyTables(scenegraph, extension);\n}\n/**\n * Processes the data stored in the textures\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param extension - Top-level extension.\n */\nfunction decodePropertyTextures(scenegraph, extension) {\n    const schema = extension.schema;\n    if (!schema) {\n        return;\n    }\n    const schemaClasses = schema.classes;\n    const { featureTextures } = extension;\n    if (schemaClasses && featureTextures) {\n        for (const schemaName in schemaClasses) {\n            const schemaClass = schemaClasses[schemaName];\n            const featureTexture = findFeatureTextureByClass(featureTextures, schemaName);\n            if (featureTexture) {\n                handleFeatureTextureProperties(scenegraph, featureTexture, schemaClass);\n            }\n        }\n    }\n}\n/**\n * Processes the data stored in the property tables.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param extension - Top-level extension.\n */\nfunction decodePropertyTables(scenegraph, extension) {\n    const schema = extension.schema;\n    if (!schema) {\n        return;\n    }\n    const schemaClasses = schema.classes;\n    const propertyTables = extension.featureTables;\n    if (schemaClasses && propertyTables) {\n        for (const schemaName in schemaClasses) {\n            const propertyTable = findPropertyTableByClass(propertyTables, schemaName);\n            if (propertyTable) {\n                processPropertyTable(scenegraph, schema, propertyTable);\n            }\n        }\n    }\n}\n/**\n * Finds the property table by class name.\n * @param propertyTables - propertyTable definition taken from the top-level extension.\n * @param schemaClassName - class name in the extension schema.\n */\nfunction findPropertyTableByClass(propertyTables, schemaClassName) {\n    for (const propertyTableName in propertyTables) {\n        const propertyTable = propertyTables[propertyTableName];\n        if (propertyTable.class === schemaClassName) {\n            return propertyTable;\n        }\n    }\n    return null;\n}\nfunction findFeatureTextureByClass(featureTextures, schemaClassName) {\n    for (const featureTexturesName in featureTextures) {\n        const featureTable = featureTextures[featureTexturesName];\n        if (featureTable.class === schemaClassName) {\n            return featureTable;\n        }\n    }\n    return null;\n}\n/**\n * Navigates through all properies in the property table, gets properties data,\n * and put the data to `propertyTable.data` as an array.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param schema - schema object.\n * @param propertyTable - propertyTable definition taken from the top-level extension.\n */\nfunction processPropertyTable(scenegraph, schema, propertyTable) {\n    // Though 'class' is not required by spec, it doesn't make any scence when it's not provided.\n    // So, bale out here.\n    if (!propertyTable.class) {\n        return;\n    }\n    const schemaClass = schema.classes?.[propertyTable.class];\n    if (!schemaClass) {\n        throw new Error(`Incorrect data in the EXT_structural_metadata extension: no schema class with name ${propertyTable.class}`);\n    }\n    const numberOfElements = propertyTable.count; // `propertyTable.count` is a number of elements in each property array.\n    for (const propertyName in schemaClass.properties) {\n        const classProperty = schemaClass.properties[propertyName];\n        const propertyTableProperty = propertyTable.properties?.[propertyName];\n        if (propertyTableProperty) {\n            // Getting all elements (`numberOfElements`) of the array in the `propertyTableProperty`\n            const data = getPropertyDataFromBinarySource(scenegraph, schema, classProperty, numberOfElements, propertyTableProperty);\n            propertyTableProperty.data = data;\n        }\n    }\n}\n/**\n * Navigates through all properies in feature texture and gets properties data.\n * Data will be stored in featureTexture.properties[propertyName].data.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param featureTexture\n * @param schemaClass\n */\nfunction handleFeatureTextureProperties(scenegraph, featureTexture, schemaClass) {\n    const attributeName = featureTexture.class;\n    for (const propertyName in schemaClass.properties) {\n        const featureTextureProperty = featureTexture?.properties?.[propertyName];\n        if (featureTextureProperty) {\n            const data = getPropertyDataFromTexture(scenegraph, featureTextureProperty, attributeName);\n            featureTextureProperty.data = data;\n        }\n    }\n}\n/**\n * Decodes properties from binary sourse based on property type.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param schemaProperty\n * @param numberOfFeatures\n * @param featureTableProperty\n */\nfunction getPropertyDataFromBinarySource(scenegraph, schema, classProperty, numberOfFeatures, featureTableProperty) {\n    let data = [];\n    const bufferView = featureTableProperty.bufferView;\n    const dataArray = scenegraph.getTypedArrayForBufferView(bufferView);\n    const arrayOffsets = getArrayOffsetsForProperty(scenegraph, classProperty, featureTableProperty, numberOfFeatures);\n    const stringOffsets = getStringOffsetsForProperty(scenegraph, classProperty, featureTableProperty, numberOfFeatures);\n    if (classProperty.type === 'STRING' || classProperty.componentType === 'STRING') {\n        data = getPropertyDataString(numberOfFeatures, dataArray, arrayOffsets, stringOffsets);\n    }\n    else if (isNumericProperty(classProperty)) {\n        data = getPropertyDataNumeric(classProperty, numberOfFeatures, dataArray, arrayOffsets);\n    }\n    return data;\n}\n/**\n * Parses propertyTable.property.arrayOffsets that are offsets of sub-arrays in a flatten array of values.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param classProperty - class property object.\n * @param propertyTableProperty - propertyTable's property metadata.\n * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @returns Typed array with offset values.\n * @see https://github.com/CesiumGS/glTF/blob/2976f1183343a47a29e4059a70961371cd2fcee8/extensions/2.0/Vendor/EXT_structural_metadata/schema/propertyTable.property.schema.json#L21\n */\nfunction getArrayOffsetsForProperty(scenegraph, classProperty, propertyTableProperty, numberOfElements) {\n    /*\n     If ARRAY is used, then componentType must also be specified.\n     ARRAY is a fixed-length array when componentCount is defined, and variable-length otherwise.\n  */\n    if (classProperty.type === 'ARRAY' &&\n        // `componentCount` is a number of fixed-length array elements.\n        // If `componentCount` is NOT defined, it's a VARIABLE-length array\n        typeof classProperty.componentCount === 'undefined' &&\n        // `arrayOffsetBufferView` is an index of the buffer view containing offsets for variable-length arrays.\n        typeof propertyTableProperty.arrayOffsetBufferView !== 'undefined') {\n        // Data are in a VARIABLE-length array\n        return getOffsetsForProperty(scenegraph, propertyTableProperty.arrayOffsetBufferView, propertyTableProperty.offsetType || 'UINT32', // offsetType is used both for stringOffsetBufferView and arrayOffsetBufferView\n        numberOfElements);\n    }\n    return null;\n}\n/**\n * Parses featureTable.property.stringOffsetBufferView.\n * String offsets is an array of offsets of strings in the united array of characters.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param propertyTableProperty - propertyTable's property metadata.\n * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @returns Typed array of offset values. The number of offsets in the array is equal to `numberOfElements` plus one.\n * @see https://github.com/CesiumGS/glTF/blob/c38f7f37e894004353c15cd0481bc5b7381ce841/extensions/2.0/Vendor/EXT_feature_metadata/schema/featureTable.property.schema.json#L50C10-L50C32\n */\nfunction getStringOffsetsForProperty(scenegraph, classProperty, propertyTableProperty, numberOfElements) {\n    if (typeof propertyTableProperty.stringOffsetBufferView !== 'undefined' // `stringOffsetBufferView` is an index of the buffer view containing offsets for strings.\n    ) {\n        // Data are in a FIXED-length array\n        return getOffsetsForProperty(scenegraph, propertyTableProperty.stringOffsetBufferView, propertyTableProperty.offsetType || 'UINT32', // offsetType is used both for stringOffsetBufferView and arrayOffsetBufferView\n        numberOfElements);\n    }\n    return null;\n}\n/**\n * Checks if the feature table property is of numeric type.\n * @param schemaPropertyType - feature table property\n * @returns true if property is numeric, else - false\n */\nfunction isNumericProperty(schemaProperty) {\n    const types = [\n        'UINT8',\n        'INT16',\n        'UINT16',\n        'INT32',\n        'UINT32',\n        'INT64',\n        'UINT64',\n        'FLOAT32',\n        'FLOAT64'\n    ];\n    return (types.includes(schemaProperty.type) ||\n        (typeof schemaProperty.componentType !== 'undefined' &&\n            types.includes(schemaProperty.componentType)));\n}\n/**\n * Decodes properties of numeric types from binary sourse.\n * @param classProperty - class property object.\n * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.\n * @param valuesDataBytes - Data taken from values property of the property table property.\n * @param arrayOffsets - Offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.\n * @returns Property values in a typed array or in an array of typed arrays.\n */\nfunction getPropertyDataNumeric(classProperty, numberOfElements, valuesDataBytes, arrayOffsets) {\n    const isArray = classProperty.type === 'ARRAY';\n    const arrayCount = classProperty.componentCount;\n    /*\n    We are getting Numeric data. So,\n      the component type can be one of NumericComponentType,\n      the attribute type should be 'SCALAR'\n    */\n    const attributeType = 'SCALAR';\n    const componentType = classProperty.componentType || classProperty.type;\n    const elementSize = getArrayElementByteSize(attributeType, componentType);\n    const elementCount = valuesDataBytes.byteLength / elementSize;\n    const valuesData = convertRawBufferToMetadataArray(valuesDataBytes, attributeType, componentType, elementCount);\n    if (isArray) {\n        if (arrayOffsets) {\n            // VARIABLE-length array\n            return parseVariableLengthArrayNumeric(valuesData, numberOfElements, arrayOffsets, valuesDataBytes.length, elementSize);\n        }\n        if (arrayCount) {\n            // FIXED-length array\n            return parseFixedLengthArrayNumeric(valuesData, numberOfElements, arrayCount);\n        }\n        return [];\n    }\n    return valuesData;\n}\n/**\n * Gets properties from texture associated with all mesh primitives.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param featureTextureProperty\n * @param attributeName\n * @returns Feature texture data\n */\nfunction getPropertyDataFromTexture(scenegraph, featureTextureProperty, attributeName) {\n    const json = scenegraph.gltf.json;\n    if (!json.meshes) {\n        return [];\n    }\n    const featureTextureTable = [];\n    for (const mesh of json.meshes) {\n        for (const primitive of mesh.primitives) {\n            processPrimitiveTextures(scenegraph, attributeName, featureTextureProperty, featureTextureTable, primitive);\n        }\n    }\n    return featureTextureTable;\n}\n/**\n * Processes data encoded in the texture associated with the primitive. This data will be accessible through the attributes.\n * @param scenegraph - Instance of the class for structured access to GLTF data.\n * @param attributeName\n * @param featureTextureProperty\n * @param featureTextureTable\n * @param primitive\n */\nfunction processPrimitiveTextures(scenegraph, attributeName, featureTextureProperty, featureTextureTable, primitive) {\n    const textureInfoTopLevel = {\n        channels: featureTextureProperty.channels,\n        ...featureTextureProperty.texture\n    };\n    const propertyData = getPrimitiveTextureData(scenegraph, textureInfoTopLevel, primitive);\n    if (!propertyData) {\n        return;\n    }\n    primitivePropertyDataToAttributes(scenegraph, attributeName, propertyData, featureTextureTable, primitive);\n}\n\nvar EXT_feature_metadata = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$8,\n    decode: decode$9\n});\n\n// Version constant cannot be imported, it needs to correspond to the build version of **this** module.\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION$3 = \"4.3.3\" ;\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n// Version constant cannot be imported, it needs to correspond to the build version of **this** module.\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION$2 = \"4.3.3\" ;\n\n// loaders.gl\nconst BASIS_EXTERNAL_LIBRARIES = {\n    /** Basis transcoder, javascript wrapper part */\n    TRANSCODER: 'basis_transcoder.js',\n    /** Basis transcoder, compiled web assembly part */\n    TRANSCODER_WASM: 'basis_transcoder.wasm',\n    /** Basis encoder, javascript wrapper part */\n    ENCODER: 'basis_encoder.js',\n    /** Basis encoder, compiled web assembly part */\n    ENCODER_WASM: 'basis_encoder.wasm'\n};\nlet loadBasisTranscoderPromise;\n/**\n * Loads wasm transcoder module\n * @param options\n * @returns {BasisFile} promise\n */\nasync function loadBasisTranscoderModule(options) {\n    registerJSModules(options.modules);\n    const basis = getJSModuleOrNull('basis');\n    if (basis) {\n        return basis;\n    }\n    loadBasisTranscoderPromise ||= loadBasisTranscoder(options);\n    return await loadBasisTranscoderPromise;\n}\n/**\n * Loads wasm transcoder module\n * @param options\n * @returns {BasisFile} promise\n */\nasync function loadBasisTranscoder(options) {\n    let BASIS = null;\n    let wasmBinary = null;\n    [BASIS, wasmBinary] = await Promise.all([\n        await loadLibrary(BASIS_EXTERNAL_LIBRARIES.TRANSCODER, 'textures', options),\n        await loadLibrary(BASIS_EXTERNAL_LIBRARIES.TRANSCODER_WASM, 'textures', options)\n    ]);\n    // Depends on how import happened...\n    // @ts-ignore TS2339: Property does not exist on type\n    BASIS = BASIS || globalThis.BASIS;\n    return await initializeBasisTranscoderModule(BASIS, wasmBinary);\n}\n/**\n * Initialize wasm transcoder module\n * @param BasisModule - js part of the module\n * @param wasmBinary - wasm part of the module\n * @returns {BasisFile} promise\n */\nfunction initializeBasisTranscoderModule(BasisModule, wasmBinary) {\n    const options = {};\n    if (wasmBinary) {\n        options.wasmBinary = wasmBinary;\n    }\n    return new Promise((resolve) => {\n        // if you try to return BasisModule the browser crashes!\n        BasisModule(options).then((module) => {\n            const { BasisFile, initializeBasis } = module;\n            initializeBasis();\n            resolve({ BasisFile });\n        });\n    });\n}\nlet loadBasisEncoderPromise;\n/**\n * Loads wasm encoder module\n * @param options\n * @returns {BasisFile, KTX2File} promise\n */\nasync function loadBasisEncoderModule(options) {\n    const modules = options.modules || {};\n    if (modules.basisEncoder) {\n        return modules.basisEncoder;\n    }\n    loadBasisEncoderPromise = loadBasisEncoderPromise || loadBasisEncoder(options);\n    return await loadBasisEncoderPromise;\n}\n/**\n * Loads wasm encoder module\n * @param options\n * @returns {BasisFile, KTX2File} promise\n */\nasync function loadBasisEncoder(options) {\n    let BASIS_ENCODER = null;\n    let wasmBinary = null;\n    [BASIS_ENCODER, wasmBinary] = await Promise.all([\n        await loadLibrary(BASIS_EXTERNAL_LIBRARIES.ENCODER, 'textures', options),\n        await loadLibrary(BASIS_EXTERNAL_LIBRARIES.ENCODER_WASM, 'textures', options)\n    ]);\n    // Depends on how import happened...\n    // @ts-ignore TS2339: Property does not exist on type\n    BASIS_ENCODER = BASIS_ENCODER || globalThis.BASIS;\n    return await initializeBasisEncoderModule(BASIS_ENCODER, wasmBinary);\n}\n/**\n * Initialize wasm transcoder module\n * @param BasisEncoderModule - js part of the module\n * @param wasmBinary - wasm part of the module\n * @returns {BasisFile, KTX2File} promise\n */\nfunction initializeBasisEncoderModule(BasisEncoderModule, wasmBinary) {\n    const options = {};\n    if (wasmBinary) {\n        options.wasmBinary = wasmBinary;\n    }\n    return new Promise((resolve) => {\n        // if you try to return BasisModule the browser crashes!\n        BasisEncoderModule(options).then((module) => {\n            const { BasisFile, KTX2File, initializeBasis, BasisEncoder } = module;\n            initializeBasis();\n            resolve({ BasisFile, KTX2File, BasisEncoder });\n        });\n    });\n}\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n/* eslint-disable camelcase */\nconst GL_EXTENSIONS_CONSTANTS = {\n    // WEBGL_compressed_texture_s3tc\n    COMPRESSED_RGB_S3TC_DXT1_EXT: 0x83f0,\n    COMPRESSED_RGBA_S3TC_DXT1_EXT: 0x83f1,\n    COMPRESSED_RGBA_S3TC_DXT3_EXT: 0x83f2,\n    COMPRESSED_RGBA_S3TC_DXT5_EXT: 0x83f3,\n    // WEBGL_compressed_texture_es3\n    COMPRESSED_R11_EAC: 0x9270,\n    COMPRESSED_SIGNED_R11_EAC: 0x9271,\n    COMPRESSED_RG11_EAC: 0x9272,\n    COMPRESSED_SIGNED_RG11_EAC: 0x9273,\n    COMPRESSED_RGB8_ETC2: 0x9274,\n    COMPRESSED_RGBA8_ETC2_EAC: 0x9275,\n    COMPRESSED_SRGB8_ETC2: 0x9276,\n    COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 0x9277,\n    COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 0x9278,\n    COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 0x9279,\n    // WEBGL_compressed_texture_pvrtc\n    COMPRESSED_RGB_PVRTC_4BPPV1_IMG: 0x8c00,\n    COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: 0x8c02,\n    COMPRESSED_RGB_PVRTC_2BPPV1_IMG: 0x8c01,\n    COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: 0x8c03,\n    // WEBGL_compressed_texture_etc1\n    COMPRESSED_RGB_ETC1_WEBGL: 0x8d64,\n    // WEBGL_compressed_texture_atc\n    COMPRESSED_RGB_ATC_WEBGL: 0x8c92,\n    COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL: 0x8c93,\n    COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL: 0x87ee,\n    // WEBGL_compressed_texture_astc\n    COMPRESSED_RGBA_ASTC_4X4_KHR: 0x93b0,\n    COMPRESSED_RGBA_ASTC_5X4_KHR: 0x93b1,\n    COMPRESSED_RGBA_ASTC_5X5_KHR: 0x93b2,\n    COMPRESSED_RGBA_ASTC_6X5_KHR: 0x93b3,\n    COMPRESSED_RGBA_ASTC_6X6_KHR: 0x93b4,\n    COMPRESSED_RGBA_ASTC_8X5_KHR: 0x93b5,\n    COMPRESSED_RGBA_ASTC_8X6_KHR: 0x93b6,\n    COMPRESSED_RGBA_ASTC_8X8_KHR: 0x93b7,\n    COMPRESSED_RGBA_ASTC_10X5_KHR: 0x93b8,\n    COMPRESSED_RGBA_ASTC_10X6_KHR: 0x93b9,\n    COMPRESSED_RGBA_ASTC_10X8_KHR: 0x93ba,\n    COMPRESSED_RGBA_ASTC_10X10_KHR: 0x93bb,\n    COMPRESSED_RGBA_ASTC_12X10_KHR: 0x93bc,\n    COMPRESSED_RGBA_ASTC_12X12_KHR: 0x93bd,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_4X4_KHR: 0x93d0,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_5X4_KHR: 0x93d1,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_5X5_KHR: 0x93d2,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_6X5_KHR: 0x93d3,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_6X6_KHR: 0x93d4,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_8X5_KHR: 0x93d5,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_8X6_KHR: 0x93d6,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_8X8_KHR: 0x93d7,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_10X5_KHR: 0x93d8,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_10X6_KHR: 0x93d9,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_10X8_KHR: 0x93da,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_10X10_KHR: 0x93db,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_12X10_KHR: 0x93dc,\n    COMPRESSED_SRGB8_ALPHA8_ASTC_12X12_KHR: 0x93dd,\n    // EXT_texture_compression_rgtc\n    COMPRESSED_RED_RGTC1_EXT: 0x8dbb,\n    COMPRESSED_SIGNED_RED_RGTC1_EXT: 0x8dbc,\n    COMPRESSED_RED_GREEN_RGTC2_EXT: 0x8dbd,\n    COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: 0x8dbe,\n    // WEBGL_compressed_texture_s3tc_srgb\n    COMPRESSED_SRGB_S3TC_DXT1_EXT: 0x8c4c,\n    COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 0x8c4d,\n    COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 0x8c4e,\n    COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 0x8c4f\n};\n\n// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nconst BROWSER_PREFIXES = ['', 'WEBKIT_', 'MOZ_'];\nconst WEBGL_EXTENSIONS = {\n    /* eslint-disable camelcase */\n    WEBGL_compressed_texture_s3tc: 'dxt',\n    WEBGL_compressed_texture_s3tc_srgb: 'dxt-srgb',\n    WEBGL_compressed_texture_etc1: 'etc1',\n    WEBGL_compressed_texture_etc: 'etc2',\n    WEBGL_compressed_texture_pvrtc: 'pvrtc',\n    WEBGL_compressed_texture_atc: 'atc',\n    WEBGL_compressed_texture_astc: 'astc',\n    EXT_texture_compression_rgtc: 'rgtc'\n    /* eslint-enable camelcase */\n};\nlet formats = null;\n/**\n * Returns a list of formats.\n * Creates a temporary WebGLRenderingContext if none is provided.\n *\n * @param gl - Optional context.\n */\nfunction getSupportedGPUTextureFormats(gl) {\n    if (!formats) {\n        gl = gl || getWebGLContext() || undefined;\n        formats = new Set();\n        for (const prefix of BROWSER_PREFIXES) {\n            for (const extension in WEBGL_EXTENSIONS) {\n                if (gl && gl.getExtension(`${prefix}${extension}`)) {\n                    const gpuTextureFormat = WEBGL_EXTENSIONS[extension];\n                    formats.add(gpuTextureFormat);\n                }\n            }\n        }\n    }\n    return formats;\n}\n/**\n * @returns {WebGLRenderingContext?}\n */\nfunction getWebGLContext() {\n    try {\n        const canvas = document.createElement('canvas');\n        return canvas.getContext('webgl');\n    }\n    catch (error) {\n        return null;\n    }\n}\n\n// loaders.gl\nconst KTX2_ID = [\n    // '´', 'K', 'T', 'X', '2', '0', 'ª', '\\r', '\\n', '\\x1A', '\\n'\n    0xab, 0x4b, 0x54, 0x58, 0x20, 0x32, 0x30, 0xbb, 0x0d, 0x0a, 0x1a, 0x0a\n];\n// eslint-disable-next-line complexity\nfunction isKTX(data) {\n    // const id = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n    const id = new Uint8Array(data);\n    const notKTX = id.byteLength < KTX2_ID.length ||\n        id[0] !== KTX2_ID[0] || // '´'\n        id[1] !== KTX2_ID[1] || // 'K'\n        id[2] !== KTX2_ID[2] || // 'T'\n        id[3] !== KTX2_ID[3] || // 'X'\n        id[4] !== KTX2_ID[4] || // ' '\n        id[5] !== KTX2_ID[5] || // '2'\n        id[6] !== KTX2_ID[6] || // '0'\n        id[7] !== KTX2_ID[7] || // 'ª'\n        id[8] !== KTX2_ID[8] || // '\\r'\n        id[9] !== KTX2_ID[9] || // '\\n'\n        id[10] !== KTX2_ID[10] || // '\\x1A'\n        id[11] !== KTX2_ID[11]; // '\\n'\n    return !notKTX;\n}\n\n// loaders.gl\nconst OutputFormat = {\n    etc1: {\n        basisFormat: 0,\n        compressed: true,\n        format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_ETC1_WEBGL\n    },\n    etc2: { basisFormat: 1, compressed: true },\n    bc1: {\n        basisFormat: 2,\n        compressed: true,\n        format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_S3TC_DXT1_EXT\n    },\n    bc3: {\n        basisFormat: 3,\n        compressed: true,\n        format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT5_EXT\n    },\n    bc4: { basisFormat: 4, compressed: true },\n    bc5: { basisFormat: 5, compressed: true },\n    'bc7-m6-opaque-only': { basisFormat: 6, compressed: true },\n    'bc7-m5': { basisFormat: 7, compressed: true },\n    'pvrtc1-4-rgb': {\n        basisFormat: 8,\n        compressed: true,\n        format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_PVRTC_4BPPV1_IMG\n    },\n    'pvrtc1-4-rgba': {\n        basisFormat: 9,\n        compressed: true,\n        format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG\n    },\n    'astc-4x4': {\n        basisFormat: 10,\n        compressed: true,\n        format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_4X4_KHR\n    },\n    'atc-rgb': { basisFormat: 11, compressed: true },\n    'atc-rgba-interpolated-alpha': { basisFormat: 12, compressed: true },\n    rgba32: { basisFormat: 13, compressed: false },\n    rgb565: { basisFormat: 14, compressed: false },\n    bgr565: { basisFormat: 15, compressed: false },\n    rgba4444: { basisFormat: 16, compressed: false }\n};\n/**\n * parse data with a Binomial Basis_Universal module\n * @param data\n * @param options\n * @returns compressed texture data\n */\nasync function parseBasis(data, options) {\n    if (options.basis.containerFormat === 'auto') {\n        if (isKTX(data)) {\n            const fileConstructors = await loadBasisEncoderModule(options);\n            return parseKTX2File(fileConstructors.KTX2File, data, options);\n        }\n        const { BasisFile } = await loadBasisTranscoderModule(options);\n        return parseBasisFile(BasisFile, data, options);\n    }\n    switch (options.basis.module) {\n        case 'encoder':\n            const fileConstructors = await loadBasisEncoderModule(options);\n            switch (options.basis.containerFormat) {\n                case 'ktx2':\n                    return parseKTX2File(fileConstructors.KTX2File, data, options);\n                case 'basis':\n                default:\n                    return parseBasisFile(fileConstructors.BasisFile, data, options);\n            }\n        case 'transcoder':\n        default:\n            const { BasisFile } = await loadBasisTranscoderModule(options);\n            return parseBasisFile(BasisFile, data, options);\n    }\n}\n/**\n * Parse *.basis file data\n * @param BasisFile - initialized transcoder module\n * @param data\n * @param options\n * @returns compressed texture data\n */\nfunction parseBasisFile(BasisFile, data, options) {\n    const basisFile = new BasisFile(new Uint8Array(data));\n    try {\n        if (!basisFile.startTranscoding()) {\n            throw new Error('Failed to start basis transcoding');\n        }\n        const imageCount = basisFile.getNumImages();\n        const images = [];\n        for (let imageIndex = 0; imageIndex < imageCount; imageIndex++) {\n            const levelsCount = basisFile.getNumLevels(imageIndex);\n            const levels = [];\n            for (let levelIndex = 0; levelIndex < levelsCount; levelIndex++) {\n                levels.push(transcodeImage(basisFile, imageIndex, levelIndex, options));\n            }\n            images.push(levels);\n        }\n        return images;\n    }\n    finally {\n        basisFile.close();\n        basisFile.delete();\n    }\n}\n/**\n * Parse the particular level image of a basis file\n * @param basisFile\n * @param imageIndex\n * @param levelIndex\n * @param options\n * @returns compressed texture data\n */\nfunction transcodeImage(basisFile, imageIndex, levelIndex, options) {\n    const width = basisFile.getImageWidth(imageIndex, levelIndex);\n    const height = basisFile.getImageHeight(imageIndex, levelIndex);\n    // See https://github.com/BinomialLLC/basis_universal/pull/83\n    const hasAlpha = basisFile.getHasAlpha( /* imageIndex, levelIndex */);\n    // Check options for output format etc\n    const { compressed, format, basisFormat } = getBasisOptions(options, hasAlpha);\n    const decodedSize = basisFile.getImageTranscodedSizeInBytes(imageIndex, levelIndex, basisFormat);\n    const decodedData = new Uint8Array(decodedSize);\n    if (!basisFile.transcodeImage(decodedData, imageIndex, levelIndex, basisFormat, 0, 0)) {\n        throw new Error('failed to start Basis transcoding');\n    }\n    return {\n        // standard loaders.gl image category payload\n        width,\n        height,\n        data: decodedData,\n        compressed,\n        format,\n        // Additional fields\n        // Add levelSize field.\n        hasAlpha\n    };\n}\n/**\n * Parse *.ktx2 file data\n * @param KTX2File\n * @param data\n * @param options\n * @returns compressed texture data\n */\nfunction parseKTX2File(KTX2File, data, options) {\n    const ktx2File = new KTX2File(new Uint8Array(data));\n    try {\n        if (!ktx2File.startTranscoding()) {\n            throw new Error('failed to start KTX2 transcoding');\n        }\n        const levelsCount = ktx2File.getLevels();\n        const levels = [];\n        for (let levelIndex = 0; levelIndex < levelsCount; levelIndex++) {\n            levels.push(transcodeKTX2Image(ktx2File, levelIndex, options));\n        }\n        return [levels];\n    }\n    finally {\n        ktx2File.close();\n        ktx2File.delete();\n    }\n}\n/**\n * Parse the particular level image of a ktx2 file\n * @param ktx2File\n * @param levelIndex\n * @param options\n * @returns\n */\nfunction transcodeKTX2Image(ktx2File, levelIndex, options) {\n    const { alphaFlag, height, width } = ktx2File.getImageLevelInfo(levelIndex, 0, 0);\n    // Check options for output format etc\n    const { compressed, format, basisFormat } = getBasisOptions(options, alphaFlag);\n    const decodedSize = ktx2File.getImageTranscodedSizeInBytes(levelIndex, 0 /* layerIndex */, 0 /* faceIndex */, basisFormat);\n    const decodedData = new Uint8Array(decodedSize);\n    if (!ktx2File.transcodeImage(decodedData, levelIndex, 0 /* layerIndex */, 0 /* faceIndex */, basisFormat, 0, -1 /* channel0 */, -1 /* channel1 */)) {\n        throw new Error('Failed to transcode KTX2 image');\n    }\n    return {\n        // standard loaders.gl image category payload\n        width,\n        height,\n        data: decodedData,\n        compressed,\n        // Additional fields\n        levelSize: decodedSize,\n        hasAlpha: alphaFlag,\n        format\n    };\n}\n/**\n * Get BasisFormat by loader format option\n * @param options\n * @param hasAlpha\n * @returns BasisFormat data\n */\nfunction getBasisOptions(options, hasAlpha) {\n    let format = options && options.basis && options.basis.format;\n    if (format === 'auto') {\n        format = selectSupportedBasisFormat();\n    }\n    if (typeof format === 'object') {\n        format = hasAlpha ? format.alpha : format.noAlpha;\n    }\n    format = format.toLowerCase();\n    return OutputFormat[format];\n}\n/**\n * Select transcode format from the list of supported formats\n * @returns key for OutputFormat map\n */\nfunction selectSupportedBasisFormat() {\n    const supportedFormats = getSupportedGPUTextureFormats();\n    if (supportedFormats.has('astc')) {\n        return 'astc-4x4';\n    }\n    else if (supportedFormats.has('dxt')) {\n        return {\n            alpha: 'bc3',\n            noAlpha: 'bc1'\n        };\n    }\n    else if (supportedFormats.has('pvrtc')) {\n        return {\n            alpha: 'pvrtc1-4-rgba',\n            noAlpha: 'pvrtc1-4-rgb'\n        };\n    }\n    else if (supportedFormats.has('etc1')) {\n        return 'etc1';\n    }\n    else if (supportedFormats.has('etc2')) {\n        return 'etc2';\n    }\n    return 'rgb565';\n}\n\n// loaders.gl\n/**\n * Worker loader for Basis super compressed textures\n */\nconst BasisWorkerLoader = {\n    dataType: null,\n    batchType: null,\n    name: 'Basis',\n    id: 'basis',\n    module: 'textures',\n    version: VERSION$2,\n    worker: true,\n    extensions: ['basis', 'ktx2'],\n    mimeTypes: ['application/octet-stream', 'image/ktx2'],\n    tests: ['sB'],\n    binary: true,\n    options: {\n        basis: {\n            format: 'auto',\n            libraryPath: 'libs/',\n            containerFormat: 'auto',\n            module: 'transcoder'\n        }\n    }\n};\n/**\n * Loader for Basis super compressed textures\n */\nconst BasisLoader = {\n    ...BasisWorkerLoader,\n    parse: parseBasis\n};\n\n/** Binary GLTF is little endian. */\nconst LITTLE_ENDIAN = true;\n/** 'glTF' in Big-Endian ASCII */\nconst MAGIC_glTF = 0x676c5446;\nconst GLB_FILE_HEADER_SIZE = 12;\nconst GLB_CHUNK_HEADER_SIZE = 8;\nconst GLB_CHUNK_TYPE_JSON = 0x4e4f534a;\nconst GLB_CHUNK_TYPE_BIN = 0x004e4942;\nconst GLB_V1_CONTENT_FORMAT_JSON = 0x0;\n/** @deprecated - Backward compatibility for old xviz files */\nconst GLB_CHUNK_TYPE_JSON_XVIZ_DEPRECATED = 0;\n/** @deprecated - Backward compatibility for old xviz files */\nconst GLB_CHUNK_TYPE_BIX_XVIZ_DEPRECATED = 1;\nfunction getMagicString(dataView, byteOffset = 0) {\n    return `\\\n${String.fromCharCode(dataView.getUint8(byteOffset + 0))}\\\n${String.fromCharCode(dataView.getUint8(byteOffset + 1))}\\\n${String.fromCharCode(dataView.getUint8(byteOffset + 2))}\\\n${String.fromCharCode(dataView.getUint8(byteOffset + 3))}`;\n}\n/** Check if the contents of an array buffer contains GLB byte markers */\nfunction isGLB(arrayBuffer, byteOffset = 0, options = {}) {\n    const dataView = new DataView(arrayBuffer);\n    // Check that GLB Header starts with the magic number\n    const { magic = MAGIC_glTF } = options;\n    const magic1 = dataView.getUint32(byteOffset, false);\n    return magic1 === magic || magic1 === MAGIC_glTF;\n}\n/**\n * Synchronously parse a GLB\n * @param glb - Target, Output is stored there\n * @param arrayBuffer - Input data\n * @param byteOffset - Offset into arrayBuffer to start parsing from (for \"embedded\" GLBs, e.g. in 3D tiles)\n * @param options\n * @returns\n */\nfunction parseGLBSync(glb, arrayBuffer, byteOffset = 0, options = {}) {\n    // Check that GLB Header starts with the magic number\n    const dataView = new DataView(arrayBuffer);\n    // Compare format with GLBLoader documentation\n    const type = getMagicString(dataView, byteOffset + 0);\n    const version = dataView.getUint32(byteOffset + 4, LITTLE_ENDIAN); // Version 2 of binary glTF container format\n    const byteLength = dataView.getUint32(byteOffset + 8, LITTLE_ENDIAN); // Total byte length of binary file\n    Object.assign(glb, {\n        // Put less important stuff in a header, to avoid clutter\n        header: {\n            byteOffset, // Byte offset into the initial arrayBuffer\n            byteLength,\n            hasBinChunk: false\n        },\n        type,\n        version,\n        json: {},\n        binChunks: []\n    });\n    byteOffset += GLB_FILE_HEADER_SIZE;\n    switch (glb.version) {\n        case 1:\n            return parseGLBV1(glb, dataView, byteOffset);\n        case 2:\n            return parseGLBV2(glb, dataView, byteOffset, (options = {}));\n        default:\n            throw new Error(`Invalid GLB version ${glb.version}. Only supports version 1 and 2.`);\n    }\n}\n/**\n * Parse a V1 GLB\n * @param glb - target, output is stored in this object\n * @param dataView - Input, memory to be parsed\n * @param byteOffset - Offset of first byte of GLB data in the data view\n * @returns Number of bytes parsed (there could be additional non-GLB data after the GLB)\n */\nfunction parseGLBV1(glb, dataView, byteOffset) {\n    // Sanity: ensure file is big enough to hold at least the headers\n    assert$4(glb.header.byteLength > GLB_FILE_HEADER_SIZE + GLB_CHUNK_HEADER_SIZE);\n    // Explanation of GLB structure:\n    // https://cloud.githubusercontent.com/assets/3479527/22600725/36b87122-ea55-11e6-9d40-6fd42819fcab.png\n    const contentLength = dataView.getUint32(byteOffset + 0, LITTLE_ENDIAN); // Byte length of chunk\n    const contentFormat = dataView.getUint32(byteOffset + 4, LITTLE_ENDIAN); // Chunk format as uint32\n    byteOffset += GLB_CHUNK_HEADER_SIZE;\n    // GLB v1 only supports a single chunk type\n    assert$4(contentFormat === GLB_V1_CONTENT_FORMAT_JSON);\n    parseJSONChunk(glb, dataView, byteOffset, contentLength);\n    // No need to call the function padToBytes() from parseJSONChunk()\n    byteOffset += contentLength;\n    byteOffset += parseBINChunk(glb, dataView, byteOffset, glb.header.byteLength);\n    return byteOffset;\n}\n/**\n * Parse a V2 GLB\n * @param glb - target, output is stored in this object\n * @param dataView - Input, memory to be parsed\n * @param byteOffset - Offset of first byte of GLB data in the data view\n * @returns Number of bytes parsed (there could be additional non-GLB data after the GLB)\n */\nfunction parseGLBV2(glb, dataView, byteOffset, options) {\n    // Sanity: ensure file is big enough to hold at least the first chunk header\n    assert$4(glb.header.byteLength > GLB_FILE_HEADER_SIZE + GLB_CHUNK_HEADER_SIZE);\n    parseGLBChunksSync(glb, dataView, byteOffset, options);\n    return byteOffset + glb.header.byteLength;\n}\n/** Iterate over GLB chunks and parse them */\nfunction parseGLBChunksSync(glb, dataView, byteOffset, options) {\n    // Per spec we must iterate over chunks, ignoring all except JSON and BIN\n    // Iterate as long as there is space left for another chunk header\n    while (byteOffset + 8 <= glb.header.byteLength) {\n        const chunkLength = dataView.getUint32(byteOffset + 0, LITTLE_ENDIAN); // Byte length of chunk\n        const chunkFormat = dataView.getUint32(byteOffset + 4, LITTLE_ENDIAN); // Chunk format as uint32\n        byteOffset += GLB_CHUNK_HEADER_SIZE;\n        // Per spec we must iterate over chunks, ignoring all except JSON and BIN\n        switch (chunkFormat) {\n            case GLB_CHUNK_TYPE_JSON:\n                parseJSONChunk(glb, dataView, byteOffset, chunkLength);\n                break;\n            case GLB_CHUNK_TYPE_BIN:\n                parseBINChunk(glb, dataView, byteOffset, chunkLength);\n                break;\n            // Backward compatibility for very old xviz files\n            case GLB_CHUNK_TYPE_JSON_XVIZ_DEPRECATED:\n                if (!options.strict) {\n                    parseJSONChunk(glb, dataView, byteOffset, chunkLength);\n                }\n                break;\n            case GLB_CHUNK_TYPE_BIX_XVIZ_DEPRECATED:\n                if (!options.strict) {\n                    parseBINChunk(glb, dataView, byteOffset, chunkLength);\n                }\n                break;\n        }\n        byteOffset += padToNBytes(chunkLength, 4);\n    }\n    return byteOffset;\n}\n/* Parse a GLB JSON chunk */\nfunction parseJSONChunk(glb, dataView, byteOffset, chunkLength) {\n    // 1. Create a \"view\" of the binary encoded JSON data inside the GLB\n    const jsonChunk = new Uint8Array(dataView.buffer, byteOffset, chunkLength);\n    // 2. Decode the JSON binary array into clear text\n    const textDecoder = new TextDecoder('utf8');\n    const jsonText = textDecoder.decode(jsonChunk);\n    // 3. Parse the JSON text into a JavaScript data structure\n    glb.json = JSON.parse(jsonText);\n    return padToNBytes(chunkLength, 4);\n}\n/** Parse a GLB BIN chunk */\nfunction parseBINChunk(glb, dataView, byteOffset, chunkLength) {\n    // Note: BIN chunk can be optional\n    glb.header.hasBinChunk = true;\n    glb.binChunks.push({\n        byteOffset,\n        byteLength: chunkLength,\n        arrayBuffer: dataView.buffer\n        // TODO - copy, or create typed array view?\n    });\n    return padToNBytes(chunkLength, 4);\n}\n\n// Resolves a relative url against a baseUrl\n// If url is absolute, return it unchanged\nfunction resolveUrl(url, options) {\n    // TODO: Use better logic to handle all protocols plus not delay on data\n    const absolute = url.startsWith('data:') || url.startsWith('http:') || url.startsWith('https:');\n    if (absolute) {\n        return url;\n    }\n    const baseUrl = options.baseUri || options.uri;\n    if (!baseUrl) {\n        throw new Error(`'baseUri' must be provided to resolve relative url ${url}`);\n    }\n    return baseUrl.substr(0, baseUrl.lastIndexOf('/') + 1) + url;\n}\n\n// This file is part of meshoptimizer library and is distributed under the terms of MIT License.\n// Built with clang version 11.0.0 (https://github.com/llvm/llvm-project.git 0160ad802e899c2922bc9b29564080c22eb0908c)\n// Built from meshoptimizer 0.16\nconst wasm_base = 'B9h9z9tFBBBF8fL9gBB9gLaaaaaFa9gEaaaB9gFaFa9gEaaaFaEMcBFFFGGGEIIILF9wFFFLEFBFKNFaFCx/IFMO/LFVK9tv9t9vq95GBt9f9f939h9z9t9f9j9h9s9s9f9jW9vq9zBBp9tv9z9o9v9wW9f9kv9j9v9kv9WvqWv94h919m9mvqBF8Z9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv94h919m9mvqBGy9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv949TvZ91v9u9jvBEn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9P9jWBIi9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9R919hWBLn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9F949wBKI9z9iqlBOc+x8ycGBM/qQFTa8jUUUUBCU/EBlHL8kUUUUBC9+RKGXAGCFJAI9LQBCaRKAE2BBC+gF9HQBALAEAIJHOAGlAGTkUUUBRNCUoBAG9uC/wgBZHKCUGAKCUG9JyRVAECFJRICBRcGXEXAcAF9PQFAVAFAclAcAVJAF9JyRMGXGXAG9FQBAMCbJHKC9wZRSAKCIrCEJCGrRQANCUGJRfCBRbAIRTEXGXAOATlAQ9PQBCBRISEMATAQJRIGXAS9FQBCBRtCBREEXGXAOAIlCi9PQBCBRISLMANCU/CBJAEJRKGXGXGXGXGXATAECKrJ2BBAtCKZrCEZfIBFGEBMAKhB83EBAKCNJhB83EBSEMAKAI2BIAI2BBHmCKrHYAYCE6HYy86BBAKCFJAICIJAYJHY2BBAmCIrCEZHPAPCE6HPy86BBAKCGJAYAPJHY2BBAmCGrCEZHPAPCE6HPy86BBAKCEJAYAPJHY2BBAmCEZHmAmCE6Hmy86BBAKCIJAYAmJHY2BBAI2BFHmCKrHPAPCE6HPy86BBAKCLJAYAPJHY2BBAmCIrCEZHPAPCE6HPy86BBAKCKJAYAPJHY2BBAmCGrCEZHPAPCE6HPy86BBAKCOJAYAPJHY2BBAmCEZHmAmCE6Hmy86BBAKCNJAYAmJHY2BBAI2BGHmCKrHPAPCE6HPy86BBAKCVJAYAPJHY2BBAmCIrCEZHPAPCE6HPy86BBAKCcJAYAPJHY2BBAmCGrCEZHPAPCE6HPy86BBAKCMJAYAPJHY2BBAmCEZHmAmCE6Hmy86BBAKCSJAYAmJHm2BBAI2BEHICKrHYAYCE6HYy86BBAKCQJAmAYJHm2BBAICIrCEZHYAYCE6HYy86BBAKCfJAmAYJHm2BBAICGrCEZHYAYCE6HYy86BBAKCbJAmAYJHK2BBAICEZHIAICE6HIy86BBAKAIJRISGMAKAI2BNAI2BBHmCIrHYAYCb6HYy86BBAKCFJAICNJAYJHY2BBAmCbZHmAmCb6Hmy86BBAKCGJAYAmJHm2BBAI2BFHYCIrHPAPCb6HPy86BBAKCEJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCIJAmAYJHm2BBAI2BGHYCIrHPAPCb6HPy86BBAKCLJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCKJAmAYJHm2BBAI2BEHYCIrHPAPCb6HPy86BBAKCOJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCNJAmAYJHm2BBAI2BIHYCIrHPAPCb6HPy86BBAKCVJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCcJAmAYJHm2BBAI2BLHYCIrHPAPCb6HPy86BBAKCMJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCSJAmAYJHm2BBAI2BKHYCIrHPAPCb6HPy86BBAKCQJAmAPJHm2BBAYCbZHYAYCb6HYy86BBAKCfJAmAYJHm2BBAI2BOHICIrHYAYCb6HYy86BBAKCbJAmAYJHK2BBAICbZHIAICb6HIy86BBAKAIJRISFMAKAI8pBB83BBAKCNJAICNJ8pBB83BBAICTJRIMAtCGJRtAECTJHEAS9JQBMMGXAIQBCBRISEMGXAM9FQBANAbJ2BBRtCBRKAfREEXAEANCU/CBJAKJ2BBHTCFrCBATCFZl9zAtJHt86BBAEAGJREAKCFJHKAM9HQBMMAfCFJRfAIRTAbCFJHbAG9HQBMMABAcAG9sJANCUGJAMAG9sTkUUUBpANANCUGJAMCaJAG9sJAGTkUUUBpMAMCBAIyAcJRcAIQBMC9+RKSFMCBC99AOAIlAGCAAGCA9Ly6yRKMALCU/EBJ8kUUUUBAKM+OmFTa8jUUUUBCoFlHL8kUUUUBC9+RKGXAFCE9uHOCtJAI9LQBCaRKAE2BBHNC/wFZC/gF9HQBANCbZHVCF9LQBALCoBJCgFCUFT+JUUUBpALC84Jha83EBALC8wJha83EBALC8oJha83EBALCAJha83EBALCiJha83EBALCTJha83EBALha83ENALha83EBAEAIJC9wJRcAECFJHNAOJRMGXAF9FQBCQCbAVCF6yRSABRECBRVCBRQCBRfCBRICBRKEXGXAMAcuQBC9+RKSEMGXGXAN2BBHOC/vF9LQBALCoBJAOCIrCa9zAKJCbZCEWJHb8oGIRTAb8oGBRtGXAOCbZHbAS9PQBALAOCa9zAIJCbZCGWJ8oGBAVAbyROAb9FRbGXGXAGCG9HQBABAt87FBABCIJAO87FBABCGJAT87FBSFMAEAtjGBAECNJAOjGBAECIJATjGBMAVAbJRVALCoBJAKCEWJHmAOjGBAmATjGIALAICGWJAOjGBALCoBJAKCFJCbZHKCEWJHTAtjGBATAOjGIAIAbJRIAKCFJRKSGMGXGXAbCb6QBAQAbJAbC989zJCFJRQSFMAM1BBHbCgFZROGXGXAbCa9MQBAMCFJRMSFMAM1BFHbCgBZCOWAOCgBZqROGXAbCa9MQBAMCGJRMSFMAM1BGHbCgBZCfWAOqROGXAbCa9MQBAMCEJRMSFMAM1BEHbCgBZCdWAOqROGXAbCa9MQBAMCIJRMSFMAM2BIC8cWAOqROAMCLJRMMAOCFrCBAOCFZl9zAQJRQMGXGXAGCG9HQBABAt87FBABCIJAQ87FBABCGJAT87FBSFMAEAtjGBAECNJAQjGBAECIJATjGBMALCoBJAKCEWJHOAQjGBAOATjGIALAICGWJAQjGBALCoBJAKCFJCbZHKCEWJHOAtjGBAOAQjGIAICFJRIAKCFJRKSFMGXAOCDF9LQBALAIAcAOCbZJ2BBHbCIrHTlCbZCGWJ8oGBAVCFJHtATyROALAIAblCbZCGWJ8oGBAtAT9FHmJHtAbCbZHTyRbAT9FRTGXGXAGCG9HQBABAV87FBABCIJAb87FBABCGJAO87FBSFMAEAVjGBAECNJAbjGBAECIJAOjGBMALAICGWJAVjGBALCoBJAKCEWJHYAOjGBAYAVjGIALAICFJHICbZCGWJAOjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAIAmJCbZHICGWJAbjGBALCoBJAKCGJCbZHKCEWJHOAVjGBAOAbjGIAKCFJRKAIATJRIAtATJRVSFMAVCBAM2BBHYyHTAOC/+F6HPJROAYCbZRtGXGXAYCIrHmQBAOCFJRbSFMAORbALAIAmlCbZCGWJ8oGBROMGXGXAtQBAbCFJRVSFMAbRVALAIAYlCbZCGWJ8oGBRbMGXGXAP9FQBAMCFJRYSFMAM1BFHYCgFZRTGXGXAYCa9MQBAMCGJRYSFMAM1BGHYCgBZCOWATCgBZqRTGXAYCa9MQBAMCEJRYSFMAM1BEHYCgBZCfWATqRTGXAYCa9MQBAMCIJRYSFMAM1BIHYCgBZCdWATqRTGXAYCa9MQBAMCLJRYSFMAMCKJRYAM2BLC8cWATqRTMATCFrCBATCFZl9zAQJHQRTMGXGXAmCb6QBAYRPSFMAY1BBHMCgFZROGXGXAMCa9MQBAYCFJRPSFMAY1BFHMCgBZCOWAOCgBZqROGXAMCa9MQBAYCGJRPSFMAY1BGHMCgBZCfWAOqROGXAMCa9MQBAYCEJRPSFMAY1BEHMCgBZCdWAOqROGXAMCa9MQBAYCIJRPSFMAYCLJRPAY2BIC8cWAOqROMAOCFrCBAOCFZl9zAQJHQROMGXGXAtCb6QBAPRMSFMAP1BBHMCgFZRbGXGXAMCa9MQBAPCFJRMSFMAP1BFHMCgBZCOWAbCgBZqRbGXAMCa9MQBAPCGJRMSFMAP1BGHMCgBZCfWAbqRbGXAMCa9MQBAPCEJRMSFMAP1BEHMCgBZCdWAbqRbGXAMCa9MQBAPCIJRMSFMAPCLJRMAP2BIC8cWAbqRbMAbCFrCBAbCFZl9zAQJHQRbMGXGXAGCG9HQBABAT87FBABCIJAb87FBABCGJAO87FBSFMAEATjGBAECNJAbjGBAECIJAOjGBMALCoBJAKCEWJHYAOjGBAYATjGIALAICGWJATjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAICFJHICbZCGWJAOjGBALCoBJAKCGJCbZCEWJHOATjGBAOAbjGIALAIAm9FAmCb6qJHICbZCGWJAbjGBAIAt9FAtCb6qJRIAKCEJRKMANCFJRNABCKJRBAECSJREAKCbZRKAICbZRIAfCEJHfAF9JQBMMCBC99AMAc6yRKMALCoFJ8kUUUUBAKM/tIFGa8jUUUUBCTlRLC9+RKGXAFCLJAI9LQBCaRKAE2BBC/+FZC/QF9HQBALhB83ENAECFJRKAEAIJC98JREGXAF9FQBGXAGCG6QBEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMALCNJAICFZCGWqHGAICGrCBAICFrCFZl9zAG8oGBJHIjGBABAIjGBABCIJRBAFCaJHFQBSGMMEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMABAICGrCBAICFrCFZl9zALCNJAICFZCGWqHI8oGBJHG87FBAIAGjGBABCGJRBAFCaJHFQBMMCBC99AKAE6yRKMAKM+lLKFaF99GaG99FaG99GXGXAGCI9HQBAF9FQFEXGXGX9DBBB8/9DBBB+/ABCGJHG1BB+yAB1BBHE+yHI+L+TABCFJHL1BBHK+yHO+L+THN9DBBBB9gHVyAN9DBB/+hANAN+U9DBBBBANAVyHcAc+MHMAECa3yAI+SHIAI+UAcAMAKCa3yAO+SHcAc+U+S+S+R+VHO+U+SHN+L9DBBB9P9d9FQBAN+oRESFMCUUUU94REMAGAE86BBGXGX9DBBB8/9DBBB+/Ac9DBBBB9gyAcAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMALAG86BBGXGX9DBBB8/9DBBB+/AI9DBBBB9gyAIAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMABAG86BBABCIJRBAFCaJHFQBSGMMAF9FQBEXGXGX9DBBB8/9DBBB+/ABCIJHG8uFB+yAB8uFBHE+yHI+L+TABCGJHL8uFBHK+yHO+L+THN9DBBBB9gHVyAN9DB/+g6ANAN+U9DBBBBANAVyHcAc+MHMAECa3yAI+SHIAI+UAcAMAKCa3yAO+SHcAc+U+S+S+R+VHO+U+SHN+L9DBBB9P9d9FQBAN+oRESFMCUUUU94REMAGAE87FBGXGX9DBBB8/9DBBB+/Ac9DBBBB9gyAcAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMALAG87FBGXGX9DBBB8/9DBBB+/AI9DBBBB9gyAIAO+U+SHN+L9DBBB9P9d9FQBAN+oRGSFMCUUUU94RGMABAG87FBABCNJRBAFCaJHFQBMMM/SEIEaE99EaF99GXAF9FQBCBREABRIEXGXGX9D/zI818/AICKJ8uFBHLCEq+y+VHKAI8uFB+y+UHO9DB/+g6+U9DBBB8/9DBBB+/AO9DBBBB9gy+SHN+L9DBBB9P9d9FQBAN+oRVSFMCUUUU94RVMAICIJ8uFBRcAICGJ8uFBRMABALCFJCEZAEqCFWJAV87FBGXGXAKAM+y+UHN9DB/+g6+U9DBBB8/9DBBB+/AN9DBBBB9gy+SHS+L9DBBB9P9d9FQBAS+oRMSFMCUUUU94RMMABALCGJCEZAEqCFWJAM87FBGXGXAKAc+y+UHK9DB/+g6+U9DBBB8/9DBBB+/AK9DBBBB9gy+SHS+L9DBBB9P9d9FQBAS+oRcSFMCUUUU94RcMABALCaJCEZAEqCFWJAc87FBGXGX9DBBU8/AOAO+U+TANAN+U+TAKAK+U+THO9DBBBBAO9DBBBB9gy+R9DB/+g6+U9DBBB8/+SHO+L9DBBB9P9d9FQBAO+oRcSFMCUUUU94RcMABALCEZAEqCFWJAc87FBAICNJRIAECIJREAFCaJHFQBMMM9JBGXAGCGrAF9sHF9FQBEXABAB8oGBHGCNWCN91+yAGCi91CnWCUUU/8EJ+++U84GBABCIJRBAFCaJHFQBMMM9TFEaCBCB8oGUkUUBHFABCEJC98ZJHBjGUkUUBGXGXAB8/BCTWHGuQBCaREABAGlCggEJCTrXBCa6QFMAFREMAEM/lFFFaGXGXAFABqCEZ9FQBABRESFMGXGXAGCT9PQBABRESFMABREEXAEAF8oGBjGBAECIJAFCIJ8oGBjGBAECNJAFCNJ8oGBjGBAECSJAFCSJ8oGBjGBAECTJREAFCTJRFAGC9wJHGCb9LQBMMAGCI9JQBEXAEAF8oGBjGBAFCIJRFAECIJREAGC98JHGCE9LQBMMGXAG9FQBEXAEAF2BB86BBAECFJREAFCFJRFAGCaJHGQBMMABMoFFGaGXGXABCEZ9FQBABRESFMAFCgFZC+BwsN9sRIGXGXAGCT9PQBABRESFMABREEXAEAIjGBAECSJAIjGBAECNJAIjGBAECIJAIjGBAECTJREAGC9wJHGCb9LQBMMAGCI9JQBEXAEAIjGBAECIJREAGC98JHGCE9LQBMMGXAG9FQBEXAEAF86BBAECFJREAGCaJHGQBMMABMMMFBCUNMIT9kBB';\nconst wasm_simd = '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';\n// Uses bulk-memory and simd extensions\nconst detector = new Uint8Array([\n    0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 3, 2, 0, 0, 5, 3, 1, 0, 1, 12, 1, 0, 10, 22, 2,\n    12, 0, 65, 0, 65, 0, 65, 0, 252, 10, 0, 0, 11, 7, 0, 65, 0, 253, 15, 26, 11\n]);\n// Used to unpack wasm\nconst wasmpack = new Uint8Array([\n    32, 0, 65, 253, 3, 1, 2, 34, 4, 106, 6, 5, 11, 8, 7, 20, 13, 33, 12, 16, 128, 9, 116, 64, 19, 113,\n    127, 15, 10, 21, 22, 14, 255, 66, 24, 54, 136, 107, 18, 23, 192, 26, 114, 118, 132, 17, 77, 101,\n    130, 144, 27, 87, 131, 44, 45, 74, 156, 154, 70, 167\n]);\nconst FILTERS = {\n    // legacy index-based enums for glTF\n    0: '',\n    1: 'meshopt_decodeFilterOct',\n    2: 'meshopt_decodeFilterQuat',\n    3: 'meshopt_decodeFilterExp',\n    // string-based enums for glTF\n    NONE: '',\n    OCTAHEDRAL: 'meshopt_decodeFilterOct',\n    QUATERNION: 'meshopt_decodeFilterQuat',\n    EXPONENTIAL: 'meshopt_decodeFilterExp'\n};\nconst DECODERS = {\n    // legacy index-based enums for glTF\n    0: 'meshopt_decodeVertexBuffer',\n    1: 'meshopt_decodeIndexBuffer',\n    2: 'meshopt_decodeIndexSequence',\n    // string-based enums for glTF\n    ATTRIBUTES: 'meshopt_decodeVertexBuffer',\n    TRIANGLES: 'meshopt_decodeIndexBuffer',\n    INDICES: 'meshopt_decodeIndexSequence'\n};\n// eslint-disable-next-line max-params\nasync function meshoptDecodeGltfBuffer(target, count, size, source, mode, filter = 'NONE') {\n    const instance = await loadWasmInstance();\n    decode$8(instance, instance.exports[DECODERS[mode]], target, count, size, source, instance.exports[FILTERS[filter || 'NONE']]);\n}\nlet wasmPromise;\nasync function loadWasmInstance() {\n    // eslint-disable-next-line\n    if (!wasmPromise) {\n        wasmPromise = loadWasmModule();\n    }\n    return wasmPromise;\n}\nasync function loadWasmModule() {\n    let wasm = wasm_base;\n    if (WebAssembly.validate(detector)) {\n        wasm = wasm_simd;\n        // eslint-disable-next-line no-console\n        console.log('Warning: meshopt_decoder is using experimental SIMD support');\n    }\n    const result = await WebAssembly.instantiate(unpack(wasm), {});\n    await result.instance.exports.__wasm_call_ctors();\n    return result.instance;\n}\nfunction unpack(data) {\n    const result = new Uint8Array(data.length);\n    for (let i = 0; i < data.length; ++i) {\n        const ch = data.charCodeAt(i);\n        result[i] = ch > 96 ? ch - 71 : ch > 64 ? ch - 65 : ch > 47 ? ch + 4 : ch > 46 ? 63 : 62;\n    }\n    let write = 0;\n    for (let i = 0; i < data.length; ++i) {\n        result[write++] = result[i] < 60 ? wasmpack[result[i]] : (result[i] - 60) * 64 + result[++i];\n    }\n    return result.buffer.slice(0, write);\n}\n// eslint-disable-next-line max-params\nfunction decode$8(instance, fun, target, count, size, source, filter) {\n    const sbrk = instance.exports.sbrk;\n    const count4 = (count + 3) & ~3; // pad for SIMD filter\n    const tp = sbrk(count4 * size);\n    const sp = sbrk(source.length);\n    const heap = new Uint8Array(instance.exports.memory.buffer);\n    heap.set(source, sp);\n    const res = fun(tp, count, size, sp, source.length);\n    if (res === 0 && filter) {\n        filter(tp, count4, size);\n    }\n    target.set(heap.subarray(tp, tp + count * size));\n    sbrk(tp - sbrk(0));\n    if (res !== 0) {\n        throw new Error(`Malformed buffer data: ${res}`);\n    }\n}\n\n/** Extension name */\nconst EXT_MESHOPT_COMPRESSION = 'EXT_meshopt_compression';\nconst name$7 = EXT_MESHOPT_COMPRESSION;\nasync function decode$7(gltfData, options) {\n    const scenegraph = new GLTFScenegraph(gltfData);\n    if (!options?.gltf?.decompressMeshes || !options.gltf?.loadBuffers) {\n        return;\n    }\n    const promises = [];\n    for (const bufferViewIndex of gltfData.json.bufferViews || []) {\n        promises.push(decodeMeshoptBufferView(scenegraph, bufferViewIndex));\n    }\n    // Decompress meshes in parallel\n    await Promise.all(promises);\n    // We have now decompressed all primitives, so remove the top-level extension\n    scenegraph.removeExtension(EXT_MESHOPT_COMPRESSION);\n}\n/** Decode one meshopt buffer view */\nasync function decodeMeshoptBufferView(scenegraph, bufferView) {\n    const meshoptExtension = scenegraph.getObjectExtension(bufferView, EXT_MESHOPT_COMPRESSION);\n    if (meshoptExtension) {\n        const { byteOffset = 0, byteLength = 0, byteStride, count, mode, filter = 'NONE', buffer: bufferIndex } = meshoptExtension;\n        const buffer = scenegraph.gltf.buffers[bufferIndex];\n        const source = new Uint8Array(buffer.arrayBuffer, buffer.byteOffset + byteOffset, byteLength);\n        const result = new Uint8Array(scenegraph.gltf.buffers[bufferView.buffer].arrayBuffer, bufferView.byteOffset, bufferView.byteLength);\n        await meshoptDecodeGltfBuffer(result, count, byteStride, source, mode, filter);\n        scenegraph.removeObjectExtension(bufferView, EXT_MESHOPT_COMPRESSION);\n    }\n}\n\nvar EXT_meshopt_compression = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$7,\n    decode: decode$7\n});\n\n// GLTF EXTENSION: EXT_TEXTURE_WEBP\nconst EXT_TEXTURE_WEBP = 'EXT_texture_webp';\n/** Extension name */\nconst name$6 = EXT_TEXTURE_WEBP;\n/**\n * Replaces a texture source reference with the extension texture\n * Done in preprocess() to prevent load of default image\n */\nfunction preprocess$3(gltfData, options) {\n    const scenegraph = new GLTFScenegraph(gltfData);\n    if (!isImageFormatSupported('image/webp')) {\n        if (scenegraph.getRequiredExtensions().includes(EXT_TEXTURE_WEBP)) {\n            throw new Error(`gltf: Required extension ${EXT_TEXTURE_WEBP} not supported by browser`);\n        }\n        return;\n    }\n    const { json } = scenegraph;\n    for (const texture of json.textures || []) {\n        const extension = scenegraph.getObjectExtension(texture, EXT_TEXTURE_WEBP);\n        if (extension) {\n            // TODO - if multiple texture extensions are present which one wins?\n            texture.source = extension.source;\n        }\n        scenegraph.removeObjectExtension(texture, EXT_TEXTURE_WEBP);\n    }\n    // Remove the top-level extension\n    scenegraph.removeExtension(EXT_TEXTURE_WEBP);\n}\n\nvar EXT_texture_webp = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$6,\n    preprocess: preprocess$3\n});\n\n// GLTF EXTENSION: KHR_texture_basisu\nconst KHR_TEXTURE_BASISU = 'KHR_texture_basisu';\n/** Extension name */\nconst name$5 = KHR_TEXTURE_BASISU;\n/**\n * Replaces a texture source reference with the extension texture\n * Done in preprocess() to prevent load of default image\n */\nfunction preprocess$2(gltfData, options) {\n    const scene = new GLTFScenegraph(gltfData);\n    const { json } = scene;\n    for (const texture of json.textures || []) {\n        const extension = scene.getObjectExtension(texture, KHR_TEXTURE_BASISU);\n        if (extension) {\n            // TODO - if multiple texture extensions are present which one wins?\n            texture.source = extension.source;\n            scene.removeObjectExtension(texture, KHR_TEXTURE_BASISU);\n        }\n    }\n    // Remove the top-level extension\n    scene.removeExtension(KHR_TEXTURE_BASISU);\n}\n\nvar KHR_texture_basisu = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$5,\n    preprocess: preprocess$2\n});\n\n// Version constant cannot be imported, it needs to correspond to the build version of **this** module.\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION$1 = \"4.3.3\" ;\n\n// loaders.gl\n/**\n * Worker loader for Draco3D compressed geometries\n */\nconst DracoLoader$1 = {\n    dataType: null,\n    batchType: null,\n    name: 'Draco',\n    id: 'draco',\n    module: 'draco',\n    // shapes: ['mesh'],\n    version: VERSION$1,\n    worker: true,\n    extensions: ['drc'],\n    mimeTypes: ['application/octet-stream'],\n    binary: true,\n    tests: ['DRACO'],\n    options: {\n        draco: {\n            decoderType: typeof WebAssembly === 'object' ? 'wasm' : 'js', // 'js' for IE11\n            libraryPath: 'libs/',\n            extraAttributes: {},\n            attributeNameEntry: undefined\n        }\n    }\n};\n\n/** Extract an arrow-like schema from a Draco mesh */\nfunction getDracoSchema(attributes, loaderData, indices) {\n    const metadata = makeMetadata(loaderData.metadata);\n    const fields = [];\n    const namedLoaderDataAttributes = transformAttributesLoaderData(loaderData.attributes);\n    for (const attributeName in attributes) {\n        const attribute = attributes[attributeName];\n        const field = getArrowFieldFromAttribute(attributeName, attribute, namedLoaderDataAttributes[attributeName]);\n        fields.push(field);\n    }\n    if (indices) {\n        const indicesField = getArrowFieldFromAttribute('indices', indices);\n        fields.push(indicesField);\n    }\n    return { fields, metadata };\n}\nfunction transformAttributesLoaderData(loaderData) {\n    const result = {};\n    for (const key in loaderData) {\n        const dracoAttribute = loaderData[key];\n        result[dracoAttribute.name || 'undefined'] = dracoAttribute;\n    }\n    return result;\n}\nfunction getArrowFieldFromAttribute(attributeName, attribute, loaderData) {\n    const metadataMap = loaderData ? makeMetadata(loaderData.metadata) : undefined;\n    const field = deduceMeshField(attributeName, attribute, metadataMap);\n    return field;\n}\nfunction makeMetadata(metadata) {\n    const serializedMetadata = {};\n    for (const key in metadata) {\n        serializedMetadata[`${key}.string`] = JSON.stringify(metadata[key]);\n    }\n    return serializedMetadata;\n}\n\n/* eslint-disable camelcase */\n// Native Draco attribute names to GLTF attribute names.\nconst DRACO_TO_GLTF_ATTRIBUTE_NAME_MAP = {\n    POSITION: 'POSITION',\n    NORMAL: 'NORMAL',\n    COLOR: 'COLOR_0',\n    TEX_COORD: 'TEXCOORD_0'\n};\nconst DRACO_DATA_TYPE_TO_TYPED_ARRAY_MAP = {\n    1: Int8Array,\n    2: Uint8Array,\n    3: Int16Array,\n    4: Uint16Array,\n    5: Int32Array,\n    6: Uint32Array,\n    // 7: BigInt64Array,\n    // 8: BigUint64Array,\n    9: Float32Array\n    // 10: Float64Array\n    // 11: BOOL - What array type do we use for this?\n};\nconst INDEX_ITEM_SIZE = 4;\nclass DracoParser {\n    draco;\n    decoder;\n    metadataQuerier;\n    // draco - the draco decoder, either import `draco3d` or load dynamically\n    constructor(draco) {\n        this.draco = draco;\n        this.decoder = new this.draco.Decoder();\n        this.metadataQuerier = new this.draco.MetadataQuerier();\n    }\n    /**\n     * Destroy draco resources\n     */\n    destroy() {\n        this.draco.destroy(this.decoder);\n        this.draco.destroy(this.metadataQuerier);\n    }\n    /**\n     * NOTE: caller must call `destroyGeometry` on the return value after using it\n     * @param arrayBuffer\n     * @param options\n     */\n    parseSync(arrayBuffer, options = {}) {\n        const buffer = new this.draco.DecoderBuffer();\n        buffer.Init(new Int8Array(arrayBuffer), arrayBuffer.byteLength);\n        this._disableAttributeTransforms(options);\n        const geometry_type = this.decoder.GetEncodedGeometryType(buffer);\n        const dracoGeometry = geometry_type === this.draco.TRIANGULAR_MESH\n            ? new this.draco.Mesh()\n            : new this.draco.PointCloud();\n        try {\n            let dracoStatus;\n            switch (geometry_type) {\n                case this.draco.TRIANGULAR_MESH:\n                    dracoStatus = this.decoder.DecodeBufferToMesh(buffer, dracoGeometry);\n                    break;\n                case this.draco.POINT_CLOUD:\n                    dracoStatus = this.decoder.DecodeBufferToPointCloud(buffer, dracoGeometry);\n                    break;\n                default:\n                    throw new Error('DRACO: Unknown geometry type.');\n            }\n            if (!dracoStatus.ok() || !dracoGeometry.ptr) {\n                const message = `DRACO decompression failed: ${dracoStatus.error_msg()}`;\n                // console.error(message);\n                throw new Error(message);\n            }\n            const loaderData = this._getDracoLoaderData(dracoGeometry, geometry_type, options);\n            const geometry = this._getMeshData(dracoGeometry, loaderData, options);\n            const boundingBox = getMeshBoundingBox(geometry.attributes);\n            const schema = getDracoSchema(geometry.attributes, loaderData, geometry.indices);\n            const data = {\n                loader: 'draco',\n                loaderData,\n                header: {\n                    vertexCount: dracoGeometry.num_points(),\n                    boundingBox\n                },\n                ...geometry,\n                schema\n            };\n            return data;\n        }\n        finally {\n            this.draco.destroy(buffer);\n            if (dracoGeometry) {\n                this.draco.destroy(dracoGeometry);\n            }\n        }\n    }\n    // Draco specific \"loader data\"\n    /**\n     * Extract\n     * @param dracoGeometry\n     * @param geometry_type\n     * @param options\n     * @returns\n     */\n    _getDracoLoaderData(dracoGeometry, geometry_type, options) {\n        const metadata = this._getTopLevelMetadata(dracoGeometry);\n        const attributes = this._getDracoAttributes(dracoGeometry, options);\n        return {\n            geometry_type,\n            num_attributes: dracoGeometry.num_attributes(),\n            num_points: dracoGeometry.num_points(),\n            num_faces: dracoGeometry instanceof this.draco.Mesh ? dracoGeometry.num_faces() : 0,\n            metadata,\n            attributes\n        };\n    }\n    /**\n     * Extract all draco provided information and metadata for each attribute\n     * @param dracoGeometry\n     * @param options\n     * @returns\n     */\n    _getDracoAttributes(dracoGeometry, options) {\n        const dracoAttributes = {};\n        for (let attributeId = 0; attributeId < dracoGeometry.num_attributes(); attributeId++) {\n            // Note: Draco docs do not seem clear on `GetAttribute` ids just being a zero-based index,\n            // but it does seems to work this way\n            const dracoAttribute = this.decoder.GetAttribute(dracoGeometry, attributeId);\n            const metadata = this._getAttributeMetadata(dracoGeometry, attributeId);\n            dracoAttributes[dracoAttribute.unique_id()] = {\n                unique_id: dracoAttribute.unique_id(),\n                attribute_type: dracoAttribute.attribute_type(),\n                data_type: dracoAttribute.data_type(),\n                num_components: dracoAttribute.num_components(),\n                byte_offset: dracoAttribute.byte_offset(),\n                byte_stride: dracoAttribute.byte_stride(),\n                normalized: dracoAttribute.normalized(),\n                attribute_index: attributeId,\n                metadata\n            };\n            // Add transformation parameters for any attributes app wants untransformed\n            const quantization = this._getQuantizationTransform(dracoAttribute, options);\n            if (quantization) {\n                dracoAttributes[dracoAttribute.unique_id()].quantization_transform = quantization;\n            }\n            const octahedron = this._getOctahedronTransform(dracoAttribute, options);\n            if (octahedron) {\n                dracoAttributes[dracoAttribute.unique_id()].octahedron_transform = octahedron;\n            }\n        }\n        return dracoAttributes;\n    }\n    /**\n     * Get standard loaders.gl mesh category data\n     * Extracts the geometry from draco\n     * @param dracoGeometry\n     * @param options\n     */\n    _getMeshData(dracoGeometry, loaderData, options) {\n        const attributes = this._getMeshAttributes(loaderData, dracoGeometry, options);\n        const positionAttribute = attributes.POSITION;\n        if (!positionAttribute) {\n            throw new Error('DRACO: No position attribute found.');\n        }\n        // For meshes, we need indices to define the faces.\n        if (dracoGeometry instanceof this.draco.Mesh) {\n            switch (options.topology) {\n                case 'triangle-strip':\n                    return {\n                        topology: 'triangle-strip',\n                        mode: 4, // GL.TRIANGLES\n                        attributes,\n                        indices: {\n                            value: this._getTriangleStripIndices(dracoGeometry),\n                            size: 1\n                        }\n                    };\n                case 'triangle-list':\n                default:\n                    return {\n                        topology: 'triangle-list',\n                        mode: 5, // GL.TRIANGLE_STRIP\n                        attributes,\n                        indices: {\n                            value: this._getTriangleListIndices(dracoGeometry),\n                            size: 1\n                        }\n                    };\n            }\n        }\n        // PointCloud - must come last as Mesh inherits from PointCloud\n        return {\n            topology: 'point-list',\n            mode: 0, // GL.POINTS\n            attributes\n        };\n    }\n    _getMeshAttributes(loaderData, dracoGeometry, options) {\n        const attributes = {};\n        for (const loaderAttribute of Object.values(loaderData.attributes)) {\n            const attributeName = this._deduceAttributeName(loaderAttribute, options);\n            loaderAttribute.name = attributeName;\n            const values = this._getAttributeValues(dracoGeometry, loaderAttribute);\n            if (values) {\n                const { value, size } = values;\n                attributes[attributeName] = {\n                    value,\n                    size,\n                    byteOffset: loaderAttribute.byte_offset,\n                    byteStride: loaderAttribute.byte_stride,\n                    normalized: loaderAttribute.normalized\n                };\n            }\n        }\n        return attributes;\n    }\n    // MESH INDICES EXTRACTION\n    /**\n     * For meshes, we need indices to define the faces.\n     * @param dracoGeometry\n     */\n    _getTriangleListIndices(dracoGeometry) {\n        // Example on how to retrieve mesh and attributes.\n        const numFaces = dracoGeometry.num_faces();\n        const numIndices = numFaces * 3;\n        const byteLength = numIndices * INDEX_ITEM_SIZE;\n        const ptr = this.draco._malloc(byteLength);\n        try {\n            this.decoder.GetTrianglesUInt32Array(dracoGeometry, byteLength, ptr);\n            return new Uint32Array(this.draco.HEAPF32.buffer, ptr, numIndices).slice();\n        }\n        finally {\n            this.draco._free(ptr);\n        }\n    }\n    /**\n     * For meshes, we need indices to define the faces.\n     * @param dracoGeometry\n     */\n    _getTriangleStripIndices(dracoGeometry) {\n        const dracoArray = new this.draco.DracoInt32Array();\n        try {\n            /* const numStrips = */ this.decoder.GetTriangleStripsFromMesh(dracoGeometry, dracoArray);\n            return getUint32Array(dracoArray);\n        }\n        finally {\n            this.draco.destroy(dracoArray);\n        }\n    }\n    /**\n     *\n     * @param dracoGeometry\n     * @param dracoAttribute\n     * @param attributeName\n     */\n    _getAttributeValues(dracoGeometry, attribute) {\n        const TypedArrayCtor = DRACO_DATA_TYPE_TO_TYPED_ARRAY_MAP[attribute.data_type];\n        if (!TypedArrayCtor) {\n            // eslint-disable-next-line no-console\n            console.warn(`DRACO: Unsupported attribute type ${attribute.data_type}`);\n            return null;\n        }\n        const numComponents = attribute.num_components;\n        const numPoints = dracoGeometry.num_points();\n        const numValues = numPoints * numComponents;\n        const byteLength = numValues * TypedArrayCtor.BYTES_PER_ELEMENT;\n        const dataType = getDracoDataType(this.draco, TypedArrayCtor);\n        let value;\n        const ptr = this.draco._malloc(byteLength);\n        try {\n            const dracoAttribute = this.decoder.GetAttribute(dracoGeometry, attribute.attribute_index);\n            this.decoder.GetAttributeDataArrayForAllPoints(dracoGeometry, dracoAttribute, dataType, byteLength, ptr);\n            value = new TypedArrayCtor(this.draco.HEAPF32.buffer, ptr, numValues).slice();\n        }\n        finally {\n            this.draco._free(ptr);\n        }\n        return { value, size: numComponents };\n    }\n    // Attribute names\n    /**\n     * DRACO does not store attribute names - We need to deduce an attribute name\n     * for each attribute\n    _getAttributeNames(\n      dracoGeometry: Mesh | PointCloud,\n      options: DracoParseOptions\n    ): {[unique_id: number]: string} {\n      const attributeNames: {[unique_id: number]: string} = {};\n      for (let attributeId = 0; attributeId < dracoGeometry.num_attributes(); attributeId++) {\n        const dracoAttribute = this.decoder.GetAttribute(dracoGeometry, attributeId);\n        const attributeName = this._deduceAttributeName(dracoAttribute, options);\n        attributeNames[attributeName] = attributeName;\n      }\n      return attributeNames;\n    }\n     */\n    /**\n     * Deduce an attribute name.\n     * @note DRACO does not save attribute names, just general type (POSITION, COLOR)\n     * to help optimize compression. We generate GLTF compatible names for the Draco-recognized\n     * types\n     * @param attributeData\n     */\n    _deduceAttributeName(attribute, options) {\n        // Deduce name based on application provided map\n        const uniqueId = attribute.unique_id;\n        for (const [attributeName, attributeUniqueId] of Object.entries(options.extraAttributes || {})) {\n            if (attributeUniqueId === uniqueId) {\n                return attributeName;\n            }\n        }\n        // Deduce name based on attribute type\n        const thisAttributeType = attribute.attribute_type;\n        for (const dracoAttributeConstant in DRACO_TO_GLTF_ATTRIBUTE_NAME_MAP) {\n            const attributeType = this.draco[dracoAttributeConstant];\n            if (attributeType === thisAttributeType) {\n                // TODO - Return unique names if there multiple attributes per type\n                // (e.g. multiple TEX_COORDS or COLORS)\n                return DRACO_TO_GLTF_ATTRIBUTE_NAME_MAP[dracoAttributeConstant];\n            }\n        }\n        // Look up in metadata\n        // TODO - shouldn't this have priority?\n        const entryName = options.attributeNameEntry || 'name';\n        if (attribute.metadata[entryName]) {\n            return attribute.metadata[entryName].string;\n        }\n        // Attribute of \"GENERIC\" type, we need to assign some name\n        return `CUSTOM_ATTRIBUTE_${uniqueId}`;\n    }\n    // METADATA EXTRACTION\n    /** Get top level metadata */\n    _getTopLevelMetadata(dracoGeometry) {\n        const dracoMetadata = this.decoder.GetMetadata(dracoGeometry);\n        return this._getDracoMetadata(dracoMetadata);\n    }\n    /** Get per attribute metadata */\n    _getAttributeMetadata(dracoGeometry, attributeId) {\n        const dracoMetadata = this.decoder.GetAttributeMetadata(dracoGeometry, attributeId);\n        return this._getDracoMetadata(dracoMetadata);\n    }\n    /**\n     * Extract metadata field values\n     * @param dracoMetadata\n     * @returns\n     */\n    _getDracoMetadata(dracoMetadata) {\n        // The not so wonderful world of undocumented Draco APIs :(\n        if (!dracoMetadata || !dracoMetadata.ptr) {\n            return {};\n        }\n        const result = {};\n        const numEntries = this.metadataQuerier.NumEntries(dracoMetadata);\n        for (let entryIndex = 0; entryIndex < numEntries; entryIndex++) {\n            const entryName = this.metadataQuerier.GetEntryName(dracoMetadata, entryIndex);\n            result[entryName] = this._getDracoMetadataField(dracoMetadata, entryName);\n        }\n        return result;\n    }\n    /**\n     * Extracts possible values for one metadata entry by name\n     * @param dracoMetadata\n     * @param entryName\n     */\n    _getDracoMetadataField(dracoMetadata, entryName) {\n        const dracoArray = new this.draco.DracoInt32Array();\n        try {\n            // Draco metadata fields can hold int32 arrays\n            this.metadataQuerier.GetIntEntryArray(dracoMetadata, entryName, dracoArray);\n            const intArray = getInt32Array(dracoArray);\n            return {\n                int: this.metadataQuerier.GetIntEntry(dracoMetadata, entryName),\n                string: this.metadataQuerier.GetStringEntry(dracoMetadata, entryName),\n                double: this.metadataQuerier.GetDoubleEntry(dracoMetadata, entryName),\n                intArray\n            };\n        }\n        finally {\n            this.draco.destroy(dracoArray);\n        }\n    }\n    // QUANTIZED ATTRIBUTE SUPPORT (NO DECOMPRESSION)\n    /** Skip transforms for specific attribute types */\n    _disableAttributeTransforms(options) {\n        const { quantizedAttributes = [], octahedronAttributes = [] } = options;\n        const skipAttributes = [...quantizedAttributes, ...octahedronAttributes];\n        for (const dracoAttributeName of skipAttributes) {\n            this.decoder.SkipAttributeTransform(this.draco[dracoAttributeName]);\n        }\n    }\n    /**\n     * Extract (and apply?) Position Transform\n     * @todo not used\n     */\n    _getQuantizationTransform(dracoAttribute, options) {\n        const { quantizedAttributes = [] } = options;\n        const attribute_type = dracoAttribute.attribute_type();\n        const skip = quantizedAttributes.map((type) => this.decoder[type]).includes(attribute_type);\n        if (skip) {\n            const transform = new this.draco.AttributeQuantizationTransform();\n            try {\n                if (transform.InitFromAttribute(dracoAttribute)) {\n                    return {\n                        quantization_bits: transform.quantization_bits(),\n                        range: transform.range(),\n                        min_values: new Float32Array([1, 2, 3]).map((i) => transform.min_value(i))\n                    };\n                }\n            }\n            finally {\n                this.draco.destroy(transform);\n            }\n        }\n        return null;\n    }\n    _getOctahedronTransform(dracoAttribute, options) {\n        const { octahedronAttributes = [] } = options;\n        const attribute_type = dracoAttribute.attribute_type();\n        const octahedron = octahedronAttributes\n            .map((type) => this.decoder[type])\n            .includes(attribute_type);\n        if (octahedron) {\n            const transform = new this.draco.AttributeQuantizationTransform();\n            try {\n                if (transform.InitFromAttribute(dracoAttribute)) {\n                    return {\n                        quantization_bits: transform.quantization_bits()\n                    };\n                }\n            }\n            finally {\n                this.draco.destroy(transform);\n            }\n        }\n        return null;\n    }\n}\n/**\n * Get draco specific data type by TypedArray constructor type\n * @param attributeType\n * @returns draco specific data type\n */\nfunction getDracoDataType(draco, attributeType) {\n    switch (attributeType) {\n        case Float32Array:\n            return draco.DT_FLOAT32;\n        case Int8Array:\n            return draco.DT_INT8;\n        case Int16Array:\n            return draco.DT_INT16;\n        case Int32Array:\n            return draco.DT_INT32;\n        case Uint8Array:\n            return draco.DT_UINT8;\n        case Uint16Array:\n            return draco.DT_UINT16;\n        case Uint32Array:\n            return draco.DT_UINT32;\n        default:\n            return draco.DT_INVALID;\n    }\n}\n/**\n * Copy a Draco int32 array into a JS typed array\n */\nfunction getInt32Array(dracoArray) {\n    const numValues = dracoArray.size();\n    const intArray = new Int32Array(numValues);\n    for (let i = 0; i < numValues; i++) {\n        intArray[i] = dracoArray.GetValue(i);\n    }\n    return intArray;\n}\n/**\n * Copy a Draco int32 array into a JS typed array\n */\nfunction getUint32Array(dracoArray) {\n    const numValues = dracoArray.size();\n    const intArray = new Int32Array(numValues);\n    for (let i = 0; i < numValues; i++) {\n        intArray[i] = dracoArray.GetValue(i);\n    }\n    return intArray;\n}\n\n// Dynamic DRACO module loading inspired by THREE.DRACOLoader\nconst DRACO_DECODER_VERSION = '1.5.6';\nconst DRACO_ENCODER_VERSION = '1.4.1';\nconst STATIC_DECODER_URL = `https://www.gstatic.com/draco/versioned/decoders/${DRACO_DECODER_VERSION}`;\nconst DRACO_EXTERNAL_LIBRARIES = {\n    /** The primary Draco3D encoder, javascript wrapper part */\n    DECODER: 'draco_wasm_wrapper.js',\n    /** The primary draco decoder, compiled web assembly part */\n    DECODER_WASM: 'draco_decoder.wasm',\n    /** Fallback decoder for non-webassebly environments. Very big bundle, lower performance */\n    FALLBACK_DECODER: 'draco_decoder.js',\n    /** Draco encoder */\n    ENCODER: 'draco_encoder.js'\n};\nconst DRACO_EXTERNAL_LIBRARY_URLS = {\n    [DRACO_EXTERNAL_LIBRARIES.DECODER]: `${STATIC_DECODER_URL}/${DRACO_EXTERNAL_LIBRARIES.DECODER}`,\n    [DRACO_EXTERNAL_LIBRARIES.DECODER_WASM]: `${STATIC_DECODER_URL}/${DRACO_EXTERNAL_LIBRARIES.DECODER_WASM}`,\n    [DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER]: `${STATIC_DECODER_URL}/${DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER}`,\n    [DRACO_EXTERNAL_LIBRARIES.ENCODER]: `https://raw.githubusercontent.com/google/draco/${DRACO_ENCODER_VERSION}/javascript/${DRACO_EXTERNAL_LIBRARIES.ENCODER}`\n};\nlet loadDecoderPromise;\nasync function loadDracoDecoderModule(options) {\n    const modules = options.modules || {};\n    // Check if a bundled draco3d library has been supplied by application\n    if (modules.draco3d) {\n        loadDecoderPromise ||= modules.draco3d.createDecoderModule({}).then((draco) => {\n            return { draco };\n        });\n    }\n    else {\n        // If not, dynamically load the WASM script from our CDN\n        loadDecoderPromise ||= loadDracoDecoder(options);\n    }\n    return await loadDecoderPromise;\n}\n// DRACO DECODER LOADING\nasync function loadDracoDecoder(options) {\n    let DracoDecoderModule;\n    let wasmBinary;\n    switch (options.draco && options.draco.decoderType) {\n        case 'js':\n            DracoDecoderModule = await loadLibrary(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER], 'draco', options, DRACO_EXTERNAL_LIBRARIES.FALLBACK_DECODER);\n            break;\n        case 'wasm':\n        default:\n            [DracoDecoderModule, wasmBinary] = await Promise.all([\n                await loadLibrary(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER], 'draco', options, DRACO_EXTERNAL_LIBRARIES.DECODER),\n                await loadLibrary(DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER_WASM], 'draco', options, DRACO_EXTERNAL_LIBRARIES.DECODER_WASM)\n            ]);\n    }\n    // Depends on how import happened...\n    // @ts-ignore\n    DracoDecoderModule = DracoDecoderModule || globalThis.DracoDecoderModule;\n    return await initializeDracoDecoder(DracoDecoderModule, wasmBinary);\n}\nfunction initializeDracoDecoder(DracoDecoderModule, wasmBinary) {\n    const options = {};\n    if (wasmBinary) {\n        options.wasmBinary = wasmBinary;\n    }\n    return new Promise((resolve) => {\n        DracoDecoderModule({\n            ...options,\n            onModuleLoaded: (draco) => resolve({ draco }) // Module is Promise-like. Wrap in object to avoid loop.\n        });\n    });\n}\n\n/**\n * Browser worker doesn't work because of issue during \"draco_encoder.js\" loading.\n * Refused to execute script from 'https://raw.githubusercontent.com/google/draco/1.4.1/javascript/draco_encoder.js' because its MIME type ('') is not executable.\n */\n({\n    id: 'draco-writer',\n    name: 'Draco compressed geometry writer',\n    module: 'draco',\n    version: VERSION$1,\n    worker: true,\n    options: {\n        draco: {},\n        source: null\n    }\n});\n/**\n * Loader for Draco3D compressed geometries\n */\nconst DracoLoader = {\n    ...DracoLoader$1,\n    parse: parse$3\n};\nasync function parse$3(arrayBuffer, options) {\n    const { draco } = await loadDracoDecoderModule(options);\n    const dracoParser = new DracoParser(draco);\n    try {\n        return dracoParser.parseSync(arrayBuffer, options?.draco);\n    }\n    finally {\n        dracoParser.destroy();\n    }\n}\n\n// TODO - remove\n// Returns a fresh attributes object with glTF-standardized attributes names\n// Attributes that cannot be identified will not be included\n// Removes `indices` if present, as it should be stored separately from the attributes\nfunction getGLTFAccessors(attributes) {\n    const accessors = {};\n    for (const name in attributes) {\n        const attribute = attributes[name];\n        if (name !== 'indices') {\n            const glTFAccessor = getGLTFAccessor(attribute);\n            accessors[name] = glTFAccessor;\n        }\n    }\n    return accessors;\n}\n// Fix up a single accessor.\n// Input: typed array or a partial accessor object\n// Return: accessor object\nfunction getGLTFAccessor(attribute) {\n    const { buffer, size, count } = getAccessorData(attribute);\n    const glTFAccessor = {\n        // glTF Accessor values\n        // TODO: Instead of a bufferView index we could have an actual buffer (typed array)\n        // bufferView: null,\n        // TODO: Deprecate `value` in favor of bufferView?\n        // @ts-ignore\n        value: buffer,\n        size, // Decoded `type` (e.g. SCALAR)\n        byteOffset: 0,\n        count,\n        type: getAccessorTypeFromSize(size),\n        componentType: getComponentTypeFromArray(buffer)\n    };\n    return glTFAccessor;\n}\n// export function getGLTFAttribute(data, gltfAttributeName): GLTFAccessor {\n//   return data.attributes[data.glTFAttributeMap[gltfAttributeName]];\n// }\nfunction getAccessorData(attribute) {\n    let buffer = attribute;\n    let size = 1;\n    let count = 0;\n    if (attribute && attribute.value) {\n        buffer = attribute.value;\n        size = attribute.size || 1;\n    }\n    if (buffer) {\n        if (!ArrayBuffer.isView(buffer)) {\n            buffer = toTypedArray(buffer, Float32Array);\n        }\n        count = buffer.length / size;\n    }\n    return { buffer, size, count };\n}\n// Convert non-typed arrays to arrays of specified format\nfunction toTypedArray(array, ArrayType, convertTypedArrays = false) {\n    if (!array) {\n        return null;\n    }\n    if (Array.isArray(array)) {\n        return new ArrayType(array);\n    }\n    if (convertTypedArrays && !(array instanceof ArrayType)) {\n        return new ArrayType(array);\n    }\n    return array;\n}\n\n// https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression\nconst KHR_DRACO_MESH_COMPRESSION = 'KHR_draco_mesh_compression';\n/** Extension name */\nconst name$4 = KHR_DRACO_MESH_COMPRESSION;\nfunction preprocess$1(gltfData, options, context) {\n    const scenegraph = new GLTFScenegraph(gltfData);\n    for (const primitive of makeMeshPrimitiveIterator(scenegraph)) {\n        if (scenegraph.getObjectExtension(primitive, KHR_DRACO_MESH_COMPRESSION)) ;\n    }\n}\nasync function decode$6(gltfData, options, context) {\n    if (!options?.gltf?.decompressMeshes) {\n        return;\n    }\n    const scenegraph = new GLTFScenegraph(gltfData);\n    const promises = [];\n    for (const primitive of makeMeshPrimitiveIterator(scenegraph)) {\n        if (scenegraph.getObjectExtension(primitive, KHR_DRACO_MESH_COMPRESSION)) {\n            promises.push(decompressPrimitive(scenegraph, primitive, options, context));\n        }\n    }\n    // Decompress meshes in parallel\n    await Promise.all(promises);\n    // We have now decompressed all primitives, so remove the top-level extension\n    scenegraph.removeExtension(KHR_DRACO_MESH_COMPRESSION);\n}\nfunction encode$3(gltfData, options = {}) {\n    const scenegraph = new GLTFScenegraph(gltfData);\n    for (const mesh of scenegraph.json.meshes || []) {\n        // eslint-disable-next-line camelcase\n        // @ts-ignore\n        compressMesh(mesh);\n        // NOTE: Only add the extension if something was actually compressed\n        scenegraph.addRequiredExtension(KHR_DRACO_MESH_COMPRESSION);\n    }\n}\n// DECODE\n// Unpacks one mesh primitive and removes the extension from the primitive\n// DracoDecoder needs to be imported and registered by app\n// Returns: Promise that resolves when all pending draco decoder jobs for this mesh complete\n// TODO - Implement fallback behavior per KHR_DRACO_MESH_COMPRESSION spec\nasync function decompressPrimitive(scenegraph, primitive, options, context) {\n    const dracoExtension = scenegraph.getObjectExtension(primitive, KHR_DRACO_MESH_COMPRESSION);\n    if (!dracoExtension) {\n        return;\n    }\n    const buffer = scenegraph.getTypedArrayForBufferView(dracoExtension.bufferView);\n    // TODO - parse does not yet deal well with byte offsets embedded in typed arrays. Copy buffer\n    // TODO - remove when `parse` is fixed to handle `byteOffset`s\n    const bufferCopy = sliceArrayBuffer(buffer.buffer, buffer.byteOffset); // , buffer.byteLength);\n    const dracoOptions = { ...options };\n    // TODO - remove hack: The entire tileset might be included, too expensive to serialize\n    delete dracoOptions['3d-tiles'];\n    const decodedData = await parseFromContext(bufferCopy, DracoLoader, dracoOptions, context);\n    const decodedAttributes = getGLTFAccessors(decodedData.attributes);\n    // Restore min/max values\n    for (const [attributeName, decodedAttribute] of Object.entries(decodedAttributes)) {\n        if (attributeName in primitive.attributes) {\n            const accessorIndex = primitive.attributes[attributeName];\n            const accessor = scenegraph.getAccessor(accessorIndex);\n            if (accessor?.min && accessor?.max) {\n                decodedAttribute.min = accessor.min;\n                decodedAttribute.max = accessor.max;\n            }\n        }\n    }\n    // @ts-ignore\n    primitive.attributes = decodedAttributes;\n    if (decodedData.indices) {\n        // @ts-ignore\n        primitive.indices = getGLTFAccessor(decodedData.indices);\n    }\n    // Extension has been processed, delete it\n    scenegraph.removeObjectExtension(primitive, KHR_DRACO_MESH_COMPRESSION);\n    checkPrimitive(primitive);\n}\n// ENCODE\n// eslint-disable-next-line max-len\n// Only TRIANGLES: 0x0004 and TRIANGLE_STRIP: 0x0005 are supported\nfunction compressMesh(attributes, indices, mode = 4, options, context) {\n    if (!options.DracoWriter) {\n        throw new Error('options.gltf.DracoWriter not provided');\n    }\n    // TODO - use DracoWriter using encode w/ registered DracoWriter...\n    const compressedData = options.DracoWriter.encodeSync({ attributes });\n    // Draco compression may change the order and number of vertices in a mesh.\n    // To satisfy the requirement that accessors properties be correct for both\n    // compressed and uncompressed data, generators should create uncompressed\n    // attributes and indices using data that has been decompressed from the Draco buffer,\n    // rather than the original source data.\n    // @ts-ignore TODO this needs to be fixed\n    const decodedData = context?.parseSync?.({ attributes });\n    const fauxAccessors = options._addFauxAttributes(decodedData.attributes);\n    const bufferViewIndex = options.addBufferView(compressedData);\n    const glTFMesh = {\n        primitives: [\n            {\n                attributes: fauxAccessors, // TODO - verify with spec\n                mode, // GL.POINTS\n                extensions: {\n                    [KHR_DRACO_MESH_COMPRESSION]: {\n                        bufferView: bufferViewIndex,\n                        attributes: fauxAccessors // TODO - verify with spec\n                    }\n                }\n            }\n        ]\n    };\n    return glTFMesh;\n}\n// UTILS\nfunction checkPrimitive(primitive) {\n    if (!primitive.attributes && Object.keys(primitive.attributes).length > 0) {\n        throw new Error('glTF: Empty primitive detected: Draco decompression failure?');\n    }\n}\nfunction* makeMeshPrimitiveIterator(scenegraph) {\n    for (const mesh of scenegraph.json.meshes || []) {\n        for (const primitive of mesh.primitives) {\n            yield primitive;\n        }\n    }\n}\n\nvar KHR_draco_mesh_compression = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$4,\n    preprocess: preprocess$1,\n    decode: decode$6,\n    encode: encode$3\n});\n\n// math.gl\nconst DEFAULT_CONFIG = {\n    EPSILON: 1e-12,\n    debug: false,\n    precision: 4,\n    printTypes: false,\n    printDegrees: false,\n    printRowMajor: true,\n    _cartographicRadians: false\n};\n// Configuration is truly global as of v3.6 to ensure single config even if multiple copies of math.gl\n// Multiple copies of config can be quite tricky to debug...\nglobalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } };\nconst config = globalThis.mathgl.config;\n/**\n * Formats a value into a string\n * @param value\n * @param param1\n * @returns\n */\nfunction formatValue(value, { precision = config.precision } = {}) {\n    value = round(value);\n    // get rid of trailing zeros\n    return `${parseFloat(value.toPrecision(precision))}`;\n}\n/**\n * Check if value is an \"array\"\n * Returns `true` if value is either an array or a typed array\n * Note: returns `false` for `ArrayBuffer` and `DataView` instances\n * @note isTypedArray and isNumericArray are often more useful in TypeScript\n */\nfunction isArray(value) {\n    return Array.isArray(value) || (ArrayBuffer.isView(value) && !(value instanceof DataView));\n}\n/* eslint-disable */\n/**\n * Compares any two math objects, using `equals` method if available.\n * @param a\n * @param b\n * @param epsilon\n * @returns\n */\nfunction equals(a, b, epsilon) {\n    const oldEpsilon = config.EPSILON;\n    if (epsilon) {\n        config.EPSILON = epsilon;\n    }\n    try {\n        if (a === b) {\n            return true;\n        }\n        if (isArray(a) && isArray(b)) {\n            if (a.length !== b.length) {\n                return false;\n            }\n            for (let i = 0; i < a.length; ++i) {\n                // eslint-disable-next-line max-depth\n                if (!equals(a[i], b[i])) {\n                    return false;\n                }\n            }\n            return true;\n        }\n        if (a && a.equals) {\n            return a.equals(b);\n        }\n        if (b && b.equals) {\n            return b.equals(a);\n        }\n        if (typeof a === 'number' && typeof b === 'number') {\n            return Math.abs(a - b) <= config.EPSILON * Math.max(1, Math.abs(a), Math.abs(b));\n        }\n        return false;\n    }\n    finally {\n        config.EPSILON = oldEpsilon;\n    }\n}\n// HELPERS\nfunction round(value) {\n    return Math.round(value / config.EPSILON) * config.EPSILON;\n}\n\n// math.gl\n/** Base class for vectors and matrices */\nclass MathArray extends Array {\n    // Common methods\n    /**\n     * Clone the current object\n     * @returns a new copy of this object\n     */\n    clone() {\n        // @ts-expect-error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.\n        return new this.constructor().copy(this); // eslint-disable-line\n    }\n    fromArray(array, offset = 0) {\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            this[i] = array[i + offset];\n        }\n        return this.check();\n    }\n    toArray(targetArray = [], offset = 0) {\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            targetArray[offset + i] = this[i];\n        }\n        return targetArray;\n    }\n    toObject(targetObject) {\n        return targetObject;\n    }\n    from(arrayOrObject) {\n        return Array.isArray(arrayOrObject)\n            ? this.copy(arrayOrObject)\n            : // @ts-ignore\n                this.fromObject(arrayOrObject);\n    }\n    to(arrayOrObject) {\n        // @ts-ignore\n        if (arrayOrObject === this) {\n            return this;\n        }\n        // @ts-expect-error TS2339: Property 'toObject' does not exist on type 'MathArray'.\n        return isArray(arrayOrObject) ? this.toArray(arrayOrObject) : this.toObject(arrayOrObject);\n    }\n    toTarget(target) {\n        return target ? this.to(target) : this;\n    }\n    /** @deprecated */\n    toFloat32Array() {\n        return new Float32Array(this);\n    }\n    toString() {\n        return this.formatString(config);\n    }\n    /** Formats string according to options */\n    formatString(opts) {\n        let string = '';\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            string += (i > 0 ? ', ' : '') + formatValue(this[i], opts);\n        }\n        return `${opts.printTypes ? this.constructor.name : ''}[${string}]`;\n    }\n    equals(array) {\n        if (!array || this.length !== array.length) {\n            return false;\n        }\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            if (!equals(this[i], array[i])) {\n                return false;\n            }\n        }\n        return true;\n    }\n    exactEquals(array) {\n        if (!array || this.length !== array.length) {\n            return false;\n        }\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            if (this[i] !== array[i]) {\n                return false;\n            }\n        }\n        return true;\n    }\n    // Modifiers\n    /** Negates all values in this object */\n    negate() {\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            this[i] = -this[i];\n        }\n        return this.check();\n    }\n    lerp(a, b, t) {\n        if (t === undefined) {\n            return this.lerp(this, a, b);\n        }\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            const ai = a[i];\n            const endValue = typeof b === 'number' ? b : b[i];\n            this[i] = ai + t * (endValue - ai);\n        }\n        return this.check();\n    }\n    /** Minimal */\n    min(vector) {\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            this[i] = Math.min(vector[i], this[i]);\n        }\n        return this.check();\n    }\n    /** Maximal */\n    max(vector) {\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            this[i] = Math.max(vector[i], this[i]);\n        }\n        return this.check();\n    }\n    clamp(minVector, maxVector) {\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            this[i] = Math.min(Math.max(this[i], minVector[i]), maxVector[i]);\n        }\n        return this.check();\n    }\n    add(...vectors) {\n        for (const vector of vectors) {\n            for (let i = 0; i < this.ELEMENTS; ++i) {\n                this[i] += vector[i];\n            }\n        }\n        return this.check();\n    }\n    subtract(...vectors) {\n        for (const vector of vectors) {\n            for (let i = 0; i < this.ELEMENTS; ++i) {\n                this[i] -= vector[i];\n            }\n        }\n        return this.check();\n    }\n    scale(scale) {\n        if (typeof scale === 'number') {\n            for (let i = 0; i < this.ELEMENTS; ++i) {\n                this[i] *= scale;\n            }\n        }\n        else {\n            for (let i = 0; i < this.ELEMENTS && i < scale.length; ++i) {\n                this[i] *= scale[i];\n            }\n        }\n        return this.check();\n    }\n    /**\n     * Multiplies all elements by `scale`\n     * Note: `Matrix4.multiplyByScalar` only scales its 3x3 \"minor\"\n     */\n    multiplyByScalar(scalar) {\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            this[i] *= scalar;\n        }\n        return this.check();\n    }\n    // Debug checks\n    /** Throws an error if array length is incorrect or contains illegal values */\n    check() {\n        if (config.debug && !this.validate()) {\n            throw new Error(`math.gl: ${this.constructor.name} some fields set to invalid numbers'`);\n        }\n        return this;\n    }\n    /** Returns false if the array length is incorrect or contains illegal values */\n    validate() {\n        let valid = this.length === this.ELEMENTS;\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            valid = valid && Number.isFinite(this[i]);\n        }\n        return valid;\n    }\n    // three.js compatibility\n    /** @deprecated */\n    sub(a) {\n        return this.subtract(a);\n    }\n    /** @deprecated */\n    setScalar(a) {\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            this[i] = a;\n        }\n        return this.check();\n    }\n    /** @deprecated */\n    addScalar(a) {\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            this[i] += a;\n        }\n        return this.check();\n    }\n    /** @deprecated */\n    subScalar(a) {\n        return this.addScalar(-a);\n    }\n    /** @deprecated */\n    multiplyScalar(scalar) {\n        // Multiplies all elements\n        // `Matrix4.scale` only scales its 3x3 \"minor\"\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            this[i] *= scalar;\n        }\n        return this.check();\n    }\n    /** @deprecated */\n    divideScalar(a) {\n        return this.multiplyByScalar(1 / a);\n    }\n    /** @deprecated */\n    clampScalar(min, max) {\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            this[i] = Math.min(Math.max(this[i], min), max);\n        }\n        return this.check();\n    }\n    /** @deprecated */\n    get elements() {\n        return this;\n    }\n}\n\n// math.gl\nfunction validateVector(v, length) {\n    if (v.length !== length) {\n        return false;\n    }\n    // Could be arguments \"array\" (v.every not availasble)\n    for (let i = 0; i < v.length; ++i) {\n        if (!Number.isFinite(v[i])) {\n            return false;\n        }\n    }\n    return true;\n}\nfunction checkNumber(value) {\n    if (!Number.isFinite(value)) {\n        throw new Error(`Invalid number ${JSON.stringify(value)}`);\n    }\n    return value;\n}\nfunction checkVector(v, length, callerName = '') {\n    if (config.debug && !validateVector(v, length)) {\n        throw new Error(`math.gl: ${callerName} some fields set to invalid numbers'`);\n    }\n    return v;\n}\n\n// math.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nfunction assert(condition, message) {\n    if (!condition) {\n        throw new Error(`math.gl assertion ${message}`);\n    }\n}\n\n// math.gl\n/** Base class for vectors with at least 2 elements */\nclass Vector$1 extends MathArray {\n    // ACCESSORS\n    get x() {\n        return this[0];\n    }\n    set x(value) {\n        this[0] = checkNumber(value);\n    }\n    get y() {\n        return this[1];\n    }\n    set y(value) {\n        this[1] = checkNumber(value);\n    }\n    /**\n     * Returns the length of the vector from the origin to the point described by this vector\n     *\n     * @note `length` is a reserved word for Arrays, so `v.length()` will return number of elements\n     * Instead we provide `len` and `magnitude`\n     */\n    len() {\n        return Math.sqrt(this.lengthSquared());\n    }\n    /**\n     * Returns the length of the vector from the origin to the point described by this vector\n     */\n    magnitude() {\n        return this.len();\n    }\n    /**\n     * Returns the squared length of the vector from the origin to the point described by this vector\n     */\n    lengthSquared() {\n        let length = 0;\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            length += this[i] * this[i];\n        }\n        return length;\n    }\n    /**\n     * Returns the squared length of the vector from the origin to the point described by this vector\n     */\n    magnitudeSquared() {\n        return this.lengthSquared();\n    }\n    distance(mathArray) {\n        return Math.sqrt(this.distanceSquared(mathArray));\n    }\n    distanceSquared(mathArray) {\n        let length = 0;\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            const dist = this[i] - mathArray[i];\n            length += dist * dist;\n        }\n        return checkNumber(length);\n    }\n    dot(mathArray) {\n        let product = 0;\n        for (let i = 0; i < this.ELEMENTS; ++i) {\n            product += this[i] * mathArray[i];\n        }\n        return checkNumber(product);\n    }\n    // MODIFIERS\n    normalize() {\n        const length = this.magnitude();\n        if (length !== 0) {\n            for (let i = 0; i < this.ELEMENTS; ++i) {\n                this[i] /= length;\n            }\n        }\n        return this.check();\n    }\n    multiply(...vectors) {\n        for (const vector of vectors) {\n            for (let i = 0; i < this.ELEMENTS; ++i) {\n                this[i] *= vector[i];\n            }\n        }\n        return this.check();\n    }\n    divide(...vectors) {\n        for (const vector of vectors) {\n            for (let i = 0; i < this.ELEMENTS; ++i) {\n                this[i] /= vector[i];\n            }\n        }\n        return this.check();\n    }\n    // THREE.js compatibility\n    lengthSq() {\n        return this.lengthSquared();\n    }\n    distanceTo(vector) {\n        return this.distance(vector);\n    }\n    distanceToSquared(vector) {\n        return this.distanceSquared(vector);\n    }\n    getComponent(i) {\n        assert(i >= 0 && i < this.ELEMENTS, 'index is out of range');\n        return checkNumber(this[i]);\n    }\n    setComponent(i, value) {\n        assert(i >= 0 && i < this.ELEMENTS, 'index is out of range');\n        this[i] = value;\n        return this.check();\n    }\n    addVectors(a, b) {\n        return this.copy(a).add(b);\n    }\n    subVectors(a, b) {\n        return this.copy(a).subtract(b);\n    }\n    multiplyVectors(a, b) {\n        return this.copy(a).multiply(b);\n    }\n    addScaledVector(a, b) {\n        // @ts-expect-error error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.\n        return this.add(new this.constructor(a).multiplyScalar(b));\n    }\n}\n\n// @eslint-disable\nlet ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array;\n\n// @eslint-disable\n/**\n * 2 Dimensional Vector\n * @module vec2\n */\n/**\n * Creates a new, empty vec2\n *\n * @returns a new 2D vector\n */\nfunction create$1() {\n    const out = new ARRAY_TYPE(2);\n    if (ARRAY_TYPE != Float32Array) {\n        out[0] = 0;\n        out[1] = 0;\n    }\n    return out;\n}\n/**\n * Transforms the vec2 with a mat3\n * 3rd vector component is implicitly '1'\n *\n * @param {NumericArray} out the receiving vector\n * @param {Readonly<NumericArray>} a the vector to transform\n * @param {ReadonlyMat3} m matrix to transform with\n * @returns {NumericArray} out\n */\nfunction transformMat3$1(out, a, m) {\n    const x = a[0];\n    const y = a[1];\n    out[0] = m[0] * x + m[3] * y + m[6];\n    out[1] = m[1] * x + m[4] * y + m[7];\n    return out;\n}\n/**\n * Perform some operation over an array of vec2s.\n *\n * @param {Array} a the array of vectors to iterate over\n * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed\n * @param {Number} offset Number of elements to skip at the beginning of the array\n * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array\n * @param {Function} fn Function to call for each vector in the array\n * @param {Object} [arg] additional argument to pass to fn\n * @returns {Array} a\n * @function\n */\n((function () {\n    const vec = create$1();\n    return function (a, stride, offset, count, fn, arg) {\n        let i;\n        let l;\n        if (!stride) {\n            stride = 2;\n        }\n        if (!offset) {\n            offset = 0;\n        }\n        if (count) {\n            l = Math.min(count * stride + offset, a.length);\n        }\n        else {\n            l = a.length;\n        }\n        for (i = offset; i < l; i += stride) {\n            vec[0] = a[i];\n            vec[1] = a[i + 1];\n            fn(vec, vec, arg);\n            a[i] = vec[0];\n            a[i + 1] = vec[1];\n        }\n        return a;\n    };\n}))();\n\n// math.gl\n// vec3 additions\n// Transform as vector, only uses 3x3 minor matrix\nfunction vec3_transformMat4AsVector(out, a, m) {\n    const x = a[0];\n    const y = a[1];\n    const z = a[2];\n    const w = m[3] * x + m[7] * y + m[11] * z || 1.0;\n    out[0] = (m[0] * x + m[4] * y + m[8] * z) / w;\n    out[1] = (m[1] * x + m[5] * y + m[9] * z) / w;\n    out[2] = (m[2] * x + m[6] * y + m[10] * z) / w;\n    return out;\n}\nfunction vec3_transformMat2(out, a, m) {\n    const x = a[0];\n    const y = a[1];\n    out[0] = m[0] * x + m[2] * y;\n    out[1] = m[1] * x + m[3] * y;\n    out[2] = a[2];\n    return out;\n}\nfunction vec4_transformMat3(out, a, m) {\n    const x = a[0];\n    const y = a[1];\n    const z = a[2];\n    out[0] = m[0] * x + m[3] * y + m[6] * z;\n    out[1] = m[1] * x + m[4] * y + m[7] * z;\n    out[2] = m[2] * x + m[5] * y + m[8] * z;\n    out[3] = a[3];\n    return out;\n}\n\n// @eslint-disable\n/**\n * 3 Dimensional Vector\n * @module vec3\n */\n/**\n * Creates a new, empty vec3\n *\n * @returns {vec3} a new 3D vector\n */\nfunction create() {\n    const out = new ARRAY_TYPE(3);\n    if (ARRAY_TYPE != Float32Array) {\n        out[0] = 0;\n        out[1] = 0;\n        out[2] = 0;\n    }\n    return out;\n}\n/**\n * Calculates the dot product of two vec3's\n *\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {Number} dot product of a and b\n */\nfunction dot(a, b) {\n    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n/**\n * Computes the cross product of two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nfunction cross(out, a, b) {\n    const ax = a[0];\n    const ay = a[1];\n    const az = a[2];\n    const bx = b[0];\n    const by = b[1];\n    const bz = b[2];\n    out[0] = ay * bz - az * by;\n    out[1] = az * bx - ax * bz;\n    out[2] = ax * by - ay * bx;\n    return out;\n}\n/**\n * Transforms the vec3 with a mat4.\n * 4th vector component is implicitly '1'\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyMat4} m matrix to transform with\n * @returns {vec3} out\n */\nfunction transformMat4(out, a, m) {\n    const x = a[0];\n    const y = a[1];\n    const z = a[2];\n    let w = m[3] * x + m[7] * y + m[11] * z + m[15];\n    w = w || 1.0;\n    out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;\n    out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;\n    out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;\n    return out;\n}\n/**\n * Transforms the vec3 with a mat3.\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyMat3} m the 3x3 matrix to transform with\n * @returns {vec3} out\n */\nfunction transformMat3(out, a, m) {\n    const x = a[0];\n    const y = a[1];\n    const z = a[2];\n    out[0] = x * m[0] + y * m[3] + z * m[6];\n    out[1] = x * m[1] + y * m[4] + z * m[7];\n    out[2] = x * m[2] + y * m[5] + z * m[8];\n    return out;\n}\n/**\n * Transforms the vec3 with a quat\n * Can also be used for dual quaternions. (Multiply it with the real part)\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyQuat} q quaternion to transform with\n * @returns {vec3} out\n */\nfunction transformQuat(out, a, q) {\n    // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed\n    const qx = q[0];\n    const qy = q[1];\n    const qz = q[2];\n    const qw = q[3];\n    const x = a[0];\n    const y = a[1];\n    const z = a[2];\n    // var qvec = [qx, qy, qz];\n    // var uv = vec3.cross([], qvec, a);\n    let uvx = qy * z - qz * y;\n    let uvy = qz * x - qx * z;\n    let uvz = qx * y - qy * x;\n    // var uuv = vec3.cross([], qvec, uv);\n    let uuvx = qy * uvz - qz * uvy;\n    let uuvy = qz * uvx - qx * uvz;\n    let uuvz = qx * uvy - qy * uvx;\n    // vec3.scale(uv, uv, 2 * w);\n    const w2 = qw * 2;\n    uvx *= w2;\n    uvy *= w2;\n    uvz *= w2;\n    // vec3.scale(uuv, uuv, 2);\n    uuvx *= 2;\n    uuvy *= 2;\n    uuvz *= 2;\n    // return vec3.add(out, a, vec3.add(out, uv, uuv));\n    out[0] = x + uvx + uuvx;\n    out[1] = y + uvy + uuvy;\n    out[2] = z + uvz + uuvz;\n    return out;\n}\n/**\n * Rotate a 3D vector around the x-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\nfunction rotateX(out, a, b, rad) {\n    const p = [];\n    const r = [];\n    // Translate point to the origin\n    p[0] = a[0] - b[0];\n    p[1] = a[1] - b[1];\n    p[2] = a[2] - b[2];\n    // perform rotation\n    r[0] = p[0];\n    r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad);\n    r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad);\n    // translate to correct position\n    out[0] = r[0] + b[0];\n    out[1] = r[1] + b[1];\n    out[2] = r[2] + b[2];\n    return out;\n}\n/**\n * Rotate a 3D vector around the y-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\nfunction rotateY(out, a, b, rad) {\n    const p = [];\n    const r = [];\n    // Translate point to the origin\n    p[0] = a[0] - b[0];\n    p[1] = a[1] - b[1];\n    p[2] = a[2] - b[2];\n    // perform rotation\n    r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad);\n    r[1] = p[1];\n    r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad);\n    // translate to correct position\n    out[0] = r[0] + b[0];\n    out[1] = r[1] + b[1];\n    out[2] = r[2] + b[2];\n    return out;\n}\n/**\n * Rotate a 3D vector around the z-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\nfunction rotateZ(out, a, b, rad) {\n    const p = [];\n    const r = [];\n    // Translate point to the origin\n    p[0] = a[0] - b[0];\n    p[1] = a[1] - b[1];\n    p[2] = a[2] - b[2];\n    // perform rotation\n    r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad);\n    r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad);\n    r[2] = p[2];\n    // translate to correct position\n    out[0] = r[0] + b[0];\n    out[1] = r[1] + b[1];\n    out[2] = r[2] + b[2];\n    return out;\n}\n/**\n * Get the angle between two 3D vectors\n * @param {ReadonlyVec3} a The first operand\n * @param {ReadonlyVec3} b The second operand\n * @returns {Number} The angle in radians\n */\nfunction angle$1(a, b) {\n    const ax = a[0];\n    const ay = a[1];\n    const az = a[2];\n    const bx = b[0];\n    const by = b[1];\n    const bz = b[2];\n    const mag = Math.sqrt((ax * ax + ay * ay + az * az) * (bx * bx + by * by + bz * bz));\n    const cosine = mag && dot(a, b) / mag;\n    return Math.acos(Math.min(Math.max(cosine, -1), 1));\n}\n/**\n * Perform some operation over an array of vec3s.\n *\n * @param {Array} a the array of vectors to iterate over\n * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed\n * @param {Number} offset Number of elements to skip at the beginning of the array\n * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array\n * @param {Function} fn Function to call for each vector in the array\n * @param {Object} [arg] additional argument to pass to fn\n * @returns {Array} a\n * @function\n */\n((function () {\n    const vec = create();\n    return function (a, stride, offset, count, fn, arg) {\n        let i;\n        let l;\n        if (!stride) {\n            stride = 3;\n        }\n        if (!offset) {\n            offset = 0;\n        }\n        if (count) {\n            l = Math.min(count * stride + offset, a.length);\n        }\n        else {\n            l = a.length;\n        }\n        for (i = offset; i < l; i += stride) {\n            vec[0] = a[i];\n            vec[1] = a[i + 1];\n            vec[2] = a[i + 2];\n            fn(vec, vec, arg);\n            a[i] = vec[0];\n            a[i + 1] = vec[1];\n            a[i + 2] = vec[2];\n        }\n        return a;\n    };\n}))();\n\n// math.gl\nconst ORIGIN = [0, 0, 0];\nlet ZERO$1;\n/**\n * Three-element vector class with common linear algebra operations.\n * Subclass of Array<number> meaning that it is highly compatible with other libraries\n */\nclass Vector3 extends Vector$1 {\n    static get ZERO() {\n        if (!ZERO$1) {\n            ZERO$1 = new Vector3(0, 0, 0);\n            Object.freeze(ZERO$1);\n        }\n        return ZERO$1;\n    }\n    /**\n     * @class\n     * @param x\n     * @param y\n     * @param z\n     */\n    constructor(x = 0, y = 0, z = 0) {\n        // PERF NOTE: initialize elements as double precision numbers\n        super(-0, -0, -0);\n        if (arguments.length === 1 && isArray(x)) {\n            this.copy(x);\n        }\n        else {\n            // this.set(x, y, z);\n            if (config.debug) {\n                checkNumber(x);\n                checkNumber(y);\n                checkNumber(z);\n            }\n            // @ts-expect-error TS2412: Property '0' of type 'number | [number, number, number]' is not assignable to numeric index type 'number'\n            this[0] = x;\n            this[1] = y;\n            this[2] = z;\n        }\n    }\n    set(x, y, z) {\n        this[0] = x;\n        this[1] = y;\n        this[2] = z;\n        return this.check();\n    }\n    copy(array) {\n        this[0] = array[0];\n        this[1] = array[1];\n        this[2] = array[2];\n        return this.check();\n    }\n    fromObject(object) {\n        if (config.debug) {\n            checkNumber(object.x);\n            checkNumber(object.y);\n            checkNumber(object.z);\n        }\n        this[0] = object.x;\n        this[1] = object.y;\n        this[2] = object.z;\n        return this.check();\n    }\n    toObject(object) {\n        object.x = this[0];\n        object.y = this[1];\n        object.z = this[2];\n        return object;\n    }\n    // Getters/setters\n    get ELEMENTS() {\n        return 3;\n    }\n    get z() {\n        return this[2];\n    }\n    set z(value) {\n        this[2] = checkNumber(value);\n    }\n    // ACCESSORS\n    angle(vector) {\n        return angle$1(this, vector);\n    }\n    // MODIFIERS\n    cross(vector) {\n        cross(this, this, vector);\n        return this.check();\n    }\n    rotateX({ radians, origin = ORIGIN }) {\n        rotateX(this, this, origin, radians);\n        return this.check();\n    }\n    rotateY({ radians, origin = ORIGIN }) {\n        rotateY(this, this, origin, radians);\n        return this.check();\n    }\n    rotateZ({ radians, origin = ORIGIN }) {\n        rotateZ(this, this, origin, radians);\n        return this.check();\n    }\n    // Transforms\n    // transforms as point (4th component is implicitly 1)\n    transform(matrix4) {\n        return this.transformAsPoint(matrix4);\n    }\n    // transforms as point (4th component is implicitly 1)\n    transformAsPoint(matrix4) {\n        transformMat4(this, this, matrix4);\n        return this.check();\n    }\n    // transforms as vector  (4th component is implicitly 0, ignores translation. slightly faster)\n    transformAsVector(matrix4) {\n        vec3_transformMat4AsVector(this, this, matrix4);\n        return this.check();\n    }\n    transformByMatrix3(matrix3) {\n        transformMat3(this, this, matrix3);\n        return this.check();\n    }\n    transformByMatrix2(matrix2) {\n        vec3_transformMat2(this, this, matrix2);\n        return this.check();\n    }\n    transformByQuaternion(quaternion) {\n        transformQuat(this, this, quaternion);\n        return this.check();\n    }\n}\n\n// math.gl\n/** Base class for matrices */\nclass Matrix extends MathArray {\n    // fromObject(object) {\n    //   const array = object.elements;\n    //   return this.fromRowMajor(array);\n    // }\n    // toObject(object) {\n    //   const array = object.elements;\n    //   this.toRowMajor(array);\n    //   return object;\n    // }\n    // TODO better override formatString?\n    toString() {\n        let string = '[';\n        if (config.printRowMajor) {\n            string += 'row-major:';\n            for (let row = 0; row < this.RANK; ++row) {\n                for (let col = 0; col < this.RANK; ++col) {\n                    string += ` ${this[col * this.RANK + row]}`;\n                }\n            }\n        }\n        else {\n            string += 'column-major:';\n            for (let i = 0; i < this.ELEMENTS; ++i) {\n                string += ` ${this[i]}`;\n            }\n        }\n        string += ']';\n        return string;\n    }\n    getElementIndex(row, col) {\n        return col * this.RANK + row;\n    }\n    // By default assumes row major indices\n    getElement(row, col) {\n        return this[col * this.RANK + row];\n    }\n    // By default assumes row major indices\n    setElement(row, col, value) {\n        this[col * this.RANK + row] = checkNumber(value);\n        return this;\n    }\n    getColumn(columnIndex, result = new Array(this.RANK).fill(-0)) {\n        const firstIndex = columnIndex * this.RANK;\n        for (let i = 0; i < this.RANK; ++i) {\n            result[i] = this[firstIndex + i];\n        }\n        return result;\n    }\n    setColumn(columnIndex, columnVector) {\n        const firstIndex = columnIndex * this.RANK;\n        for (let i = 0; i < this.RANK; ++i) {\n            this[firstIndex + i] = columnVector[i];\n        }\n        return this;\n    }\n}\n\n/**\n * Transpose the values of a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the source matrix\n * @returns {mat3} out\n */\nfunction transpose(out, a) {\n    // If we are transposing ourselves we can skip a few steps but have to cache some values\n    if (out === a) {\n        const a01 = a[1];\n        const a02 = a[2];\n        const a12 = a[5];\n        out[1] = a[3];\n        out[2] = a[6];\n        out[3] = a01;\n        out[5] = a[7];\n        out[6] = a02;\n        out[7] = a12;\n    }\n    else {\n        out[0] = a[0];\n        out[1] = a[3];\n        out[2] = a[6];\n        out[3] = a[1];\n        out[4] = a[4];\n        out[5] = a[7];\n        out[6] = a[2];\n        out[7] = a[5];\n        out[8] = a[8];\n    }\n    return out;\n}\n/**\n * Inverts a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the source matrix\n * @returns {mat3} out\n */\nfunction invert(out, a) {\n    const a00 = a[0];\n    const a01 = a[1];\n    const a02 = a[2];\n    const a10 = a[3];\n    const a11 = a[4];\n    const a12 = a[5];\n    const a20 = a[6];\n    const a21 = a[7];\n    const a22 = a[8];\n    const b01 = a22 * a11 - a12 * a21;\n    const b11 = -a22 * a10 + a12 * a20;\n    const b21 = a21 * a10 - a11 * a20;\n    // Calculate the determinant\n    let det = a00 * b01 + a01 * b11 + a02 * b21;\n    if (!det) {\n        return null;\n    }\n    det = 1.0 / det;\n    out[0] = b01 * det;\n    out[1] = (-a22 * a01 + a02 * a21) * det;\n    out[2] = (a12 * a01 - a02 * a11) * det;\n    out[3] = b11 * det;\n    out[4] = (a22 * a00 - a02 * a20) * det;\n    out[5] = (-a12 * a00 + a02 * a10) * det;\n    out[6] = b21 * det;\n    out[7] = (-a21 * a00 + a01 * a20) * det;\n    out[8] = (a11 * a00 - a01 * a10) * det;\n    return out;\n}\n/**\n * Calculates the determinant of a mat3\n *\n * @param {ReadonlyMat3} a the source matrix\n * @returns {Number} determinant of a\n */\nfunction determinant(a) {\n    const a00 = a[0];\n    const a01 = a[1];\n    const a02 = a[2];\n    const a10 = a[3];\n    const a11 = a[4];\n    const a12 = a[5];\n    const a20 = a[6];\n    const a21 = a[7];\n    const a22 = a[8];\n    return (a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20));\n}\n/**\n * Multiplies two mat3's\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the first operand\n * @param {ReadonlyMat3} b the second operand\n * @returns {mat3} out\n */\nfunction multiply(out, a, b) {\n    const a00 = a[0];\n    const a01 = a[1];\n    const a02 = a[2];\n    const a10 = a[3];\n    const a11 = a[4];\n    const a12 = a[5];\n    const a20 = a[6];\n    const a21 = a[7];\n    const a22 = a[8];\n    const b00 = b[0];\n    const b01 = b[1];\n    const b02 = b[2];\n    const b10 = b[3];\n    const b11 = b[4];\n    const b12 = b[5];\n    const b20 = b[6];\n    const b21 = b[7];\n    const b22 = b[8];\n    out[0] = b00 * a00 + b01 * a10 + b02 * a20;\n    out[1] = b00 * a01 + b01 * a11 + b02 * a21;\n    out[2] = b00 * a02 + b01 * a12 + b02 * a22;\n    out[3] = b10 * a00 + b11 * a10 + b12 * a20;\n    out[4] = b10 * a01 + b11 * a11 + b12 * a21;\n    out[5] = b10 * a02 + b11 * a12 + b12 * a22;\n    out[6] = b20 * a00 + b21 * a10 + b22 * a20;\n    out[7] = b20 * a01 + b21 * a11 + b22 * a21;\n    out[8] = b20 * a02 + b21 * a12 + b22 * a22;\n    return out;\n}\n/**\n * Translate a mat3 by the given vector\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to translate\n * @param {ReadonlyVec2} v vector to translate by\n * @returns {mat3} out\n */\nfunction translate(out, a, v) {\n    const a00 = a[0];\n    const a01 = a[1];\n    const a02 = a[2];\n    const a10 = a[3];\n    const a11 = a[4];\n    const a12 = a[5];\n    const a20 = a[6];\n    const a21 = a[7];\n    const a22 = a[8];\n    const x = v[0];\n    const y = v[1];\n    out[0] = a00;\n    out[1] = a01;\n    out[2] = a02;\n    out[3] = a10;\n    out[4] = a11;\n    out[5] = a12;\n    out[6] = x * a00 + y * a10 + a20;\n    out[7] = x * a01 + y * a11 + a21;\n    out[8] = x * a02 + y * a12 + a22;\n    return out;\n}\n/**\n * Rotates a mat3 by the given angle\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat3} out\n */\nfunction rotate(out, a, rad) {\n    const a00 = a[0];\n    const a01 = a[1];\n    const a02 = a[2];\n    const a10 = a[3];\n    const a11 = a[4];\n    const a12 = a[5];\n    const a20 = a[6];\n    const a21 = a[7];\n    const a22 = a[8];\n    const s = Math.sin(rad);\n    const c = Math.cos(rad);\n    out[0] = c * a00 + s * a10;\n    out[1] = c * a01 + s * a11;\n    out[2] = c * a02 + s * a12;\n    out[3] = c * a10 - s * a00;\n    out[4] = c * a11 - s * a01;\n    out[5] = c * a12 - s * a02;\n    out[6] = a20;\n    out[7] = a21;\n    out[8] = a22;\n    return out;\n}\n/**\n * Scales the mat3 by the dimensions in the given vec2\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to scale\n * @param {ReadonlyVec2} v the vec2 to scale the matrix by\n * @returns {mat3} out\n **/\nfunction scale(out, a, v) {\n    const x = v[0];\n    const y = v[1];\n    out[0] = x * a[0];\n    out[1] = x * a[1];\n    out[2] = x * a[2];\n    out[3] = y * a[3];\n    out[4] = y * a[4];\n    out[5] = y * a[5];\n    out[6] = a[6];\n    out[7] = a[7];\n    out[8] = a[8];\n    return out;\n}\n/**\n * Calculates a 3x3 matrix from the given quaternion\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {ReadonlyQuat} q Quaternion to create matrix from\n *\n * @returns {mat3} out\n */\nfunction fromQuat(out, q) {\n    const x = q[0];\n    const y = q[1];\n    const z = q[2];\n    const w = q[3];\n    const x2 = x + x;\n    const y2 = y + y;\n    const z2 = z + z;\n    const xx = x * x2;\n    const yx = y * x2;\n    const yy = y * y2;\n    const zx = z * x2;\n    const zy = z * y2;\n    const zz = z * z2;\n    const wx = w * x2;\n    const wy = w * y2;\n    const wz = w * z2;\n    out[0] = 1 - yy - zz;\n    out[3] = yx - wz;\n    out[6] = zx + wy;\n    out[1] = yx + wz;\n    out[4] = 1 - xx - zz;\n    out[7] = zy - wx;\n    out[2] = zx - wy;\n    out[5] = zy + wx;\n    out[8] = 1 - xx - yy;\n    return out;\n}\n\n// math.gl\n// eslint-disable-next-line no-shadow\nvar INDICES;\n(function (INDICES) {\n    INDICES[INDICES[\"COL0ROW0\"] = 0] = \"COL0ROW0\";\n    INDICES[INDICES[\"COL0ROW1\"] = 1] = \"COL0ROW1\";\n    INDICES[INDICES[\"COL0ROW2\"] = 2] = \"COL0ROW2\";\n    INDICES[INDICES[\"COL1ROW0\"] = 3] = \"COL1ROW0\";\n    INDICES[INDICES[\"COL1ROW1\"] = 4] = \"COL1ROW1\";\n    INDICES[INDICES[\"COL1ROW2\"] = 5] = \"COL1ROW2\";\n    INDICES[INDICES[\"COL2ROW0\"] = 6] = \"COL2ROW0\";\n    INDICES[INDICES[\"COL2ROW1\"] = 7] = \"COL2ROW1\";\n    INDICES[INDICES[\"COL2ROW2\"] = 8] = \"COL2ROW2\";\n})(INDICES || (INDICES = {}));\nconst IDENTITY_MATRIX = Object.freeze([1, 0, 0, 0, 1, 0, 0, 0, 1]);\n/**\n * A 3x3 matrix with common linear algebra operations\n * Subclass of Array<number> meaning that it is highly compatible with other libraries\n */\nclass Matrix3 extends Matrix {\n    static get IDENTITY() {\n        return getIdentityMatrix();\n    }\n    static get ZERO() {\n        return getZeroMatrix();\n    }\n    get ELEMENTS() {\n        return 9;\n    }\n    get RANK() {\n        return 3;\n    }\n    get INDICES() {\n        return INDICES;\n    }\n    constructor(array, ...args) {\n        // PERF NOTE: initialize elements as double precision numbers\n        super(-0, -0, -0, -0, -0, -0, -0, -0, -0);\n        if (arguments.length === 1 && Array.isArray(array)) {\n            this.copy(array);\n        }\n        else if (args.length > 0) {\n            this.copy([array, ...args]);\n        }\n        else {\n            this.identity();\n        }\n    }\n    copy(array) {\n        // Element wise copy for performance\n        this[0] = array[0];\n        this[1] = array[1];\n        this[2] = array[2];\n        this[3] = array[3];\n        this[4] = array[4];\n        this[5] = array[5];\n        this[6] = array[6];\n        this[7] = array[7];\n        this[8] = array[8];\n        return this.check();\n    }\n    // Constructors\n    identity() {\n        return this.copy(IDENTITY_MATRIX);\n    }\n    /**\n     *\n     * @param object\n     * @returns self\n     */\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    fromObject(object) {\n        return this.check();\n    }\n    /** Calculates a 3x3 matrix from the given quaternion\n     * q quat  Quaternion to create matrix from\n     */\n    fromQuaternion(q) {\n        fromQuat(this, q);\n        return this.check();\n    }\n    /**\n     * accepts column major order, stores in column major order\n     */\n    // eslint-disable-next-line max-params\n    set(m00, m10, m20, m01, m11, m21, m02, m12, m22) {\n        this[0] = m00;\n        this[1] = m10;\n        this[2] = m20;\n        this[3] = m01;\n        this[4] = m11;\n        this[5] = m21;\n        this[6] = m02;\n        this[7] = m12;\n        this[8] = m22;\n        return this.check();\n    }\n    /**\n     * accepts row major order, stores as column major\n     */\n    // eslint-disable-next-line max-params\n    setRowMajor(m00, m01, m02, m10, m11, m12, m20, m21, m22) {\n        this[0] = m00;\n        this[1] = m10;\n        this[2] = m20;\n        this[3] = m01;\n        this[4] = m11;\n        this[5] = m21;\n        this[6] = m02;\n        this[7] = m12;\n        this[8] = m22;\n        return this.check();\n    }\n    // Accessors\n    determinant() {\n        return determinant(this);\n    }\n    // Modifiers\n    transpose() {\n        transpose(this, this);\n        return this.check();\n    }\n    /** Invert a matrix. Note that this can fail if the matrix is not invertible */\n    invert() {\n        invert(this, this);\n        return this.check();\n    }\n    // Operations\n    multiplyLeft(a) {\n        multiply(this, a, this);\n        return this.check();\n    }\n    multiplyRight(a) {\n        multiply(this, this, a);\n        return this.check();\n    }\n    rotate(radians) {\n        rotate(this, this, radians);\n        return this.check();\n    }\n    scale(factor) {\n        if (Array.isArray(factor)) {\n            scale(this, this, factor);\n        }\n        else {\n            scale(this, this, [factor, factor]);\n        }\n        return this.check();\n    }\n    translate(vec) {\n        translate(this, this, vec);\n        return this.check();\n    }\n    // Transforms\n    transform(vector, result) {\n        let out;\n        switch (vector.length) {\n            case 2:\n                out = transformMat3$1(result || [-0, -0], vector, this);\n                break;\n            case 3:\n                out = transformMat3(result || [-0, -0, -0], vector, this);\n                break;\n            case 4:\n                out = vec4_transformMat3(result || [-0, -0, -0, -0], vector, this);\n                break;\n            default:\n                throw new Error('Illegal vector');\n        }\n        checkVector(out, vector.length);\n        return out;\n    }\n    /** @deprecated */\n    transformVector(vector, result) {\n        return this.transform(vector, result);\n    }\n    /** @deprecated */\n    transformVector2(vector, result) {\n        return this.transform(vector, result);\n    }\n    /** @deprecated */\n    transformVector3(vector, result) {\n        return this.transform(vector, result);\n    }\n}\nlet ZERO_MATRIX3;\nlet IDENTITY_MATRIX3 = null;\nfunction getZeroMatrix() {\n    if (!ZERO_MATRIX3) {\n        ZERO_MATRIX3 = new Matrix3([0, 0, 0, 0, 0, 0, 0, 0, 0]);\n        Object.freeze(ZERO_MATRIX3);\n    }\n    return ZERO_MATRIX3;\n}\nfunction getIdentityMatrix() {\n    if (!IDENTITY_MATRIX3) {\n        IDENTITY_MATRIX3 = new Matrix3();\n        Object.freeze(IDENTITY_MATRIX3);\n    }\n    return IDENTITY_MATRIX3;\n}\n\n/**\n * https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_texture_transform/README.md\n */\n/** Extension name */\nconst KHR_TEXTURE_TRANSFORM = 'KHR_texture_transform';\nconst name$3 = KHR_TEXTURE_TRANSFORM;\nconst scratchVector = new Vector3();\nconst scratchRotationMatrix = new Matrix3();\nconst scratchScaleMatrix = new Matrix3();\n/**\n * The extension entry to process the transformation\n * @param gltfData gltf buffers and json\n * @param options GLTFLoader options\n */\nasync function decode$5(gltfData, options) {\n    const gltfScenegraph = new GLTFScenegraph(gltfData);\n    const hasExtension = gltfScenegraph.hasExtension(KHR_TEXTURE_TRANSFORM);\n    if (!hasExtension || !options.gltf?.loadBuffers) {\n        return;\n    }\n    const materials = gltfData.json.materials || [];\n    for (let i = 0; i < materials.length; i++) {\n        transformTexCoords(i, gltfData);\n    }\n}\n/**\n * Transform TEXCOORD by material\n * @param materialIndex processing material index\n * @param gltfData gltf buffers and json\n */\nfunction transformTexCoords(materialIndex, gltfData) {\n    const material = gltfData.json.materials?.[materialIndex];\n    const materialTextures = [\n        material?.pbrMetallicRoughness?.baseColorTexture,\n        material?.emissiveTexture,\n        material?.normalTexture,\n        material?.occlusionTexture,\n        material?.pbrMetallicRoughness?.metallicRoughnessTexture\n    ];\n    // Save processed texCoords in order no to process the same twice\n    const processedTexCoords = [];\n    for (const textureInfo of materialTextures) {\n        if (textureInfo && textureInfo?.extensions?.[KHR_TEXTURE_TRANSFORM]) {\n            transformPrimitives(gltfData, materialIndex, textureInfo, processedTexCoords);\n        }\n    }\n}\n/**\n * Transform primitives of the particular material\n * @param gltfData gltf data\n * @param materialIndex primitives with this material will be transformed\n * @param texture texture object\n * @param processedTexCoords storage to save already processed texCoords\n */\nfunction transformPrimitives(gltfData, materialIndex, texture, processedTexCoords) {\n    const transformParameters = getTransformParameters(texture, processedTexCoords);\n    if (!transformParameters) {\n        return;\n    }\n    const meshes = gltfData.json.meshes || [];\n    for (const mesh of meshes) {\n        for (const primitive of mesh.primitives) {\n            const material = primitive.material;\n            if (Number.isFinite(material) && materialIndex === material) {\n                transformPrimitive(gltfData, primitive, transformParameters);\n            }\n        }\n    }\n}\n/**\n * Get parameters for TEXCOORD transformation\n * @param texture texture object\n * @param processedTexCoords storage to save already processed texCoords\n * @returns texCoord couple and transformation matrix\n */\nfunction getTransformParameters(texture, processedTexCoords) {\n    const textureInfo = texture.extensions?.[KHR_TEXTURE_TRANSFORM];\n    const { texCoord: originalTexCoord = 0 } = texture;\n    // If texCoord is not set in the extension, original attribute data will be replaced\n    const { texCoord = originalTexCoord } = textureInfo;\n    // Make sure that couple [originalTexCoord, extensionTexCoord] is not processed twice\n    const isProcessed = processedTexCoords.findIndex(([original, newTexCoord]) => original === originalTexCoord && newTexCoord === texCoord) !== -1;\n    if (!isProcessed) {\n        const matrix = makeTransformationMatrix(textureInfo);\n        if (originalTexCoord !== texCoord) {\n            texture.texCoord = texCoord;\n        }\n        processedTexCoords.push([originalTexCoord, texCoord]);\n        return { originalTexCoord, texCoord, matrix };\n    }\n    return null;\n}\n/**\n * Transform `TEXCOORD_0` attribute in the primitive\n * @param gltfData gltf data\n * @param primitive primitive object\n * @param transformParameters texCoord couple and transformation matrix\n */\nfunction transformPrimitive(gltfData, primitive, transformParameters) {\n    const { originalTexCoord, texCoord, matrix } = transformParameters;\n    const texCoordAccessor = primitive.attributes[`TEXCOORD_${originalTexCoord}`];\n    if (Number.isFinite(texCoordAccessor)) {\n        // Get accessor of the `TEXCOORD_0` attribute\n        const accessor = gltfData.json.accessors?.[texCoordAccessor];\n        if (accessor && accessor.bufferView) {\n            // Get `bufferView` of the `accessor`\n            const bufferView = gltfData.json.bufferViews?.[accessor.bufferView];\n            if (bufferView) {\n                // Get `arrayBuffer` the `bufferView` look at\n                const { arrayBuffer, byteOffset: bufferByteOffset } = gltfData.buffers[bufferView.buffer];\n                // Resulting byteOffset is sum of the buffer, accessor and bufferView byte offsets\n                const byteOffset = (bufferByteOffset || 0) + (accessor.byteOffset || 0) + (bufferView.byteOffset || 0);\n                // Deduce TypedArray type and its length from `accessor` and `bufferView` data\n                const { ArrayType, length } = getAccessorArrayTypeAndLength(accessor, bufferView);\n                // Number of bytes each component occupies\n                const bytes = BYTES$1[accessor.componentType];\n                // Number of components. For the `TEXCOORD_0` with `VEC2` type, it must return 2\n                const components = COMPONENTS$1[accessor.type];\n                // Multiplier to calculate the address of the `TEXCOORD_0` element in the arrayBuffer\n                const elementAddressScale = bufferView.byteStride || bytes * components;\n                // Data transform to Float32Array\n                const result = new Float32Array(length);\n                for (let i = 0; i < accessor.count; i++) {\n                    // Take [u, v] couple from the arrayBuffer\n                    const uv = new ArrayType(arrayBuffer, byteOffset + i * elementAddressScale, 2);\n                    // Set and transform Vector3 per https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform#overview\n                    scratchVector.set(uv[0], uv[1], 1);\n                    scratchVector.transformByMatrix3(matrix);\n                    // Save result in Float32Array\n                    result.set([scratchVector[0], scratchVector[1]], i * components);\n                }\n                // If texCoord the same, replace gltf structural data\n                if (originalTexCoord === texCoord) {\n                    updateGltf(accessor, bufferView, gltfData.buffers, result);\n                }\n                else {\n                    // If texCoord change, create new attribute\n                    createAttribute(texCoord, accessor, primitive, gltfData, result);\n                }\n            }\n        }\n    }\n}\n/**\n * Update GLTF structural objects with new data as we create new `Float32Array` for `TEXCOORD_0`.\n * @param accessor accessor to change\n * @param bufferView bufferView to change\n * @param buffers binary buffers\n * @param newTexcoordArray typed array with data after transformation\n */\nfunction updateGltf(accessor, bufferView, buffers, newTexCoordArray) {\n    accessor.componentType = 5126;\n    buffers.push({\n        arrayBuffer: newTexCoordArray.buffer,\n        byteOffset: 0,\n        byteLength: newTexCoordArray.buffer.byteLength\n    });\n    bufferView.buffer = buffers.length - 1;\n    bufferView.byteLength = newTexCoordArray.buffer.byteLength;\n    bufferView.byteOffset = 0;\n    delete bufferView.byteStride;\n}\n/**\n *\n * @param newTexCoord new `texCoord` value\n * @param originalAccessor original accessor object, that store data before transformation\n * @param primitive primitive object\n * @param gltfData gltf data\n * @param newTexCoordArray typed array with data after transformation\n * @returns\n */\nfunction createAttribute(newTexCoord, originalAccessor, primitive, gltfData, newTexCoordArray) {\n    gltfData.buffers.push({\n        arrayBuffer: newTexCoordArray.buffer,\n        byteOffset: 0,\n        byteLength: newTexCoordArray.buffer.byteLength\n    });\n    const bufferViews = gltfData.json.bufferViews;\n    if (!bufferViews) {\n        return;\n    }\n    bufferViews.push({\n        buffer: gltfData.buffers.length - 1,\n        byteLength: newTexCoordArray.buffer.byteLength,\n        byteOffset: 0\n    });\n    const accessors = gltfData.json.accessors;\n    if (!accessors) {\n        return;\n    }\n    accessors.push({\n        bufferView: bufferViews?.length - 1,\n        byteOffset: 0,\n        componentType: 5126,\n        count: originalAccessor.count,\n        type: 'VEC2'\n    });\n    primitive.attributes[`TEXCOORD_${newTexCoord}`] = accessors.length - 1;\n}\n/**\n * Construct transformation matrix from the extension data (transition, rotation, scale)\n * @param extensionData extension data\n * @returns transformation matrix\n */\nfunction makeTransformationMatrix(extensionData) {\n    const { offset = [0, 0], rotation = 0, scale = [1, 1] } = extensionData;\n    const translationMatrix = new Matrix3().set(1, 0, 0, 0, 1, 0, offset[0], offset[1], 1);\n    const rotationMatrix = scratchRotationMatrix.set(Math.cos(rotation), Math.sin(rotation), 0, -Math.sin(rotation), Math.cos(rotation), 0, 0, 0, 1);\n    const scaleMatrix = scratchScaleMatrix.set(scale[0], 0, 0, 0, scale[1], 0, 0, 0, 1);\n    return translationMatrix.multiplyRight(rotationMatrix).multiplyRight(scaleMatrix);\n}\n\nvar KHR_texture_transform = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$3,\n    decode: decode$5\n});\n\n// GLTF EXTENSION: KHR_lights_punctual\nconst KHR_LIGHTS_PUNCTUAL = 'KHR_lights_punctual';\nconst name$2 = KHR_LIGHTS_PUNCTUAL;\nasync function decode$4(gltfData) {\n    const gltfScenegraph = new GLTFScenegraph(gltfData);\n    const { json } = gltfScenegraph;\n    // Move the light array out of the extension and remove the extension\n    const extension = gltfScenegraph.getExtension(KHR_LIGHTS_PUNCTUAL);\n    if (extension) {\n        // @ts-ignore\n        gltfScenegraph.json.lights = extension.lights;\n        gltfScenegraph.removeExtension(KHR_LIGHTS_PUNCTUAL);\n    }\n    // Any nodes that have the extension, add lights field pointing to light object\n    // and remove the extension\n    for (const node of json.nodes || []) {\n        const nodeExtension = gltfScenegraph.getObjectExtension(node, KHR_LIGHTS_PUNCTUAL);\n        if (nodeExtension) {\n            // @ts-ignore\n            node.light = nodeExtension.light;\n        }\n        gltfScenegraph.removeObjectExtension(node, KHR_LIGHTS_PUNCTUAL);\n    }\n}\n// Move the light ar ray out of the extension and remove the extension\nasync function encode$2(gltfData) {\n    const gltfScenegraph = new GLTFScenegraph(gltfData);\n    const { json } = gltfScenegraph;\n    // @ts-ignore\n    if (json.lights) {\n        const extension = gltfScenegraph.addExtension(KHR_LIGHTS_PUNCTUAL);\n        // @ts-ignore\n        assert$1(!extension.lights);\n        // @ts-ignore\n        extension.lights = json.lights;\n        // @ts-ignore\n        delete json.lights;\n    }\n    // Any nodes that have lights field pointing to light object\n    // add the extension\n    // @ts-ignore\n    if (gltfScenegraph.json.lights) {\n        // @ts-ignore\n        for (const light of gltfScenegraph.json.lights) {\n            const node = light.node;\n            gltfScenegraph.addObjectExtension(node, KHR_LIGHTS_PUNCTUAL, light);\n        }\n        // @ts-ignore\n        delete gltfScenegraph.json.lights;\n    }\n}\n\nvar KHR_lights_punctual = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$2,\n    decode: decode$4,\n    encode: encode$2\n});\n\n// GLTF EXTENSION: KHR_materials_unlit\nconst KHR_MATERIALS_UNLIT = 'KHR_materials_unlit';\nconst name$1 = KHR_MATERIALS_UNLIT;\nasync function decode$3(gltfData) {\n    const gltfScenegraph = new GLTFScenegraph(gltfData);\n    const { json } = gltfScenegraph;\n    // Any nodes that have the extension, add lights field pointing to light object\n    // and remove the extension\n    for (const material of json.materials || []) {\n        const extension = material.extensions && material.extensions.KHR_materials_unlit;\n        if (extension) {\n            // @ts-ignore TODO\n            material.unlit = true;\n        }\n        gltfScenegraph.removeObjectExtension(material, KHR_MATERIALS_UNLIT);\n    }\n    // Remove the top-level extension\n    gltfScenegraph.removeExtension(KHR_MATERIALS_UNLIT);\n}\nfunction encode$1(gltfData) {\n    const gltfScenegraph = new GLTFScenegraph(gltfData);\n    const { json } = gltfScenegraph;\n    // Any nodes that have lights field pointing to light object\n    // add the extension\n    // @ts-ignore\n    if (gltfScenegraph.materials) {\n        for (const material of json.materials || []) {\n            // @ts-ignore\n            if (material.unlit) {\n                // @ts-ignore\n                delete material.unlit;\n                gltfScenegraph.addObjectExtension(material, KHR_MATERIALS_UNLIT, {});\n                gltfScenegraph.addExtension(KHR_MATERIALS_UNLIT);\n            }\n        }\n    }\n}\n\nvar KHR_materials_unlit = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$1,\n    decode: decode$3,\n    encode: encode$1\n});\n\n// GLTF EXTENSION: KHR_techniques_webgl\nconst KHR_TECHNIQUES_WEBGL = 'KHR_techniques_webgl';\nconst name = KHR_TECHNIQUES_WEBGL;\nasync function decode$2(gltfData) {\n    const gltfScenegraph = new GLTFScenegraph(gltfData);\n    const { json } = gltfScenegraph;\n    const extension = gltfScenegraph.getExtension(KHR_TECHNIQUES_WEBGL);\n    if (extension) {\n        const techniques = resolveTechniques(extension, gltfScenegraph);\n        for (const material of json.materials || []) {\n            const materialExtension = gltfScenegraph.getObjectExtension(material, KHR_TECHNIQUES_WEBGL);\n            if (materialExtension) {\n                // @ts-ignore TODO\n                material.technique = Object.assign({}, materialExtension, \n                // @ts-ignore\n                techniques[materialExtension.technique]);\n                // @ts-ignore TODO\n                material.technique.values = resolveValues(material.technique, gltfScenegraph);\n            }\n            gltfScenegraph.removeObjectExtension(material, KHR_TECHNIQUES_WEBGL);\n        }\n        // Remove the top-level extension\n        gltfScenegraph.removeExtension(KHR_TECHNIQUES_WEBGL);\n    }\n}\n// eslint-disable-next-line\nasync function encode(gltfData, options) {\n    // TODO\n}\nfunction resolveTechniques(techniquesExtension, \n// programs: {[key: string]: any}[],\n// shaders: {[key: string]: any}[],\n// techniques: {[key: string]: any}[]\ngltfScenegraph) {\n    const { programs = [], shaders = [], techniques = [] } = techniquesExtension;\n    const textDecoder = new TextDecoder();\n    shaders.forEach((shader) => {\n        if (Number.isFinite(shader.bufferView)) {\n            shader.code = textDecoder.decode(gltfScenegraph.getTypedArrayForBufferView(shader.bufferView));\n        }\n        else {\n            // TODO: handle URI shader\n            throw new Error('KHR_techniques_webgl: no shader code');\n        }\n    });\n    programs.forEach((program) => {\n        program.fragmentShader = shaders[program.fragmentShader];\n        program.vertexShader = shaders[program.vertexShader];\n    });\n    techniques.forEach((technique) => {\n        technique.program = programs[technique.program];\n    });\n    return techniques;\n}\nfunction resolveValues(technique, gltfScenegraph) {\n    const values = Object.assign({}, technique.values);\n    // merge values from uniforms\n    Object.keys(technique.uniforms || {}).forEach((uniform) => {\n        if (technique.uniforms[uniform].value && !(uniform in values)) {\n            values[uniform] = technique.uniforms[uniform].value;\n        }\n    });\n    // resolve textures\n    Object.keys(values).forEach((uniform) => {\n        if (typeof values[uniform] === 'object' && values[uniform].index !== undefined) {\n            // Assume this is a texture\n            // TODO: find if there are any other types that can be referenced\n            values[uniform].texture = gltfScenegraph.getTexture(values[uniform].index);\n        }\n    });\n    return values;\n}\n\nvar KHR_techniques_webgl = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name,\n    decode: decode$2,\n    encode: encode\n});\n\n// GLTF 1.0 extensions (decode only)\n/**\n * List of extensions processed by the GLTFLoader\n * Note that may extensions can only be handled on the rendering stage and are left out here\n * These are just extensions that can be handled fully or partially during loading.\n */\nconst EXTENSIONS = [\n    // 1.0\n    // KHR_binary_gltf is handled separately - must be processed before other parsing starts\n    // KHR_binary_gltf,\n    // 2.0\n    EXT_structural_metadata,\n    EXT_mesh_features,\n    EXT_meshopt_compression,\n    EXT_texture_webp,\n    // Basisu should come after webp, we want basisu to be preferred if both are provided\n    KHR_texture_basisu,\n    KHR_draco_mesh_compression,\n    KHR_lights_punctual,\n    KHR_materials_unlit,\n    KHR_techniques_webgl,\n    KHR_texture_transform,\n    EXT_feature_metadata\n];\n/** Call before any resource loading starts */\nfunction preprocessExtensions(gltf, options = {}, context) {\n    const extensions = EXTENSIONS.filter((extension) => useExtension(extension.name, options));\n    for (const extension of extensions) {\n        extension.preprocess?.(gltf, options, context);\n    }\n}\n/** Call after resource loading */\nasync function decodeExtensions(gltf, options = {}, context) {\n    const extensions = EXTENSIONS.filter((extension) => useExtension(extension.name, options));\n    for (const extension of extensions) {\n        // Note: We decode async extensions sequentially, this might not be necessary\n        // Currently we only have Draco, but when we add Basis we may revisit\n        await extension.decode?.(gltf, options, context);\n    }\n}\nfunction useExtension(extensionName, options) {\n    const excludes = options?.gltf?.excludeExtensions || {};\n    const exclude = extensionName in excludes && !excludes[extensionName];\n    return !exclude;\n}\n\n// GLTF 1.0 EXTENSION: KHR_binary_glTF\nconst KHR_BINARY_GLTF = 'KHR_binary_glTF';\nfunction preprocess(gltfData) {\n    const gltfScenegraph = new GLTFScenegraph(gltfData);\n    const { json } = gltfScenegraph;\n    // Note: json.buffers.binary_glTF also needs to be replaced\n    // This is currently done during gltf normalization\n    // Image and shader nodes can have the extension\n    // https://github.com/KhronosGroup/glTF/blob/master/extensions/1.0/Khronos/KHR_binary_glTF/schema/image.KHR_binary_glTF.schema.json\n    for (const image of json.images || []) {\n        const extension = gltfScenegraph.getObjectExtension(image, KHR_BINARY_GLTF);\n        // The data in the extension is valid as glTF 2.0 data inside the object, so just copy it in\n        if (extension) {\n            Object.assign(image, extension);\n        }\n        gltfScenegraph.removeObjectExtension(image, KHR_BINARY_GLTF);\n    }\n    // TODO shaders - At least traverse and throw error if used?\n    // https://github.com/KhronosGroup/glTF/blob/master/extensions/1.0/Khronos/KHR_binary_glTF/schema/shader.KHR_binary_glTF.schema.json\n    // glTF v1 one files have a partially formed URI field that is not expected in (and causes problems in) 2.0\n    if (json.buffers && json.buffers[0]) {\n        delete json.buffers[0].uri;\n    }\n    // Remove the top-level extension as it has now been processed\n    gltfScenegraph.removeExtension(KHR_BINARY_GLTF);\n}\n// KHR_binary_gltf is a 1.0 extension that is supported natively by 2.0\n// export function encode() {\n//   throw new Error(KHR_BINARY_GLTF);\n// }\n\n/* eslint-disable camelcase */\n// Binary format changes (mainly implemented by GLBLoader)\n// https://github.com/KhronosGroup/glTF/tree/master/extensions/1.0/Khronos/KHR_binary_glTF\n// JSON format changes:\n// https://github.com/khronosgroup/gltf/issues/605\n// - [x] Top-level JSON objects are arrays now\n// - [ ] Removed indirection from animation: sampler now refers directly to accessors, #712\n// - [ ] material.parameter.value and technique.parameter.value must be an array, #690\n// - [ ] Node can have only one mesh #821\n// - [ ] Added reqs on JSON encoding\n// - [ ] Added reqs on binary data alignment #802 (comment)\n// Additions:\n// - [ ] Added accessor.normalized, #691, #706\n// - [ ] Added glExtensionsUsed property and 5125 (UNSIGNED_INT) accessor.componentType value, #619\n// - [ ] Added extensionsRequired property, #720, #721\n// - [ ] Added \"STEP\" as valid animation.sampler.interpolation value, #712\n// Removals:\n// - [x] Removed buffer.type, #786, #629\n// - [ ] Removed revision number from profile.version, #709\n// - [ ] Removed technique.functions.scissor and removed 3089 (SCISSOR_TEST) as a valid value for technique.states.enable, #681\n// - [ ] Techniques, programs, and shaders were moved out to KHR_technique_webgl extension.\n// Other edits:\n// - [x] asset is now required, #642\n// - [ ] buffer.byteLength and bufferView.byteLength are now required, #560.\n// - [ ] accessor.min and accessor.max are now required, #593, and clarified that the JSON value and binary data must be the same, #628.\n// - [ ] Clarified animation.sampler and animation.channel restrictions, #712\n// - [ ] skin.inverseBindMatrices is now optional, #461.\n// - [ ] Attribute parameters can't have a value defined in the technique or parameter, #563 (comment).\n// - [ ] Only TEXCOORD and COLOR attribute semantics can be written in the form [semantic]_[set_index], #563 (comment).\n// - [ ] TEXCOORD and COLOR attribute semantics must be written in the form [semantic]_[set_index], e.g., just TEXCOORD should be TEXCOORD_0, and just COLOR should be COLOR_0, #649\n// - [ ] camera.perspective.aspectRatio and camera.perspective.yfov must now be > 0, not >= 0, #563 (comment).\n// - [ ] Application-specific parameter semantics must start with an underscore, e.g., _TEMPERATURE and _SIMULATION_TIME, #563 (comment).\n// - [ ] Properties in technique.parameters must be defined in technique.uniforms or technique.attributes,\n// #563 (comment).\n// - [ ] technique.parameter.count can only be defined when the semantic is JOINTMATRIX or an application-specific semantic is used. It can never be defined for attribute parameters; only uniforms, d2f6945\n// - [ ] technique.parameter.semantic is required when the parameter is an attribute, 28e113d\n// - [ ] Mesh-only models are allowed, e.g., without materials, #642\n// - [ ] Skeleton hierarchies (nodes containing jointName) must be separated from non-skeleton hierarchies., #647\n// - [ ] technique.states.functions.blendColor and technique.states.functions.depthRange parameters now must match WebGL function min/max, #707\nconst GLTF_ARRAYS = {\n    accessors: 'accessor',\n    animations: 'animation',\n    buffers: 'buffer',\n    bufferViews: 'bufferView',\n    images: 'image',\n    materials: 'material',\n    meshes: 'mesh',\n    nodes: 'node',\n    samplers: 'sampler',\n    scenes: 'scene',\n    skins: 'skin',\n    textures: 'texture'\n};\nconst GLTF_KEYS = {\n    accessor: 'accessors',\n    animations: 'animation',\n    buffer: 'buffers',\n    bufferView: 'bufferViews',\n    image: 'images',\n    material: 'materials',\n    mesh: 'meshes',\n    node: 'nodes',\n    sampler: 'samplers',\n    scene: 'scenes',\n    skin: 'skins',\n    texture: 'textures'\n};\n/**\n * Converts (normalizes) glTF v1 to v2\n */\nclass GLTFV1Normalizer {\n    idToIndexMap = {\n        animations: {},\n        accessors: {},\n        buffers: {},\n        bufferViews: {},\n        images: {},\n        materials: {},\n        meshes: {},\n        nodes: {},\n        samplers: {},\n        scenes: {},\n        skins: {},\n        textures: {}\n    };\n    json;\n    // constructor() {}\n    /**\n     * Convert (normalize) glTF < 2.0 to glTF 2.0\n     * @param gltf - object with json and binChunks\n     * @param options\n     * @param options normalize Whether to actually normalize\n     */\n    normalize(gltf, options) {\n        this.json = gltf.json;\n        const json = gltf.json;\n        // Check version\n        switch (json.asset && json.asset.version) {\n            // We are converting to v2 format. Return if there is nothing to do\n            case '2.0':\n                return;\n            // This class is written to convert 1.0\n            case undefined:\n            case '1.0':\n                break;\n            default:\n                // eslint-disable-next-line no-undef, no-console\n                console.warn(`glTF: Unknown version ${json.asset.version}`);\n                return;\n        }\n        if (!options.normalize) {\n            // We are still missing a few conversion tricks, remove once addressed\n            throw new Error('glTF v1 is not supported.');\n        }\n        // eslint-disable-next-line no-undef, no-console\n        console.warn('Converting glTF v1 to glTF v2 format. This is experimental and may fail.');\n        this._addAsset(json);\n        // In glTF2 top-level fields are Arrays not Object maps\n        this._convertTopLevelObjectsToArrays(json);\n        // Extract bufferView indices for images\n        // (this extension needs to be invoked early in the normalization process)\n        // TODO can this be handled by standard extension processing instead of called explicitly?\n        preprocess(gltf);\n        // Convert object references from ids to indices\n        this._convertObjectIdsToArrayIndices(json);\n        this._updateObjects(json);\n        this._updateMaterial(json);\n    }\n    // asset is now required, #642 https://github.com/KhronosGroup/glTF/issues/639\n    _addAsset(json) {\n        json.asset = json.asset || {};\n        // We are normalizing to glTF v2, so change version to \"2.0\"\n        json.asset.version = '2.0';\n        json.asset.generator = json.asset.generator || 'Normalized to glTF 2.0 by loaders.gl';\n    }\n    _convertTopLevelObjectsToArrays(json) {\n        // TODO check that all arrays are covered\n        for (const arrayName in GLTF_ARRAYS) {\n            this._convertTopLevelObjectToArray(json, arrayName);\n        }\n    }\n    /** Convert one top level object to array */\n    _convertTopLevelObjectToArray(json, mapName) {\n        const objectMap = json[mapName];\n        if (!objectMap || Array.isArray(objectMap)) {\n            return;\n        }\n        // Rewrite the top-level field as an array\n        json[mapName] = [];\n        // Copy the map key into object.id\n        for (const id in objectMap) {\n            const object = objectMap[id];\n            object.id = object.id || id; // Mutates the loaded object\n            const index = json[mapName].length;\n            json[mapName].push(object);\n            this.idToIndexMap[mapName][id] = index;\n        }\n    }\n    /** Go through all objects in all top-level arrays and replace ids with indices */\n    _convertObjectIdsToArrayIndices(json) {\n        for (const arrayName in GLTF_ARRAYS) {\n            this._convertIdsToIndices(json, arrayName);\n        }\n        if ('scene' in json) {\n            json.scene = this._convertIdToIndex(json.scene, 'scene');\n        }\n        // Convert any index references that are not using array names\n        // texture.source (image)\n        for (const texture of json.textures) {\n            this._convertTextureIds(texture);\n        }\n        for (const mesh of json.meshes) {\n            this._convertMeshIds(mesh);\n        }\n        for (const node of json.nodes) {\n            this._convertNodeIds(node);\n        }\n        for (const node of json.scenes) {\n            this._convertSceneIds(node);\n        }\n    }\n    _convertTextureIds(texture) {\n        if (texture.source) {\n            texture.source = this._convertIdToIndex(texture.source, 'image');\n        }\n    }\n    _convertMeshIds(mesh) {\n        for (const primitive of mesh.primitives) {\n            const { attributes, indices, material } = primitive;\n            for (const attributeName in attributes) {\n                attributes[attributeName] = this._convertIdToIndex(attributes[attributeName], 'accessor');\n            }\n            if (indices) {\n                primitive.indices = this._convertIdToIndex(indices, 'accessor');\n            }\n            if (material) {\n                primitive.material = this._convertIdToIndex(material, 'material');\n            }\n        }\n    }\n    _convertNodeIds(node) {\n        if (node.children) {\n            node.children = node.children.map((child) => this._convertIdToIndex(child, 'node'));\n        }\n        if (node.meshes) {\n            node.meshes = node.meshes.map((mesh) => this._convertIdToIndex(mesh, 'mesh'));\n        }\n    }\n    _convertSceneIds(scene) {\n        if (scene.nodes) {\n            scene.nodes = scene.nodes.map((node) => this._convertIdToIndex(node, 'node'));\n        }\n    }\n    /** Go through all objects in a top-level array and replace ids with indices */\n    _convertIdsToIndices(json, topLevelArrayName) {\n        if (!json[topLevelArrayName]) {\n            console.warn(`gltf v1: json doesn't contain attribute ${topLevelArrayName}`); // eslint-disable-line no-console, no-undef\n            json[topLevelArrayName] = [];\n        }\n        for (const object of json[topLevelArrayName]) {\n            for (const key in object) {\n                const id = object[key];\n                const index = this._convertIdToIndex(id, key);\n                object[key] = index;\n            }\n        }\n    }\n    _convertIdToIndex(id, key) {\n        const arrayName = GLTF_KEYS[key];\n        if (arrayName in this.idToIndexMap) {\n            const index = this.idToIndexMap[arrayName][id];\n            if (!Number.isFinite(index)) {\n                throw new Error(`gltf v1: failed to resolve ${key} with id ${id}`);\n            }\n            return index;\n        }\n        return id;\n    }\n    /**\n     *\n     * @param {*} json\n     */\n    _updateObjects(json) {\n        for (const buffer of this.json.buffers) {\n            // - [x] Removed buffer.type, #786, #629\n            delete buffer.type;\n        }\n    }\n    /**\n     * Update material (set pbrMetallicRoughness)\n     * @param {*} json\n     */\n    _updateMaterial(json) {\n        for (const material of json.materials) {\n            material.pbrMetallicRoughness = {\n                baseColorFactor: [1, 1, 1, 1],\n                metallicFactor: 1,\n                roughnessFactor: 1\n            };\n            const textureId = material.values?.tex || material.values?.texture2d_0 || material.values?.diffuseTex;\n            const textureIndex = json.textures.findIndex((texture) => texture.id === textureId);\n            if (textureIndex !== -1) {\n                material.pbrMetallicRoughness.baseColorTexture = { index: textureIndex };\n            }\n        }\n    }\n}\nfunction normalizeGLTFV1(gltf, options = {}) {\n    return new GLTFV1Normalizer().normalize(gltf, options);\n}\n\nasync function parseGLTF$1(gltf, arrayBufferOrString, byteOffset = 0, options, context) {\n    parseGLTFContainerSync(gltf, arrayBufferOrString, byteOffset, options);\n    normalizeGLTFV1(gltf, { normalize: options?.gltf?.normalize });\n    preprocessExtensions(gltf, options, context);\n    // Load linked buffers asynchronously and decodes base64 buffers in parallel\n    if (options?.gltf?.loadBuffers && gltf.json.buffers) {\n        await loadBuffers(gltf, options, context);\n    }\n    // loadImages and decodeExtensions should not be running in parallel, because\n    // decodeExtensions uses data from images taken during the loadImages call.\n    if (options?.gltf?.loadImages) {\n        await loadImages(gltf, options, context);\n    }\n    await decodeExtensions(gltf, options, context);\n    return gltf;\n}\n/**\n *\n * @param gltf\n * @param data - can be ArrayBuffer (GLB), ArrayBuffer (Binary JSON), String (JSON), or Object (parsed JSON)\n * @param byteOffset\n * @param options\n */\nfunction parseGLTFContainerSync(gltf, data, byteOffset, options) {\n    // Initialize gltf container\n    if (options.uri) {\n        gltf.baseUri = options.uri;\n    }\n    // If data is binary and starting with magic bytes, assume binary JSON text, convert to string\n    if (data instanceof ArrayBuffer && !isGLB(data, byteOffset, options)) {\n        const textDecoder = new TextDecoder();\n        data = textDecoder.decode(data);\n    }\n    if (typeof data === 'string') {\n        // If string, try to parse as JSON\n        gltf.json = parseJSON(data);\n    }\n    else if (data instanceof ArrayBuffer) {\n        // If still ArrayBuffer, parse as GLB container\n        const glb = {};\n        byteOffset = parseGLBSync(glb, data, byteOffset, options.glb);\n        assert$1(glb.type === 'glTF', `Invalid GLB magic string ${glb.type}`);\n        gltf._glb = glb;\n        gltf.json = glb.json;\n    }\n    else {\n        assert$1(false, 'GLTF: must be ArrayBuffer or string');\n    }\n    // Populate buffers\n    // Create an external buffers array to hold binary data\n    const buffers = gltf.json.buffers || [];\n    gltf.buffers = new Array(buffers.length).fill(null);\n    // Populates JSON and some bin chunk info\n    if (gltf._glb && gltf._glb.header.hasBinChunk) {\n        const { binChunks } = gltf._glb;\n        gltf.buffers[0] = {\n            arrayBuffer: binChunks[0].arrayBuffer,\n            byteOffset: binChunks[0].byteOffset,\n            byteLength: binChunks[0].byteLength\n        };\n        // TODO - this modifies JSON and is a post processing thing\n        // gltf.json.buffers[0].data = gltf.buffers[0].arrayBuffer;\n        // gltf.json.buffers[0].byteOffset = gltf.buffers[0].byteOffset;\n    }\n    // Populate images\n    const images = gltf.json.images || [];\n    gltf.images = new Array(images.length).fill({});\n}\n/** Asynchronously fetch and parse buffers, store in buffers array outside of json\n * TODO - traverse gltf and determine which buffers are actually needed\n */\nasync function loadBuffers(gltf, options, context) {\n    // TODO\n    const buffers = gltf.json.buffers || [];\n    for (let i = 0; i < buffers.length; ++i) {\n        const buffer = buffers[i];\n        if (buffer.uri) {\n            const { fetch } = context;\n            assert$1(fetch);\n            const uri = resolveUrl(buffer.uri, options);\n            const response = await context?.fetch?.(uri);\n            const arrayBuffer = await response?.arrayBuffer?.();\n            gltf.buffers[i] = {\n                arrayBuffer,\n                byteOffset: 0,\n                byteLength: arrayBuffer.byteLength\n            };\n            delete buffer.uri;\n        }\n        else if (gltf.buffers[i] === null) {\n            gltf.buffers[i] = {\n                arrayBuffer: new ArrayBuffer(buffer.byteLength),\n                byteOffset: 0,\n                byteLength: buffer.byteLength\n            };\n        }\n    }\n}\n/**\n * Loads all images\n * TODO - traverse gltf and determine which images are actually needed\n * @param gltf\n * @param options\n * @param context\n * @returns\n */\nasync function loadImages(gltf, options, context) {\n    const imageIndices = getReferencesImageIndices(gltf);\n    const images = gltf.json.images || [];\n    const promises = [];\n    for (const imageIndex of imageIndices) {\n        promises.push(loadImage(gltf, images[imageIndex], imageIndex, options, context));\n    }\n    return await Promise.all(promises);\n}\n/** Make sure we only load images that are actually referenced by textures */\nfunction getReferencesImageIndices(gltf) {\n    const imageIndices = new Set();\n    const textures = gltf.json.textures || [];\n    for (const texture of textures) {\n        if (texture.source !== undefined) {\n            imageIndices.add(texture.source);\n        }\n    }\n    return Array.from(imageIndices).sort();\n}\n/** Asynchronously fetches and parses one image, store in images array outside of json */\nasync function loadImage(gltf, image, index, options, context) {\n    let arrayBuffer;\n    if (image.uri && !image.hasOwnProperty('bufferView')) {\n        const uri = resolveUrl(image.uri, options);\n        const { fetch } = context;\n        const response = await fetch(uri);\n        arrayBuffer = await response.arrayBuffer();\n        image.bufferView = {\n            data: arrayBuffer\n        };\n    }\n    if (Number.isFinite(image.bufferView)) {\n        const array = getTypedArrayForBufferView(gltf.json, gltf.buffers, image.bufferView);\n        arrayBuffer = sliceArrayBuffer(array.buffer, array.byteOffset, array.byteLength);\n    }\n    assert$1(arrayBuffer, 'glTF image has no data');\n    // Call `parse`\n    let parsedImage = (await parseFromContext(arrayBuffer, [ImageLoader, BasisLoader], {\n        ...options,\n        mimeType: image.mimeType,\n        basis: options.basis || { format: selectSupportedBasisFormat() }\n    }, context));\n    if (parsedImage && parsedImage[0]) {\n        parsedImage = {\n            compressed: true,\n            // @ts-expect-error\n            mipmaps: false,\n            width: parsedImage[0].width,\n            height: parsedImage[0].height,\n            data: parsedImage[0]\n        };\n    }\n    // TODO making sure ImageLoader is overridable by using array of loaders\n    // const parsedImage = await parse(arrayBuffer, [ImageLoader]);\n    // Store the loaded image\n    gltf.images = gltf.images || [];\n    // @ts-expect-error TODO - sort out image typing asap\n    gltf.images[index] = parsedImage;\n}\n\n/**\n * GLTF loader\n */\nconst GLTFLoader = {\n    dataType: null,\n    batchType: null,\n    name: 'glTF',\n    id: 'gltf',\n    module: 'gltf',\n    version: VERSION$3,\n    extensions: ['gltf', 'glb'],\n    mimeTypes: ['model/gltf+json', 'model/gltf-binary'],\n    text: true,\n    binary: true,\n    tests: ['glTF'],\n    parse: parse$2,\n    options: {\n        gltf: {\n            normalize: true, // Normalize glTF v1 to glTF v2 format (not yet stable)\n            loadBuffers: true, // Fetch any linked .BIN buffers, decode base64\n            loadImages: true, // Create image objects\n            decompressMeshes: true // Decompress Draco encoded meshes\n        },\n        // common?\n        log: console // eslint-disable-line\n    }\n};\nasync function parse$2(arrayBuffer, options = {}, context) {\n    // Apps can call the parse method directly, we so apply default options here\n    options = { ...GLTFLoader.options, ...options };\n    // @ts-ignore\n    options.gltf = { ...GLTFLoader.options.gltf, ...options.gltf };\n    const { byteOffset = 0 } = options;\n    const gltf = {};\n    return await parseGLTF$1(gltf, arrayBuffer, byteOffset, options, context);\n}\n\n// loaders.gl\n// This is a post processor for loaded glTF files\n// The goal is to make the loaded data easier to use in WebGL applications\n//\n// Functions:\n// * Resolve indexed arrays structure of glTF into a linked tree.\n// * Translate stringified enum keys and values into WebGL constants.\n// * Load images (optional)\n// ENUM LOOKUP\nconst COMPONENTS = {\n    SCALAR: 1,\n    VEC2: 2,\n    VEC3: 3,\n    VEC4: 4,\n    MAT2: 4,\n    MAT3: 9,\n    MAT4: 16\n};\nconst BYTES = {\n    5120: 1, // BYTE\n    5121: 1, // UNSIGNED_BYTE\n    5122: 2, // SHORT\n    5123: 2, // UNSIGNED_SHORT\n    5125: 4, // UNSIGNED_INT\n    5126: 4 // FLOAT\n};\nconst GL_SAMPLER = {\n    // Sampler parameters\n    TEXTURE_MAG_FILTER: 0x2800,\n    TEXTURE_MIN_FILTER: 0x2801,\n    TEXTURE_WRAP_S: 0x2802,\n    TEXTURE_WRAP_T: 0x2803,\n    // Sampler default values\n    REPEAT: 0x2901,\n    LINEAR: 0x2601,\n    NEAREST_MIPMAP_LINEAR: 0x2702\n};\nconst SAMPLER_PARAMETER_GLTF_TO_GL = {\n    magFilter: GL_SAMPLER.TEXTURE_MAG_FILTER,\n    minFilter: GL_SAMPLER.TEXTURE_MIN_FILTER,\n    wrapS: GL_SAMPLER.TEXTURE_WRAP_S,\n    wrapT: GL_SAMPLER.TEXTURE_WRAP_T\n};\n// When undefined, a sampler with repeat wrapping and auto filtering should be used.\n// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#texture\nconst DEFAULT_SAMPLER_PARAMETERS = {\n    [GL_SAMPLER.TEXTURE_MAG_FILTER]: GL_SAMPLER.LINEAR,\n    [GL_SAMPLER.TEXTURE_MIN_FILTER]: GL_SAMPLER.NEAREST_MIPMAP_LINEAR,\n    [GL_SAMPLER.TEXTURE_WRAP_S]: GL_SAMPLER.REPEAT,\n    [GL_SAMPLER.TEXTURE_WRAP_T]: GL_SAMPLER.REPEAT\n};\nfunction makeDefaultSampler() {\n    return {\n        id: 'default-sampler',\n        parameters: DEFAULT_SAMPLER_PARAMETERS\n    };\n}\nfunction getBytesFromComponentType(componentType) {\n    return BYTES[componentType];\n}\nfunction getSizeFromAccessorType(type) {\n    return COMPONENTS[type];\n}\nclass GLTFPostProcessor {\n    baseUri = '';\n    // @ts-expect-error\n    jsonUnprocessed;\n    // @ts-expect-error\n    json;\n    buffers = [];\n    images = [];\n    postProcess(gltf, options = {}) {\n        const { json, buffers = [], images = [] } = gltf;\n        // @ts-expect-error\n        const { baseUri = '' } = gltf;\n        assert$1(json);\n        this.baseUri = baseUri;\n        this.buffers = buffers;\n        this.images = images;\n        this.jsonUnprocessed = json;\n        this.json = this._resolveTree(gltf.json, options);\n        return this.json;\n    }\n    // Convert indexed glTF structure into tree structure\n    // cross-link index resolution, enum lookup, convenience calculations\n    // eslint-disable-next-line complexity, max-statements\n    _resolveTree(gltf, options = {}) {\n        // @ts-expect-error\n        const json = { ...gltf };\n        this.json = json;\n        if (gltf.bufferViews) {\n            json.bufferViews = gltf.bufferViews.map((bufView, i) => this._resolveBufferView(bufView, i));\n        }\n        if (gltf.images) {\n            json.images = gltf.images.map((image, i) => this._resolveImage(image, i));\n        }\n        if (gltf.samplers) {\n            json.samplers = gltf.samplers.map((sampler, i) => this._resolveSampler(sampler, i));\n        }\n        if (gltf.textures) {\n            json.textures = gltf.textures.map((texture, i) => this._resolveTexture(texture, i));\n        }\n        if (gltf.accessors) {\n            json.accessors = gltf.accessors.map((accessor, i) => this._resolveAccessor(accessor, i));\n        }\n        if (gltf.materials) {\n            json.materials = gltf.materials.map((material, i) => this._resolveMaterial(material, i));\n        }\n        if (gltf.meshes) {\n            json.meshes = gltf.meshes.map((mesh, i) => this._resolveMesh(mesh, i));\n        }\n        if (gltf.nodes) {\n            json.nodes = gltf.nodes.map((node, i) => this._resolveNode(node, i));\n            json.nodes = json.nodes.map((node, i) => this._resolveNodeChildren(node));\n        }\n        if (gltf.skins) {\n            json.skins = gltf.skins.map((skin, i) => this._resolveSkin(skin, i));\n        }\n        if (gltf.scenes) {\n            json.scenes = gltf.scenes.map((scene, i) => this._resolveScene(scene, i));\n        }\n        if (typeof this.json.scene === 'number' && json.scenes) {\n            json.scene = json.scenes[this.json.scene];\n        }\n        return json;\n    }\n    getScene(index) {\n        return this._get(this.json.scenes, index);\n    }\n    getNode(index) {\n        return this._get(this.json.nodes, index);\n    }\n    getSkin(index) {\n        return this._get(this.json.skins, index);\n    }\n    getMesh(index) {\n        return this._get(this.json.meshes, index);\n    }\n    getMaterial(index) {\n        return this._get(this.json.materials, index);\n    }\n    getAccessor(index) {\n        return this._get(this.json.accessors, index);\n    }\n    getCamera(index) {\n        return this._get(this.json.cameras, index);\n    }\n    getTexture(index) {\n        return this._get(this.json.textures, index);\n    }\n    getSampler(index) {\n        return this._get(this.json.samplers, index);\n    }\n    getImage(index) {\n        return this._get(this.json.images, index);\n    }\n    getBufferView(index) {\n        return this._get(this.json.bufferViews, index);\n    }\n    getBuffer(index) {\n        return this._get(this.json.buffers, index);\n    }\n    _get(array, index) {\n        // check if already resolved\n        if (typeof index === 'object') {\n            return index;\n        }\n        const object = array && array[index];\n        if (!object) {\n            console.warn(`glTF file error: Could not find ${array}[${index}]`); // eslint-disable-line\n        }\n        return object;\n    }\n    // PARSING HELPERS\n    _resolveScene(scene, index) {\n        return {\n            ...scene,\n            // @ts-ignore\n            id: scene.id || `scene-${index}`,\n            nodes: (scene.nodes || []).map((node) => this.getNode(node))\n        };\n    }\n    _resolveNode(gltfNode, index) {\n        // @ts-expect-error\n        const node = {\n            ...gltfNode,\n            // @ts-expect-error id could already be present, glTF standard does not prevent it\n            id: gltfNode?.id || `node-${index}`\n        };\n        if (gltfNode.mesh !== undefined) {\n            node.mesh = this.getMesh(gltfNode.mesh);\n        }\n        if (gltfNode.camera !== undefined) {\n            node.camera = this.getCamera(gltfNode.camera);\n        }\n        if (gltfNode.skin !== undefined) {\n            node.skin = this.getSkin(gltfNode.skin);\n        }\n        // TODO deprecated - Delete in v4.0?\n        // @ts-expect-error node.meshes does not seem to be part of the GLTF standard\n        if (gltfNode.meshes !== undefined && gltfNode.meshes.length) {\n            // @ts-expect-error\n            node.mesh = gltfNode.meshes.reduce((accum, meshIndex) => {\n                const mesh = this.getMesh(meshIndex);\n                accum.id = mesh.id;\n                accum.primitives = accum.primitives.concat(mesh.primitives);\n                return accum;\n            }, { primitives: [] });\n        }\n        return node;\n    }\n    _resolveNodeChildren(node) {\n        if (node.children) {\n            // @ts-expect-error node.children are numbers at this stage\n            node.children = node.children.map((child) => this.getNode(child));\n        }\n        return node;\n    }\n    _resolveSkin(gltfSkin, index) {\n        const inverseBindMatrices = typeof gltfSkin.inverseBindMatrices === 'number'\n            ? this.getAccessor(gltfSkin.inverseBindMatrices)\n            : undefined;\n        return {\n            ...gltfSkin,\n            id: gltfSkin.id || `skin-${index}`,\n            inverseBindMatrices\n        };\n    }\n    _resolveMesh(gltfMesh, index) {\n        const mesh = {\n            ...gltfMesh,\n            id: gltfMesh.id || `mesh-${index}`,\n            primitives: []\n        };\n        if (gltfMesh.primitives) {\n            mesh.primitives = gltfMesh.primitives.map((gltfPrimitive) => {\n                const primitive = {\n                    ...gltfPrimitive,\n                    attributes: {},\n                    indices: undefined,\n                    material: undefined\n                };\n                const attributes = gltfPrimitive.attributes;\n                for (const attribute in attributes) {\n                    primitive.attributes[attribute] = this.getAccessor(attributes[attribute]);\n                }\n                if (gltfPrimitive.indices !== undefined) {\n                    primitive.indices = this.getAccessor(gltfPrimitive.indices);\n                }\n                if (gltfPrimitive.material !== undefined) {\n                    primitive.material = this.getMaterial(gltfPrimitive.material);\n                }\n                return primitive;\n            });\n        }\n        return mesh;\n    }\n    _resolveMaterial(gltfMaterial, index) {\n        // @ts-expect-error\n        const material = {\n            ...gltfMaterial,\n            // @ts-expect-error\n            id: gltfMaterial.id || `material-${index}`\n        };\n        if (material.normalTexture) {\n            material.normalTexture = { ...material.normalTexture };\n            material.normalTexture.texture = this.getTexture(material.normalTexture.index);\n        }\n        if (material.occlusionTexture) {\n            material.occlusionTexture = { ...material.occlusionTexture };\n            material.occlusionTexture.texture = this.getTexture(material.occlusionTexture.index);\n        }\n        if (material.emissiveTexture) {\n            material.emissiveTexture = { ...material.emissiveTexture };\n            material.emissiveTexture.texture = this.getTexture(material.emissiveTexture.index);\n        }\n        if (!material.emissiveFactor) {\n            material.emissiveFactor = material.emissiveTexture ? [1, 1, 1] : [0, 0, 0];\n        }\n        if (material.pbrMetallicRoughness) {\n            material.pbrMetallicRoughness = { ...material.pbrMetallicRoughness };\n            const mr = material.pbrMetallicRoughness;\n            if (mr.baseColorTexture) {\n                mr.baseColorTexture = { ...mr.baseColorTexture };\n                mr.baseColorTexture.texture = this.getTexture(mr.baseColorTexture.index);\n            }\n            if (mr.metallicRoughnessTexture) {\n                mr.metallicRoughnessTexture = { ...mr.metallicRoughnessTexture };\n                mr.metallicRoughnessTexture.texture = this.getTexture(mr.metallicRoughnessTexture.index);\n            }\n        }\n        return material;\n    }\n    _resolveAccessor(gltfAccessor, index) {\n        // Look up enums\n        const bytesPerComponent = getBytesFromComponentType(gltfAccessor.componentType);\n        const components = getSizeFromAccessorType(gltfAccessor.type);\n        const bytesPerElement = bytesPerComponent * components;\n        const accessor = {\n            ...gltfAccessor,\n            // @ts-expect-error\n            id: gltfAccessor.id || `accessor-${index}`,\n            bytesPerComponent,\n            components,\n            bytesPerElement,\n            value: undefined,\n            bufferView: undefined,\n            sparse: undefined\n        };\n        if (gltfAccessor.bufferView !== undefined) {\n            // Draco encoded meshes don't have bufferView\n            accessor.bufferView = this.getBufferView(gltfAccessor.bufferView);\n        }\n        // Create TypedArray for the accessor\n        // Note: The canonical way to instantiate is to ignore this array and create\n        // WebGLBuffer's using the bufferViews.\n        if (accessor.bufferView) {\n            const buffer = accessor.bufferView.buffer;\n            const { ArrayType, byteLength } = getAccessorArrayTypeAndLength(accessor, accessor.bufferView);\n            const byteOffset = (accessor.bufferView.byteOffset || 0) + (accessor.byteOffset || 0) + buffer.byteOffset;\n            let cutBuffer = buffer.arrayBuffer.slice(byteOffset, byteOffset + byteLength);\n            if (accessor.bufferView.byteStride) {\n                cutBuffer = this._getValueFromInterleavedBuffer(buffer, byteOffset, accessor.bufferView.byteStride, accessor.bytesPerElement, accessor.count);\n            }\n            accessor.value = new ArrayType(cutBuffer);\n        }\n        return accessor;\n    }\n    /**\n     * Take values of particular accessor from interleaved buffer\n     * various parts of the buffer\n     * @param buffer\n     * @param byteOffset\n     * @param byteStride\n     * @param bytesPerElement\n     * @param count\n     * @returns\n     */\n    _getValueFromInterleavedBuffer(buffer, byteOffset, byteStride, bytesPerElement, count) {\n        const result = new Uint8Array(count * bytesPerElement);\n        for (let i = 0; i < count; i++) {\n            const elementOffset = byteOffset + i * byteStride;\n            result.set(new Uint8Array(buffer.arrayBuffer.slice(elementOffset, elementOffset + bytesPerElement)), i * bytesPerElement);\n        }\n        return result.buffer;\n    }\n    _resolveTexture(gltfTexture, index) {\n        return {\n            ...gltfTexture,\n            // @ts-expect-error id could already be present, glTF standard does not prevent it\n            id: gltfTexture.id || `texture-${index}`,\n            sampler: typeof gltfTexture.sampler === 'number'\n                ? this.getSampler(gltfTexture.sampler)\n                : makeDefaultSampler(),\n            source: typeof gltfTexture.source === 'number' ? this.getImage(gltfTexture.source) : undefined\n        };\n    }\n    _resolveSampler(gltfSampler, index) {\n        const sampler = {\n            // @ts-expect-error id could already be present, glTF standard does not prevent it\n            id: gltfSampler.id || `sampler-${index}`,\n            ...gltfSampler,\n            parameters: {}\n        };\n        // Map textual parameters to GL parameter values\n        for (const key in sampler) {\n            const glEnum = this._enumSamplerParameter(key);\n            if (glEnum !== undefined) {\n                sampler.parameters[glEnum] = sampler[key];\n            }\n        }\n        return sampler;\n    }\n    _enumSamplerParameter(key) {\n        return SAMPLER_PARAMETER_GLTF_TO_GL[key];\n    }\n    _resolveImage(gltfImage, index) {\n        const image = {\n            ...gltfImage,\n            // @ts-expect-error id could already be present, glTF standard does not prevent it\n            id: gltfImage.id || `image-${index}`,\n            image: null,\n            bufferView: gltfImage.bufferView !== undefined ? this.getBufferView(gltfImage.bufferView) : undefined\n        };\n        // Check if image has been preloaded by the GLTFLoader\n        // If so, link it into the JSON and drop the URI\n        const preloadedImage = this.images[index];\n        if (preloadedImage) {\n            image.image = preloadedImage;\n        }\n        return image;\n    }\n    _resolveBufferView(gltfBufferView, index) {\n        const bufferIndex = gltfBufferView.buffer;\n        const arrayBuffer = this.buffers[bufferIndex].arrayBuffer;\n        // Add offset of buffer, then offset of buffer view\n        let byteOffset = this.buffers[bufferIndex].byteOffset || 0;\n        if (gltfBufferView.byteOffset) {\n            byteOffset += gltfBufferView.byteOffset;\n        }\n        const bufferView = {\n            // // @ts-expect-error id could already be present, glTF standard does not prevent it\n            id: `bufferView-${index}`,\n            ...gltfBufferView,\n            // ...this.buffers[bufferIndex],\n            buffer: this.buffers[bufferIndex],\n            data: new Uint8Array(arrayBuffer, byteOffset, gltfBufferView.byteLength)\n        };\n        return bufferView;\n    }\n    _resolveCamera(gltfCamera, index) {\n        const camera = {\n            ...gltfCamera,\n            // @ts-expect-error id could already be present, glTF standard does not prevent it\n            id: gltfCamera.id || `camera-${index}`\n        };\n        return camera;\n    }\n}\nfunction postProcessGLTF(gltf, options) {\n    return new GLTFPostProcessor().postProcess(gltf, options);\n}\n\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION = \"4.3.3\" ;\n/**\n * Loader for the LAS (LASer) point cloud format\n * @note Does not support LAS v1.4\n */\nconst LASLoader$2 = {\n    dataType: null,\n    batchType: null,\n    name: 'LAS',\n    id: 'las',\n    module: 'las',\n    version: VERSION,\n    worker: true,\n    extensions: ['las', 'laz'], // LAZ is the \"compressed\" flavor of LAS,\n    mimeTypes: ['application/octet-stream'], // TODO - text version?\n    text: true,\n    binary: true,\n    tests: ['LAS'],\n    options: {\n        las: {\n            shape: 'mesh',\n            fp64: false,\n            skip: 1,\n            colorDepth: 8\n        }\n    }\n};\n\n// @ts-nocheck\n/* eslint-disable */\n/*\n * Last update 2020-07-23\n *\n * Compiled from Howard Butler's laz-perf\n * https://github.com/hobu/laz-perf\n * Under LGPL License\n *\n * To update this file:\n * - git clone https://github.com/hobu/laz-perf\n * - cd laz-perf\n * - echo 'set(CMAKE_CXX_FLAGS \"-s SINGLE_FILE=1 ${CMAKE_CXX_FLAGS}\"' >> emscripten/CMakeLists.txt\n * - mkdir build && cd build\n * - cmake .. -DEMSCRIPTEN=1 -DCMAKE_TOOLCHAIN_FILE=<path-to-emsdk>/emscripten/<emsdk-version>/cmake/Modules/Platform/Emscripten.cmake\n * - VERBOSE=1 make\n *\n * See the laz-perf repository for required dependencies\n *\n * The result should be build/emscripten/laz-perf.asm.js\n * Copy the content of this file in the getModule function below\n */\n// laz-perf.js\nfunction getModule() {\n    var Module = typeof Module !== 'undefined' ? Module : {};\n    var moduleOverrides = {};\n    var key;\n    for (key in Module) {\n        if (Module.hasOwnProperty(key)) {\n            moduleOverrides[key] = Module[key];\n        }\n    }\n    var ENVIRONMENT_IS_WEB = false;\n    var ENVIRONMENT_IS_WORKER = false;\n    var ENVIRONMENT_IS_NODE = false;\n    var ENVIRONMENT_IS_SHELL = false;\n    ENVIRONMENT_IS_WEB = typeof window === 'object';\n    ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';\n    ENVIRONMENT_IS_NODE =\n        typeof process === 'object' &&\n            typeof process.versions === 'object' &&\n            typeof process.versions.node === 'string';\n    ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;\n    var scriptDirectory = '';\n    function locateFile(path) {\n        if (Module['locateFile']) {\n            return Module['locateFile'](path, scriptDirectory);\n        }\n        return scriptDirectory + path;\n    }\n    var read_, readAsync, readBinary;\n    var nodeFS;\n    var nodePath;\n    if (ENVIRONMENT_IS_NODE) {\n        if (ENVIRONMENT_IS_WORKER) {\n            scriptDirectory = require('path').dirname(scriptDirectory) + '/';\n        }\n        else {\n            const dirname = typeof __dirname !== 'undefined' ? __dirname : '';\n            scriptDirectory = dirname + '/';\n        }\n        read_ = function shell_read(filename, binary) {\n            var ret = tryParseAsDataURI(filename);\n            if (ret) {\n                return binary ? ret : ret.toString();\n            }\n            if (!nodeFS)\n                nodeFS = require('fs');\n            if (!nodePath)\n                nodePath = require('path');\n            filename = nodePath['normalize'](filename);\n            return nodeFS['readFileSync'](filename, binary ? null : 'utf8');\n        };\n        readBinary = function readBinary(filename) {\n            var ret = read_(filename, true);\n            if (!ret.buffer) {\n                ret = new Uint8Array(ret);\n            }\n            assert(ret.buffer);\n            return ret;\n        };\n        if (process['argv'].length > 1) {\n            process['argv'][1].replace(/\\\\/g, '/');\n        }\n        process['argv'].slice(2);\n        if (typeof module !== 'undefined') {\n            module['exports'] = Module;\n        }\n        process['on']('uncaughtException', function (ex) {\n            if (!(ex instanceof ExitStatus)) {\n                throw ex;\n            }\n        });\n        process['on']('unhandledRejection', abort);\n        Module['inspect'] = function () {\n            return '[Emscripten Module object]';\n        };\n    }\n    else if (ENVIRONMENT_IS_SHELL) {\n        if (typeof read != 'undefined') {\n            read_ = function shell_read(f) {\n                var data = tryParseAsDataURI(f);\n                if (data) {\n                    return intArrayToString(data);\n                }\n                return read(f);\n            };\n        }\n        readBinary = function readBinary(f) {\n            var data;\n            data = tryParseAsDataURI(f);\n            if (data) {\n                return data;\n            }\n            if (typeof readbuffer === 'function') {\n                return new Uint8Array(readbuffer(f));\n            }\n            data = read(f, 'binary');\n            assert(typeof data === 'object');\n            return data;\n        };\n        if (typeof scriptArgs != 'undefined') {\n            scriptArgs;\n        }\n        if (typeof print !== 'undefined') {\n            if (typeof console === 'undefined')\n                console = {};\n            console.log = print;\n            console.warn = console.error = typeof printErr !== 'undefined' ? printErr : print;\n        }\n    }\n    else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {\n        if (ENVIRONMENT_IS_WORKER) {\n            scriptDirectory = self.location.href;\n        }\n        else if (document.currentScript) {\n            scriptDirectory = document.currentScript.src;\n        }\n        if (scriptDirectory.indexOf('blob:') !== 0) {\n            scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/') + 1);\n        }\n        else {\n            scriptDirectory = '';\n        }\n        {\n            read_ = function shell_read(url) {\n                try {\n                    var xhr = new XMLHttpRequest();\n                    xhr.open('GET', url, false);\n                    xhr.send(null);\n                    return xhr.responseText;\n                }\n                catch (err) {\n                    var data = tryParseAsDataURI(url);\n                    if (data) {\n                        return intArrayToString(data);\n                    }\n                    throw err;\n                }\n            };\n            if (ENVIRONMENT_IS_WORKER) {\n                readBinary = function readBinary(url) {\n                    try {\n                        var xhr = new XMLHttpRequest();\n                        xhr.open('GET', url, false);\n                        xhr.responseType = 'arraybuffer';\n                        xhr.send(null);\n                        return new Uint8Array(xhr.response);\n                    }\n                    catch (err) {\n                        var data = tryParseAsDataURI(url);\n                        if (data) {\n                            return data;\n                        }\n                        throw err;\n                    }\n                };\n            }\n            readAsync = function readAsync(url, onload, onerror) {\n                var xhr = new XMLHttpRequest();\n                xhr.open('GET', url, true);\n                xhr.responseType = 'arraybuffer';\n                xhr.onload = function xhr_onload() {\n                    if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) {\n                        onload(xhr.response);\n                        return;\n                    }\n                    var data = tryParseAsDataURI(url);\n                    if (data) {\n                        onload(data.buffer);\n                        return;\n                    }\n                    onerror();\n                };\n                xhr.onerror = onerror;\n                xhr.send(null);\n            };\n        }\n    }\n    else ;\n    var out = Module['print'] || console.log.bind(console);\n    var err = Module['printErr'] || console.warn.bind(console);\n    for (key in moduleOverrides) {\n        if (moduleOverrides.hasOwnProperty(key)) {\n            Module[key] = moduleOverrides[key];\n        }\n    }\n    moduleOverrides = null;\n    if (Module['arguments'])\n        ;\n    if (Module['thisProgram'])\n        ;\n    if (Module['quit'])\n        ;\n    new Array(0);\n    var tempRet0 = 0;\n    var setTempRet0 = function (value) {\n        tempRet0 = value;\n    };\n    var getTempRet0 = function () {\n        return tempRet0;\n    };\n    var GLOBAL_BASE = 8;\n    if (Module['wasmBinary'])\n        ;\n    if (Module['noExitRuntime'])\n        ;\n    var ABORT = false;\n    function assert(condition, text) {\n        if (!condition) {\n            abort('Assertion failed: ' + text);\n        }\n    }\n    var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined;\n    function UTF8ArrayToString(heap, idx, maxBytesToRead) {\n        var endIdx = idx + maxBytesToRead;\n        var endPtr = idx;\n        while (heap[endPtr] && !(endPtr >= endIdx))\n            ++endPtr;\n        if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {\n            return UTF8Decoder.decode(heap.subarray(idx, endPtr));\n        }\n        else {\n            var str = '';\n            while (idx < endPtr) {\n                var u0 = heap[idx++];\n                if (!(u0 & 128)) {\n                    str += String.fromCharCode(u0);\n                    continue;\n                }\n                var u1 = heap[idx++] & 63;\n                if ((u0 & 224) == 192) {\n                    str += String.fromCharCode(((u0 & 31) << 6) | u1);\n                    continue;\n                }\n                var u2 = heap[idx++] & 63;\n                if ((u0 & 240) == 224) {\n                    u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;\n                }\n                else {\n                    u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[idx++] & 63);\n                }\n                if (u0 < 65536) {\n                    str += String.fromCharCode(u0);\n                }\n                else {\n                    var ch = u0 - 65536;\n                    str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));\n                }\n            }\n        }\n        return str;\n    }\n    function UTF8ToString(ptr, maxBytesToRead) {\n        return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';\n    }\n    function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {\n        if (!(maxBytesToWrite > 0))\n            return 0;\n        var startIdx = outIdx;\n        var endIdx = outIdx + maxBytesToWrite - 1;\n        for (var i = 0; i < str.length; ++i) {\n            var u = str.charCodeAt(i);\n            if (u >= 55296 && u <= 57343) {\n                var u1 = str.charCodeAt(++i);\n                u = (65536 + ((u & 1023) << 10)) | (u1 & 1023);\n            }\n            if (u <= 127) {\n                if (outIdx >= endIdx)\n                    break;\n                heap[outIdx++] = u;\n            }\n            else if (u <= 2047) {\n                if (outIdx + 1 >= endIdx)\n                    break;\n                heap[outIdx++] = 192 | (u >> 6);\n                heap[outIdx++] = 128 | (u & 63);\n            }\n            else if (u <= 65535) {\n                if (outIdx + 2 >= endIdx)\n                    break;\n                heap[outIdx++] = 224 | (u >> 12);\n                heap[outIdx++] = 128 | ((u >> 6) & 63);\n                heap[outIdx++] = 128 | (u & 63);\n            }\n            else {\n                if (outIdx + 3 >= endIdx)\n                    break;\n                heap[outIdx++] = 240 | (u >> 18);\n                heap[outIdx++] = 128 | ((u >> 12) & 63);\n                heap[outIdx++] = 128 | ((u >> 6) & 63);\n                heap[outIdx++] = 128 | (u & 63);\n            }\n        }\n        heap[outIdx] = 0;\n        return outIdx - startIdx;\n    }\n    function stringToUTF8(str, outPtr, maxBytesToWrite) {\n        return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);\n    }\n    function lengthBytesUTF8(str) {\n        var len = 0;\n        for (var i = 0; i < str.length; ++i) {\n            var u = str.charCodeAt(i);\n            if (u >= 55296 && u <= 57343)\n                u = (65536 + ((u & 1023) << 10)) | (str.charCodeAt(++i) & 1023);\n            if (u <= 127)\n                ++len;\n            else if (u <= 2047)\n                len += 2;\n            else if (u <= 65535)\n                len += 3;\n            else\n                len += 4;\n        }\n        return len;\n    }\n    var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined;\n    function UTF16ToString(ptr, maxBytesToRead) {\n        var endPtr = ptr;\n        var idx = endPtr >> 1;\n        var maxIdx = idx + maxBytesToRead / 2;\n        while (!(idx >= maxIdx) && HEAPU16[idx])\n            ++idx;\n        endPtr = idx << 1;\n        if (endPtr - ptr > 32 && UTF16Decoder) {\n            return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));\n        }\n        else {\n            var i = 0;\n            var str = '';\n            while (1) {\n                var codeUnit = HEAP16[(ptr + i * 2) >> 1];\n                if (codeUnit == 0 || i == maxBytesToRead / 2)\n                    return str;\n                ++i;\n                str += String.fromCharCode(codeUnit);\n            }\n        }\n    }\n    function stringToUTF16(str, outPtr, maxBytesToWrite) {\n        if (maxBytesToWrite === undefined) {\n            maxBytesToWrite = 2147483647;\n        }\n        if (maxBytesToWrite < 2)\n            return 0;\n        maxBytesToWrite -= 2;\n        var startPtr = outPtr;\n        var numCharsToWrite = maxBytesToWrite < str.length * 2 ? maxBytesToWrite / 2 : str.length;\n        for (var i = 0; i < numCharsToWrite; ++i) {\n            var codeUnit = str.charCodeAt(i);\n            HEAP16[outPtr >> 1] = codeUnit;\n            outPtr += 2;\n        }\n        HEAP16[outPtr >> 1] = 0;\n        return outPtr - startPtr;\n    }\n    function lengthBytesUTF16(str) {\n        return str.length * 2;\n    }\n    function UTF32ToString(ptr, maxBytesToRead) {\n        var i = 0;\n        var str = '';\n        while (!(i >= maxBytesToRead / 4)) {\n            var utf32 = HEAP32[(ptr + i * 4) >> 2];\n            if (utf32 == 0)\n                break;\n            ++i;\n            if (utf32 >= 65536) {\n                var ch = utf32 - 65536;\n                str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));\n            }\n            else {\n                str += String.fromCharCode(utf32);\n            }\n        }\n        return str;\n    }\n    function stringToUTF32(str, outPtr, maxBytesToWrite) {\n        if (maxBytesToWrite === undefined) {\n            maxBytesToWrite = 2147483647;\n        }\n        if (maxBytesToWrite < 4)\n            return 0;\n        var startPtr = outPtr;\n        var endPtr = startPtr + maxBytesToWrite - 4;\n        for (var i = 0; i < str.length; ++i) {\n            var codeUnit = str.charCodeAt(i);\n            if (codeUnit >= 55296 && codeUnit <= 57343) {\n                var trailSurrogate = str.charCodeAt(++i);\n                codeUnit = (65536 + ((codeUnit & 1023) << 10)) | (trailSurrogate & 1023);\n            }\n            HEAP32[outPtr >> 2] = codeUnit;\n            outPtr += 4;\n            if (outPtr + 4 > endPtr)\n                break;\n        }\n        HEAP32[outPtr >> 2] = 0;\n        return outPtr - startPtr;\n    }\n    function lengthBytesUTF32(str) {\n        var len = 0;\n        for (var i = 0; i < str.length; ++i) {\n            var codeUnit = str.charCodeAt(i);\n            if (codeUnit >= 55296 && codeUnit <= 57343)\n                ++i;\n            len += 4;\n        }\n        return len;\n    }\n    var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;\n    function updateGlobalBufferAndViews(buf) {\n        buffer = buf;\n        Module['HEAP8'] = HEAP8 = new Int8Array(buf);\n        Module['HEAP16'] = HEAP16 = new Int16Array(buf);\n        Module['HEAP32'] = HEAP32 = new Int32Array(buf);\n        Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf);\n        Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf);\n        Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf);\n        Module['HEAPF32'] = HEAPF32 = new Float32Array(buf);\n        Module['HEAPF64'] = HEAPF64 = new Float64Array(buf);\n    }\n    var DYNAMIC_BASE = 5265264, DYNAMICTOP_PTR = 22176;\n    var INITIAL_INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 167772160;\n    if (Module['buffer']) {\n        buffer = Module['buffer'];\n    }\n    else {\n        buffer = new ArrayBuffer(INITIAL_INITIAL_MEMORY);\n    }\n    INITIAL_INITIAL_MEMORY = buffer.byteLength;\n    updateGlobalBufferAndViews(buffer);\n    HEAP32[DYNAMICTOP_PTR >> 2] = DYNAMIC_BASE;\n    function callRuntimeCallbacks(callbacks) {\n        while (callbacks.length > 0) {\n            var callback = callbacks.shift();\n            if (typeof callback == 'function') {\n                callback(Module);\n                continue;\n            }\n            var func = callback.func;\n            if (typeof func === 'number') {\n                if (callback.arg === undefined) {\n                    Module['dynCall_v'](func);\n                }\n                else {\n                    Module['dynCall_vi'](func, callback.arg);\n                }\n            }\n            else {\n                func(callback.arg === undefined ? null : callback.arg);\n            }\n        }\n    }\n    var __ATPRERUN__ = [];\n    var __ATINIT__ = [];\n    var __ATMAIN__ = [];\n    var __ATPOSTRUN__ = [];\n    function preRun() {\n        if (Module['preRun']) {\n            if (typeof Module['preRun'] == 'function')\n                Module['preRun'] = [Module['preRun']];\n            while (Module['preRun'].length) {\n                addOnPreRun(Module['preRun'].shift());\n            }\n        }\n        callRuntimeCallbacks(__ATPRERUN__);\n    }\n    function initRuntime() {\n        callRuntimeCallbacks(__ATINIT__);\n    }\n    function preMain() {\n        callRuntimeCallbacks(__ATMAIN__);\n    }\n    function postRun() {\n        if (Module['postRun']) {\n            if (typeof Module['postRun'] == 'function')\n                Module['postRun'] = [Module['postRun']];\n            while (Module['postRun'].length) {\n                addOnPostRun(Module['postRun'].shift());\n            }\n        }\n        callRuntimeCallbacks(__ATPOSTRUN__);\n    }\n    function addOnPreRun(cb) {\n        __ATPRERUN__.unshift(cb);\n    }\n    function addOnPostRun(cb) {\n        __ATPOSTRUN__.unshift(cb);\n    }\n    var runDependencies = 0;\n    var dependenciesFulfilled = null;\n    function addRunDependency(id) {\n        runDependencies++;\n        if (Module['monitorRunDependencies']) {\n            Module['monitorRunDependencies'](runDependencies);\n        }\n    }\n    function removeRunDependency(id) {\n        runDependencies--;\n        if (Module['monitorRunDependencies']) {\n            Module['monitorRunDependencies'](runDependencies);\n        }\n        if (runDependencies == 0) {\n            if (dependenciesFulfilled) {\n                var callback = dependenciesFulfilled;\n                dependenciesFulfilled = null;\n                callback();\n            }\n        }\n    }\n    Module['preloadedImages'] = {};\n    Module['preloadedAudios'] = {};\n    function abort(what) {\n        if (Module['onAbort']) {\n            Module['onAbort'](what);\n        }\n        what += '';\n        out(what);\n        err(what);\n        ABORT = true;\n        what = 'abort(' + what + '). Build with -s ASSERTIONS=1 for more info.';\n        throw what;\n    }\n    var memoryInitializer = null;\n    function hasPrefix(str, prefix) {\n        return String.prototype.startsWith ? str.startsWith(prefix) : str.indexOf(prefix) === 0;\n    }\n    var dataURIPrefix = 'data:application/octet-stream;base64,';\n    function isDataURI(filename) {\n        return hasPrefix(filename, dataURIPrefix);\n    }\n    __ATINIT__.push({\n        func: function () {\n            globalCtors();\n        }\n    });\n    memoryInitializer =\n        'data:application/octet-stream;base64,AAAAAAAAAAAPDg0MCwoJCA4AAQMGCgoJDQECBAcLCwoMAwQFCAwMCwsGBwgJDQ0MCgoLDA0ODg0JCgsMDQ4PDggJCgsMDQ4PAAECAwQFBgcBAAECAwQFBgIBAAECAwQFAwIBAAECAwQEAwIBAAECAwUEAwIBAAECBgUEAwIBAAEHBgUEAwIBAMgPAAAoDQAAEBAAACAQAADIDwAAUA0AABAQAAAgEAAAEQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAEACQsLAAAJBgsAAAsABhEAAAAREREAAAAAAAAAAAAAAAAAAAAACwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAwAAAAADAAAAAAJDAAAAAAADAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAANAAAABA0AAAAACQ4AAAAAAA4AAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAADwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhISAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAASEhIAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAAAAAAAAAAAKAAAAAAoAAAAACQsAAAAAAAsAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAADAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGGRJEOwI/LEcUPTMwChsGRktFNw9JDo4XA0AdPGkrNh9KLRwBICUpIQgMFRYiLhA4Pgs0MRhkdHV2L0EJfzkRI0MyQomKiwUEJignDSoeNYwHGkiTE5SVAAAAAAAAAAAASWxsZWdhbCBieXRlIHNlcXVlbmNlAERvbWFpbiBlcnJvcgBSZXN1bHQgbm90IHJlcHJlc2VudGFibGUATm90IGEgdHR5AFBlcm1pc3Npb24gZGVuaWVkAE9wZXJhdGlvbiBub3QgcGVybWl0dGVkAE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkATm8gc3VjaCBwcm9jZXNzAEZpbGUgZXhpc3RzAFZhbHVlIHRvbyBsYXJnZSBmb3IgZGF0YSB0eXBlAE5vIHNwYWNlIGxlZnQgb24gZGV2aWNlAE91dCBvZiBtZW1vcnkAUmVzb3VyY2UgYnVzeQBJbnRlcnJ1cHRlZCBzeXN0ZW0gY2FsbABSZXNvdXJjZSB0ZW1wb3JhcmlseSB1bmF2YWlsYWJsZQBJbnZhbGlkIHNlZWsAQ3Jvc3MtZGV2aWNlIGxpbmsAUmVhZC1vbmx5IGZpbGUgc3lzdGVtAERpcmVjdG9yeSBub3QgZW1wdHkAQ29ubmVjdGlvbiByZXNldCBieSBwZWVyAE9wZXJhdGlvbiB0aW1lZCBvdXQAQ29ubmVjdGlvbiByZWZ1c2VkAEhvc3QgaXMgZG93bgBIb3N0IGlzIHVucmVhY2hhYmxlAEFkZHJlc3MgaW4gdXNlAEJyb2tlbiBwaXBlAEkvTyBlcnJvcgBObyBzdWNoIGRldmljZSBvciBhZGRyZXNzAEJsb2NrIGRldmljZSByZXF1aXJlZABObyBzdWNoIGRldmljZQBOb3QgYSBkaXJlY3RvcnkASXMgYSBkaXJlY3RvcnkAVGV4dCBmaWxlIGJ1c3kARXhlYyBmb3JtYXQgZXJyb3IASW52YWxpZCBhcmd1bWVudABBcmd1bWVudCBsaXN0IHRvbyBsb25nAFN5bWJvbGljIGxpbmsgbG9vcABGaWxlbmFtZSB0b28gbG9uZwBUb28gbWFueSBvcGVuIGZpbGVzIGluIHN5c3RlbQBObyBmaWxlIGRlc2NyaXB0b3JzIGF2YWlsYWJsZQBCYWQgZmlsZSBkZXNjcmlwdG9yAE5vIGNoaWxkIHByb2Nlc3MAQmFkIGFkZHJlc3MARmlsZSB0b28gbGFyZ2UAVG9vIG1hbnkgbGlua3MATm8gbG9ja3MgYXZhaWxhYmxlAFJlc291cmNlIGRlYWRsb2NrIHdvdWxkIG9jY3VyAFN0YXRlIG5vdCByZWNvdmVyYWJsZQBQcmV2aW91cyBvd25lciBkaWVkAE9wZXJhdGlvbiBjYW5jZWxlZABGdW5jdGlvbiBub3QgaW1wbGVtZW50ZWQATm8gbWVzc2FnZSBvZiBkZXNpcmVkIHR5cGUASWRlbnRpZmllciByZW1vdmVkAERldmljZSBub3QgYSBzdHJlYW0ATm8gZGF0YSBhdmFpbGFibGUARGV2aWNlIHRpbWVvdXQAT3V0IG9mIHN0cmVhbXMgcmVzb3VyY2VzAExpbmsgaGFzIGJlZW4gc2V2ZXJlZABQcm90b2NvbCBlcnJvcgBCYWQgbWVzc2FnZQBGaWxlIGRlc2NyaXB0b3IgaW4gYmFkIHN0YXRlAE5vdCBhIHNvY2tldABEZXN0aW5hdGlvbiBhZGRyZXNzIHJlcXVpcmVkAE1lc3NhZ2UgdG9vIGxhcmdlAFByb3RvY29sIHdyb25nIHR5cGUgZm9yIHNvY2tldABQcm90b2NvbCBub3QgYXZhaWxhYmxlAFByb3RvY29sIG5vdCBzdXBwb3J0ZWQAU29ja2V0IHR5cGUgbm90IHN1cHBvcnRlZABOb3Qgc3VwcG9ydGVkAFByb3RvY29sIGZhbWlseSBub3Qgc3VwcG9ydGVkAEFkZHJlc3MgZmFtaWx5IG5vdCBzdXBwb3J0ZWQgYnkgcHJvdG9jb2wAQWRkcmVzcyBub3QgYXZhaWxhYmxlAE5ldHdvcmsgaXMgZG93bgBOZXR3b3JrIHVucmVhY2hhYmxlAENvbm5lY3Rpb24gcmVzZXQgYnkgbmV0d29yawBDb25uZWN0aW9uIGFib3J0ZWQATm8gYnVmZmVyIHNwYWNlIGF2YWlsYWJsZQBTb2NrZXQgaXMgY29ubmVjdGVkAFNvY2tldCBub3QgY29ubmVjdGVkAENhbm5vdCBzZW5kIGFmdGVyIHNvY2tldCBzaHV0ZG93bgBPcGVyYXRpb24gYWxyZWFkeSBpbiBwcm9ncmVzcwBPcGVyYXRpb24gaW4gcHJvZ3Jlc3MAU3RhbGUgZmlsZSBoYW5kbGUAUmVtb3RlIEkvTyBlcnJvcgBRdW90YSBleGNlZWRlZABObyBtZWRpdW0gZm91bmQAV3JvbmcgbWVkaXVtIHR5cGUATm8gZXJyb3IgaW5mb3JtYXRpb24AAAAAAADgFgAAmRgAAGAQAAAAAAAA4BYAAEIZAABgEAAAAAAAAOAWAAAqGgAASA8AAAAAAAC4FgAANBsAAOAWAACfGgAAMAoAAAAAAADgFgAAaRsAAEgPAAAAAAAA4BYAAIobAABIDwAAAAAAALgWAAAPHAAA4BYAAHwcAABIDwAAAAAAAOAWAACVHAAASA8AAAAAAADgFgAA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c2hhcmVkX3B0cl9wb2ludGVySVBONmxhc3ppcDdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRU5TXzE0ZGVmYXVsdF9kZWxldGVJUzNfRUVOU185YWxsb2NhdG9ySVMzX0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJTjZsYXN6aXA3c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRQBOU3QzX18yMjBfX3NoYXJlZF9wdHJfcG9pbnRlcklQTjZsYXN6aXAyaW82cmVhZGVyMTBiYXNpY19maWxlSU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRU5TXzE0ZGVmYXVsdF9kZWxldGVJUzdfRUVOU185YWxsb2NhdG9ySVM3X0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJTjZsYXN6aXAyaW82cmVhZGVyMTBiYXNpY19maWxlSU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFAExBU0YATjZsYXN6aXAxM2ludmFsaWRfbWFnaWNFAGFsbG9jYXRvcjxUPjo6YWxsb2NhdGUoc2l6ZV90IG4pICduJyBleGNlZWRzIG1heGltdW0gc3VwcG9ydGVkIHNpemUARmlsZSBtYWdpYyBpcyBub3QgdmFsaWQATlN0M19fMjEwX19mdW5jdGlvbjZfX2Z1bmNJWk42bGFzemlwMmlvNnJlYWRlcjEwYmFzaWNfZmlsZUlOUzJfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRTExX3ZhbGlkYXRvcnNFdkVVbFJOUzNfNmhlYWRlckVFX05TXzlhbGxvY2F0b3JJU0JfRUVGdlNBX0VFRQBOU3QzX18yMTBfX2Z1bmN0aW9uNl9fYmFzZUlGdlJONmxhc3ppcDJpbzZoZWFkZXJFRUVFAE42bGFzemlwMjFvbGRfc3R5bGVfY29tcHJlc3Npb25FAE42bGFzemlwMTRub3RfY29tcHJlc3NlZEUAVGhlIGZpbGUgc2VlbXMgdG8gaGF2ZSBvbGQgc3R5bGUgY29tcHJlc3Npb24gd2hpY2ggaXMgbm90IHN1cHBvcnRlZABUaGUgZmlsZSBkb2Vzbid0IHNlZW0gdG8gYmUgY29tcHJlc3NlZABaTjZsYXN6aXAyaW82cmVhZGVyMTBiYXNpY19maWxlSU5TXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUUxMV92YWxpZGF0b3JzRXZFVWxSTlMwXzZoZWFkZXJFRV8AbGFzemlwIGVuY29kZWQATjZsYXN6aXAxM25vX2xhc3ppcF92bHJFAE42bGFzemlwMjVsYXN6aXBfZm9ybWF0X3Vuc3VwcG9ydGVkRQBPbmx5IExBU3ppcCBQT0lOVFdJU0UgQ0hVTktFRCBkZWNvbXByZXNzb3IgaXMgc3VwcG9ydGVkAE5vIExBU3ppcCBWTFIgd2FzIGZvdW5kIGluIHRoZSBWTFJzIHNlY3Rpb24ATjZsYXN6aXAyMmNodW5rX3RhYmxlX3JlYWRfZXJyb3JFAENodW5rIHRhYmxlIG9mZnNldCA9PSAtMSBpcyBub3Qgc3VwcG9ydGVkIGF0IHRoaXMgdGltZQBONmxhc3ppcDEzbm90X3N1cHBvcnRlZEUATjZsYXN6aXAyNnVua25vd25fY2h1bmtfdGFibGVfZm9ybWF0RQBjaHVua19zaXplID09IHVpbnQubWF4IGlzIG5vdCBzdXBwb3J0ZWQgYXQgdGhpcyB0aW1lLgBUaGVyZSB3YXMgYSBwcm9ibGVtIHJlYWRpbmcgdGhlIGNodW5rIHRhYmxlAFRoZSBjaHVuayB0YWJsZSB2ZXJzaW9uIG51bWJlciBpcyB1bmtub3duAE42bGFzemlwMTFlbmRfb2ZfZmlsZUUAUmVhY2hlZCBFbmQgb2YgZmlsZQBJbnZhbGlkIG51bWJlciBvZiBzeW1ib2xzAE5TdDNfXzIyMF9fc2hhcmVkX3B0cl9wb2ludGVySVBONmxhc3ppcDhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOU18xNGRlZmF1bHRfZGVsZXRlSVM5X0VFTlNfOWFsbG9jYXRvcklTOV9FRUVFAE5TdDNfXzIxNGRlZmF1bHRfZGVsZXRlSU42bGFzemlwOGRlY29kZXJzMTBhcml0aG1ldGljSU5TMV8yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOUzFfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRUVFAE42bGFzemlwMTl1bmtub3duX3NjaGVtYV90eXBlRQBUaGUgTEFaIHNjaGVtYSBpcyBub3QgcmVjb2duaXplZABONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2ZpZWxkX2RlY29tcHJlc3NvcklOU184ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlNfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlNfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyMGR5bmFtaWNfZGVjb21wcmVzc29yRQBOU3QzX18yMjBfX3NoYXJlZF9wdHJfcG9pbnRlcklQTjZsYXN6aXA3Zm9ybWF0czI2ZHluYW1pY19maWVsZF9kZWNvbXByZXNzb3JJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVFRU5TXzE0ZGVmYXVsdF9kZWxldGVJU0NfRUVOU185YWxsb2NhdG9ySVNDX0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJTjZsYXN6aXA3Zm9ybWF0czI2ZHluYW1pY19maWVsZF9kZWNvbXByZXNzb3JJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOU18yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOU183c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMwXzVmaWVsZElOUzBfM2xhczdwb2ludDEwRU5TMF8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNDX0VFRUVFRQBONmxhc3ppcDdmb3JtYXRzMTBiYXNlX2ZpZWxkRQBOU3QzX18yMjBfX3NoYXJlZF9wdHJfcG9pbnRlcklQTjZsYXN6aXA3Zm9ybWF0czI2ZHluYW1pY19kZWNvbXByZXNzb3JfZmllbGRJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzJfNWZpZWxkSU5TMl8zbGFzN3BvaW50MTBFTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0VfRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTSV9FRU5TXzlhbGxvY2F0b3JJU0lfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSU5TMV8yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOUzFfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRU5TMl81ZmllbGRJTlMyXzNsYXM3cG9pbnQxMEVOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTRV9FRUVFRUVFRQBONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOU184ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlNfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlNfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRU5TMF81ZmllbGRJTlMwXzNsYXM3Z3BzdGltZUVOUzBfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTQ19FRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzVmaWVsZElOUzJfM2xhczdncHN0aW1lRU5TMl8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNFX0VFRUVFRU5TXzE0ZGVmYXVsdF9kZWxldGVJU0lfRUVOU185YWxsb2NhdG9ySVNJX0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJTjZsYXN6aXA3Zm9ybWF0czI2ZHluYW1pY19kZWNvbXByZXNzb3JfZmllbGRJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzJfNWZpZWxkSU5TMl8zbGFzN2dwc3RpbWVFTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0VfRUVFRUVFRUUATjZsYXN6aXA3Zm9ybWF0czI2ZHluYW1pY19kZWNvbXByZXNzb3JfZmllbGRJTlNfOGRlY29kZXJzMTBhcml0aG1ldGljSU5TXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzBfNWZpZWxkSU5TMF8zbGFzM3JnYkVOUzBfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTQ19FRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzVmaWVsZElOUzJfM2xhczNyZ2JFTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0VfRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTSV9FRU5TXzlhbGxvY2F0b3JJU0lfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSU5TMV8yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOUzFfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRU5TMl81ZmllbGRJTlMyXzNsYXMzcmdiRU5TMl8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNFX0VFRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOU18yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOU183c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMwXzVmaWVsZElOUzBfM2xhczEwZXh0cmFieXRlc0VOUzBfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTQ19FRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzVmaWVsZElOUzJfM2xhczEwZXh0cmFieXRlc0VOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTRV9FRUVFRUVOU18xNGRlZmF1bHRfZGVsZXRlSVNJX0VFTlNfOWFsbG9jYXRvcklTSV9FRUVFAE5TdDNfXzIxNGRlZmF1bHRfZGVsZXRlSU42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzVmaWVsZElOUzJfM2xhczEwZXh0cmFieXRlc0VOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTRV9FRUVFRUVFRQBONmxhc3ppcDdmb3JtYXRzMjFkeW5hbWljX2RlY29tcHJlc3NvcjFJTlNfOGRlY29kZXJzMTBhcml0aG1ldGljSU5TXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzBfMTlyZWNvcmRfZGVjb21wcmVzc29ySUpOUzBfNWZpZWxkSU5TMF8zbGFzN3BvaW50MTBFTlMwXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0RfRUVFRUVFRUVFAE5TdDNfXzIyMF9fc2hhcmVkX3B0cl9wb2ludGVySVBONmxhc3ppcDdmb3JtYXRzMjFkeW5hbWljX2RlY29tcHJlc3NvcjFJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzJfMTlyZWNvcmRfZGVjb21wcmVzc29ySUpOUzJfNWZpZWxkSU5TMl8zbGFzN3BvaW50MTBFTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0ZfRUVFRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTS19FRU5TXzlhbGxvY2F0b3JJU0tfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjFkeW5hbWljX2RlY29tcHJlc3NvcjFJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzJfMTlyZWNvcmRfZGVjb21wcmVzc29ySUpOUzJfNWZpZWxkSU5TMl8zbGFzN3BvaW50MTBFTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0ZfRUVFRUVFRUVFRUUATjZsYXN6aXA3Zm9ybWF0czIxZHluYW1pY19kZWNvbXByZXNzb3IxSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOU18yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOU183c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMwXzE5cmVjb3JkX2RlY29tcHJlc3NvcklKTlMwXzVmaWVsZElOUzBfM2xhczdwb2ludDEwRU5TMF8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNEX0VFRUVOU0JfSU5TQ183Z3BzdGltZUVOU0VfSVNIX0VFRUVFRUVFRQBOU3QzX18yMjBfX3NoYXJlZF9wdHJfcG9pbnRlcklQTjZsYXN6aXA3Zm9ybWF0czIxZHluYW1pY19kZWNvbXByZXNzb3IxSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzE5cmVjb3JkX2RlY29tcHJlc3NvcklKTlMyXzVmaWVsZElOUzJfM2xhczdwb2ludDEwRU5TMl8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNGX0VFRUVOU0RfSU5TRV83Z3BzdGltZUVOU0dfSVNKX0VFRUVFRUVFRU5TXzE0ZGVmYXVsdF9kZWxldGVJU05fRUVOU185YWxsb2NhdG9ySVNOX0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJTjZsYXN6aXA3Zm9ybWF0czIxZHluYW1pY19kZWNvbXByZXNzb3IxSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzE5cmVjb3JkX2RlY29tcHJlc3NvcklKTlMyXzVmaWVsZElOUzJfM2xhczdwb2ludDEwRU5TMl8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNGX0VFRUVOU0RfSU5TRV83Z3BzdGltZUVOU0dfSVNKX0VFRUVFRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyMWR5bmFtaWNfZGVjb21wcmVzc29yMUlOU184ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlNfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlNfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRU5TMF8xOXJlY29yZF9kZWNvbXByZXNzb3JJSk5TMF81ZmllbGRJTlMwXzNsYXM3cG9pbnQxMEVOUzBfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTRF9FRUVFTlNCX0lOU0NfM3JnYkVOU0VfSVNIX0VFRUVFRUVFRQBOU3QzX18yMjBfX3NoYXJlZF9wdHJfcG9pbnRlcklQTjZsYXN6aXA3Zm9ybWF0czIxZHluYW1pY19kZWNvbXByZXNzb3IxSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzE5cmVjb3JkX2RlY29tcHJlc3NvcklKTlMyXzVmaWVsZElOUzJfM2xhczdwb2ludDEwRU5TMl8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNGX0VFRUVOU0RfSU5TRV8zcmdiRU5TR19JU0pfRUVFRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTTl9FRU5TXzlhbGxvY2F0b3JJU05fRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjFkeW5hbWljX2RlY29tcHJlc3NvcjFJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzJfMTlyZWNvcmRfZGVjb21wcmVzc29ySUpOUzJfNWZpZWxkSU5TMl8zbGFzN3BvaW50MTBFTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0ZfRUVFRU5TRF9JTlNFXzNyZ2JFTlNHX0lTSl9FRUVFRUVFRUVFRQBONmxhc3ppcDdmb3JtYXRzMjFkeW5hbWljX2RlY29tcHJlc3NvcjFJTlNfOGRlY29kZXJzMTBhcml0aG1ldGljSU5TXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzBfMTlyZWNvcmRfZGVjb21wcmVzc29ySUpOUzBfNWZpZWxkSU5TMF8zbGFzN3BvaW50MTBFTlMwXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0RfRUVFRU5TQl9JTlNDXzdncHN0aW1lRU5TRV9JU0hfRUVFRU5TQl9JTlNDXzNyZ2JFTlNFX0lTS19FRUVFRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyMWR5bmFtaWNfZGVjb21wcmVzc29yMUlOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSU5TMV8yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOUzFfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRU5TMl8xOXJlY29yZF9kZWNvbXByZXNzb3JJSk5TMl81ZmllbGRJTlMyXzNsYXM3cG9pbnQxMEVOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTRl9FRUVFTlNEX0lOU0VfN2dwc3RpbWVFTlNHX0lTSl9FRUVFTlNEX0lOU0VfM3JnYkVOU0dfSVNNX0VFRUVFRUVFRU5TXzE0ZGVmYXVsdF9kZWxldGVJU1FfRUVOU185YWxsb2NhdG9ySVNRX0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJTjZsYXN6aXA3Zm9ybWF0czIxZHluYW1pY19kZWNvbXByZXNzb3IxSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzE5cmVjb3JkX2RlY29tcHJlc3NvcklKTlMyXzVmaWVsZElOUzJfM2xhczdwb2ludDEwRU5TMl8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNGX0VFRUVOU0RfSU5TRV83Z3BzdGltZUVOU0dfSVNKX0VFRUVOU0RfSU5TRV8zcmdiRU5TR19JU01fRUVFRUVFRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUDEwYnVmX3N0cmVhbU5TXzE0ZGVmYXVsdF9kZWxldGVJUzFfRUVOU185YWxsb2NhdG9ySVMxX0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJMTBidWZfc3RyZWFtRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwOGRlY29kZXJzMTBhcml0aG1ldGljSTEwYnVmX3N0cmVhbUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTNV9FRU5TXzlhbGxvY2F0b3JJUzVfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDhkZWNvZGVyczEwYXJpdGhtZXRpY0kxMGJ1Zl9zdHJlYW1FRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZmllbGRfZGVjb21wcmVzc29ySU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0kxMGJ1Zl9zdHJlYW1FRUVFAE5TdDNfXzIyMF9fc2hhcmVkX3B0cl9wb2ludGVySVBONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2ZpZWxkX2RlY29tcHJlc3NvcklOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSTEwYnVmX3N0cmVhbUVFRUVOU18xNGRlZmF1bHRfZGVsZXRlSVM4X0VFTlNfOWFsbG9jYXRvcklTOF9FRUVFAE5TdDNfXzIxNGRlZmF1bHRfZGVsZXRlSU42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZmllbGRfZGVjb21wcmVzc29ySU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJMTBidWZfc3RyZWFtRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0kxMGJ1Zl9zdHJlYW1FRU5TMF81ZmllbGRJaU5TMF8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSWlFRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJMTBidWZfc3RyZWFtRUVOUzJfNWZpZWxkSWlOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElpRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTQ19FRU5TXzlhbGxvY2F0b3JJU0NfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSTEwYnVmX3N0cmVhbUVFTlMyXzVmaWVsZElpTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJaUVFRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0kxMGJ1Zl9zdHJlYW1FRU5TMF81ZmllbGRJak5TMF8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSWpFRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJMTBidWZfc3RyZWFtRUVOUzJfNWZpZWxkSWpOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElqRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTQ19FRU5TXzlhbGxvY2F0b3JJU0NfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSTEwYnVmX3N0cmVhbUVFTlMyXzVmaWVsZElqTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJakVFRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0kxMGJ1Zl9zdHJlYW1FRU5TMF81ZmllbGRJYU5TMF8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSWFFRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJMTBidWZfc3RyZWFtRUVOUzJfNWZpZWxkSWFOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElhRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTQ19FRU5TXzlhbGxvY2F0b3JJU0NfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSTEwYnVmX3N0cmVhbUVFTlMyXzVmaWVsZElhTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJYUVFRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0kxMGJ1Zl9zdHJlYW1FRU5TMF81ZmllbGRJc05TMF8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSXNFRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJMTBidWZfc3RyZWFtRUVOUzJfNWZpZWxkSXNOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElzRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTQ19FRU5TXzlhbGxvY2F0b3JJU0NfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSTEwYnVmX3N0cmVhbUVFTlMyXzVmaWVsZElzTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJc0VFRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0kxMGJ1Zl9zdHJlYW1FRU5TMF81ZmllbGRJaE5TMF8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSWhFRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJMTBidWZfc3RyZWFtRUVOUzJfNWZpZWxkSWhOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZEloRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTQ19FRU5TXzlhbGxvY2F0b3JJU0NfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSTEwYnVmX3N0cmVhbUVFTlMyXzVmaWVsZEloTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJaEVFRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0kxMGJ1Zl9zdHJlYW1FRU5TMF81ZmllbGRJdE5TMF8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSXRFRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJMTBidWZfc3RyZWFtRUVOUzJfNWZpZWxkSXROUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZEl0RUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTQ19FRU5TXzlhbGxvY2F0b3JJU0NfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSTEwYnVmX3N0cmVhbUVFTlMyXzVmaWVsZEl0TlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJdEVFRUVFRUVFADZMQVNaaXAAUDZMQVNaaXAAUEs2TEFTWmlwAGlpAHYAdmkAdmlpaWkAdmlpaQBpaWkAMTNEeW5hbWljTEFTWmlwAFAxM0R5bmFtaWNMQVNaaXAAUEsxM0R5bmFtaWNMQVNaaXAAdm9pZABib29sAGNoYXIAc2lnbmVkIGNoYXIAdW5zaWduZWQgY2hhcgBzaG9ydAB1bnNpZ25lZCBzaG9ydABpbnQAdW5zaWduZWQgaW50AGxvbmcAdW5zaWduZWQgbG9uZwBmbG9hdABkb3VibGUAc3RkOjpzdHJpbmcAc3RkOjpiYXNpY19zdHJpbmc8dW5zaWduZWQgY2hhcj4Ac3RkOjp3c3RyaW5nAHN0ZDo6dTE2c3RyaW5nAHN0ZDo6dTMyc3RyaW5nAGVtc2NyaXB0ZW46OnZhbABlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaWduZWQgY2hhcj4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgY2hhcj4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8c2hvcnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVuc2lnbmVkIHNob3J0PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVuc2lnbmVkIGludD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8bG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgbG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50OF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50OF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQxNl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50MzJfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDMyX3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGZsb2F0PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxkb3VibGU+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGxvbmcgZG91YmxlPgBOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0llRUUATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJZEVFAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWZFRQBOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0ltRUUATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJbEVFAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWpFRQBOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lpRUUATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJdEVFAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXNFRQBOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0loRUUATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJYUVFAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWNFRQBOMTBlbXNjcmlwdGVuM3ZhbEUATlN0M19fMjEyYmFzaWNfc3RyaW5nSURpTlNfMTFjaGFyX3RyYWl0c0lEaUVFTlNfOWFsbG9jYXRvcklEaUVFRUUATlN0M19fMjIxX19iYXNpY19zdHJpbmdfY29tbW9uSUxiMUVFRQBOU3QzX18yMTJiYXNpY19zdHJpbmdJRHNOU18xMWNoYXJfdHJhaXRzSURzRUVOU185YWxsb2NhdG9ySURzRUVFRQBOU3QzX18yMTJiYXNpY19zdHJpbmdJd05TXzExY2hhcl90cmFpdHNJd0VFTlNfOWFsbG9jYXRvckl3RUVFRQBOU3QzX18yMTJiYXNpY19zdHJpbmdJaE5TXzExY2hhcl90cmFpdHNJaEVFTlNfOWFsbG9jYXRvckloRUVFRQBOU3QzX18yMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFRQAtKyAgIDBYMHgAKG51bGwpAC0wWCswWCAwWC0weCsweCAweABpbmYASU5GAG5hbgBOQU4ALgB0ZXJtaW5hdGluZyB3aXRoICVzIGV4Y2VwdGlvbiBvZiB0eXBlICVzOiAlcwB0ZXJtaW5hdGluZyB3aXRoICVzIGV4Y2VwdGlvbiBvZiB0eXBlICVzAHRlcm1pbmF0aW5nIHdpdGggJXMgZm9yZWlnbiBleGNlcHRpb24AdGVybWluYXRpbmcAdW5jYXVnaHQAU3Q5ZXhjZXB0aW9uAE4xMF9fY3h4YWJpdjExNl9fc2hpbV90eXBlX2luZm9FAFN0OXR5cGVfaW5mbwBOMTBfX2N4eGFiaXYxMjBfX3NpX2NsYXNzX3R5cGVfaW5mb0UATjEwX19jeHhhYml2MTE3X19jbGFzc190eXBlX2luZm9FAHRlcm1pbmF0ZV9oYW5kbGVyIHVuZXhwZWN0ZWRseSByZXR1cm5lZABzdGQ6OmJhZF9hbGxvYwBTdDliYWRfYWxsb2MAU3QxMWxvZ2ljX2Vycm9yAFN0MTNydW50aW1lX2Vycm9yAFN0MTJsZW5ndGhfZXJyb3IAU3QxMm91dF9vZl9yYW5nZQBOMTBfX2N4eGFiaXYxMTdfX3BiYXNlX3R5cGVfaW5mb0UATjEwX19jeHhhYml2MTE5X19wb2ludGVyX3R5cGVfaW5mb0UATjEwX19jeHhhYml2MTIwX19mdW5jdGlvbl90eXBlX2luZm9FAE4xMF9fY3h4YWJpdjEyOV9fcG9pbnRlcl90b19tZW1iZXJfdHlwZV9pbmZvRQBQdXJlIHZpcnR1YWwgZnVuY3Rpb24gY2FsbGVkIQBOMTBfX2N4eGFiaXYxMjNfX2Z1bmRhbWVudGFsX3R5cGVfaW5mb0UAdgBEbgBiAGMAaABhAHMAdABpAGoAbABtAGYAZABOMTBfX2N4eGFiaXYxMjFfX3ZtaV9jbGFzc190eXBlX2luZm9FAF9fY3hhX2d1YXJkX2FjcXVpcmUgZGV0ZWN0ZWQgcmVjdXJzaXZlIGluaXRpYWxpemF0aW9uAHN0ZDo6YmFkX2Z1bmN0aW9uX2NhbGwATlN0M19fMjE3YmFkX2Z1bmN0aW9uX2NhbGxFAE5TdDNfXzIxNF9fc2hhcmVkX2NvdW50RQBOU3QzX18yMTlfX3NoYXJlZF93ZWFrX2NvdW50RQBtdXRleCBsb2NrIGZhaWxlZABiYXNpY19zdHJpbmcAdW5zcGVjaWZpZWQgZ2VuZXJpY19jYXRlZ29yeSBlcnJvcgBVbmtub3duIGVycm9yICVkAGdlbmVyaWMATlN0M19fMjI0X19nZW5lcmljX2Vycm9yX2NhdGVnb3J5RQBOU3QzX18yMTJfX2RvX21lc3NhZ2VFAE5TdDNfXzIxNGVycm9yX2NhdGVnb3J5RQB1bnNwZWNpZmllZCBzeXN0ZW1fY2F0ZWdvcnkgZXJyb3IAc3lzdGVtAE5TdDNfXzIyM19fc3lzdGVtX2Vycm9yX2NhdGVnb3J5RQBOU3QzX18yMTJzeXN0ZW1fZXJyb3JFADogAHZlY3Rvcg==';\n    var tempDoublePtr = 22368;\n    function ___cxa_allocate_exception(size) {\n        return _malloc(size);\n    }\n    var ___exception_infos = {};\n    function ___exception_addRef(ptr) {\n        if (!ptr)\n            return;\n        var info = ___exception_infos[ptr];\n        info.refcount++;\n    }\n    function ___exception_deAdjust(adjusted) {\n        if (!adjusted || ___exception_infos[adjusted])\n            return adjusted;\n        for (var key in ___exception_infos) {\n            var ptr = +key;\n            var adj = ___exception_infos[ptr].adjusted;\n            var len = adj.length;\n            for (var i = 0; i < len; i++) {\n                if (adj[i] === adjusted) {\n                    return ptr;\n                }\n            }\n        }\n        return adjusted;\n    }\n    function ___cxa_begin_catch(ptr) {\n        var info = ___exception_infos[ptr];\n        if (info && !info.caught) {\n            info.caught = true;\n            __ZSt18uncaught_exceptionv.uncaught_exceptions--;\n        }\n        if (info)\n            info.rethrown = false;\n        ___exception_addRef(___exception_deAdjust(ptr));\n        return ptr;\n    }\n    function ___cxa_throw(ptr, type, destructor) {\n        ___exception_infos[ptr] = {\n            ptr: ptr,\n            adjusted: [ptr],\n            type: type,\n            destructor: destructor,\n            refcount: 0,\n            caught: false,\n            rethrown: false\n        };\n        if (!('uncaught_exception' in __ZSt18uncaught_exceptionv)) {\n            __ZSt18uncaught_exceptionv.uncaught_exceptions = 1;\n        }\n        else {\n            __ZSt18uncaught_exceptionv.uncaught_exceptions++;\n        }\n        throw ptr;\n    }\n    function ___cxa_uncaught_exceptions() {\n        return __ZSt18uncaught_exceptionv.uncaught_exceptions;\n    }\n    function ___gxx_personality_v0() { }\n    function getShiftFromSize(size) {\n        switch (size) {\n            case 1:\n                return 0;\n            case 2:\n                return 1;\n            case 4:\n                return 2;\n            case 8:\n                return 3;\n            default:\n                throw new TypeError('Unknown type size: ' + size);\n        }\n    }\n    function embind_init_charCodes() {\n        var codes = new Array(256);\n        for (var i = 0; i < 256; ++i) {\n            codes[i] = String.fromCharCode(i);\n        }\n        embind_charCodes = codes;\n    }\n    var embind_charCodes = undefined;\n    function readLatin1String(ptr) {\n        var ret = '';\n        var c = ptr;\n        while (HEAPU8[c]) {\n            ret += embind_charCodes[HEAPU8[c++]];\n        }\n        return ret;\n    }\n    var awaitingDependencies = {};\n    var registeredTypes = {};\n    var typeDependencies = {};\n    var char_0 = 48;\n    var char_9 = 57;\n    function makeLegalFunctionName(name) {\n        if (undefined === name) {\n            return '_unknown';\n        }\n        name = name.replace(/[^a-zA-Z0-9_]/g, '$');\n        var f = name.charCodeAt(0);\n        if (f >= char_0 && f <= char_9) {\n            return '_' + name;\n        }\n        else {\n            return name;\n        }\n    }\n    function createNamedFunction(name, body) {\n        name = makeLegalFunctionName(name);\n        return new Function('body', 'return function ' +\n            name +\n            '() {\\n' +\n            '    \"use strict\";' +\n            '    return body.apply(this, arguments);\\n' +\n            '};\\n')(body);\n    }\n    function extendError(baseErrorType, errorName) {\n        var errorClass = createNamedFunction(errorName, function (message) {\n            this.name = errorName;\n            this.message = message;\n            var stack = new Error(message).stack;\n            if (stack !== undefined) {\n                this.stack = this.toString() + '\\n' + stack.replace(/^Error(:[^\\n]*)?\\n/, '');\n            }\n        });\n        errorClass.prototype = Object.create(baseErrorType.prototype);\n        errorClass.prototype.constructor = errorClass;\n        errorClass.prototype.toString = function () {\n            if (this.message === undefined) {\n                return this.name;\n            }\n            else {\n                return this.name + ': ' + this.message;\n            }\n        };\n        return errorClass;\n    }\n    var BindingError = undefined;\n    function throwBindingError(message) {\n        throw new BindingError(message);\n    }\n    var InternalError = undefined;\n    function throwInternalError(message) {\n        throw new InternalError(message);\n    }\n    function whenDependentTypesAreResolved(myTypes, dependentTypes, getTypeConverters) {\n        myTypes.forEach(function (type) {\n            typeDependencies[type] = dependentTypes;\n        });\n        function onComplete(typeConverters) {\n            var myTypeConverters = getTypeConverters(typeConverters);\n            if (myTypeConverters.length !== myTypes.length) {\n                throwInternalError('Mismatched type converter count');\n            }\n            for (var i = 0; i < myTypes.length; ++i) {\n                registerType(myTypes[i], myTypeConverters[i]);\n            }\n        }\n        var typeConverters = new Array(dependentTypes.length);\n        var unregisteredTypes = [];\n        var registered = 0;\n        dependentTypes.forEach(function (dt, i) {\n            if (registeredTypes.hasOwnProperty(dt)) {\n                typeConverters[i] = registeredTypes[dt];\n            }\n            else {\n                unregisteredTypes.push(dt);\n                if (!awaitingDependencies.hasOwnProperty(dt)) {\n                    awaitingDependencies[dt] = [];\n                }\n                awaitingDependencies[dt].push(function () {\n                    typeConverters[i] = registeredTypes[dt];\n                    ++registered;\n                    if (registered === unregisteredTypes.length) {\n                        onComplete(typeConverters);\n                    }\n                });\n            }\n        });\n        if (0 === unregisteredTypes.length) {\n            onComplete(typeConverters);\n        }\n    }\n    function registerType(rawType, registeredInstance, options) {\n        options = options || {};\n        if (!('argPackAdvance' in registeredInstance)) {\n            throw new TypeError('registerType registeredInstance requires argPackAdvance');\n        }\n        var name = registeredInstance.name;\n        if (!rawType) {\n            throwBindingError('type \"' + name + '\" must have a positive integer typeid pointer');\n        }\n        if (registeredTypes.hasOwnProperty(rawType)) {\n            if (options.ignoreDuplicateRegistrations) {\n                return;\n            }\n            else {\n                throwBindingError(\"Cannot register type '\" + name + \"' twice\");\n            }\n        }\n        registeredTypes[rawType] = registeredInstance;\n        delete typeDependencies[rawType];\n        if (awaitingDependencies.hasOwnProperty(rawType)) {\n            var callbacks = awaitingDependencies[rawType];\n            delete awaitingDependencies[rawType];\n            callbacks.forEach(function (cb) {\n                cb();\n            });\n        }\n    }\n    function __embind_register_bool(rawType, name, size, trueValue, falseValue) {\n        var shift = getShiftFromSize(size);\n        name = readLatin1String(name);\n        registerType(rawType, {\n            name: name,\n            fromWireType: function (wt) {\n                return !!wt;\n            },\n            toWireType: function (destructors, o) {\n                return o ? trueValue : falseValue;\n            },\n            argPackAdvance: 8,\n            readValueFromPointer: function (pointer) {\n                var heap;\n                if (size === 1) {\n                    heap = HEAP8;\n                }\n                else if (size === 2) {\n                    heap = HEAP16;\n                }\n                else if (size === 4) {\n                    heap = HEAP32;\n                }\n                else {\n                    throw new TypeError('Unknown boolean type size: ' + name);\n                }\n                return this['fromWireType'](heap[pointer >> shift]);\n            },\n            destructorFunction: null\n        });\n    }\n    function ClassHandle_isAliasOf(other) {\n        if (!(this instanceof ClassHandle)) {\n            return false;\n        }\n        if (!(other instanceof ClassHandle)) {\n            return false;\n        }\n        var leftClass = this.$$.ptrType.registeredClass;\n        var left = this.$$.ptr;\n        var rightClass = other.$$.ptrType.registeredClass;\n        var right = other.$$.ptr;\n        while (leftClass.baseClass) {\n            left = leftClass.upcast(left);\n            leftClass = leftClass.baseClass;\n        }\n        while (rightClass.baseClass) {\n            right = rightClass.upcast(right);\n            rightClass = rightClass.baseClass;\n        }\n        return leftClass === rightClass && left === right;\n    }\n    function shallowCopyInternalPointer(o) {\n        return {\n            count: o.count,\n            deleteScheduled: o.deleteScheduled,\n            preservePointerOnDelete: o.preservePointerOnDelete,\n            ptr: o.ptr,\n            ptrType: o.ptrType,\n            smartPtr: o.smartPtr,\n            smartPtrType: o.smartPtrType\n        };\n    }\n    function throwInstanceAlreadyDeleted(obj) {\n        function getInstanceTypeName(handle) {\n            return handle.$$.ptrType.registeredClass.name;\n        }\n        throwBindingError(getInstanceTypeName(obj) + ' instance already deleted');\n    }\n    var finalizationGroup = false;\n    function detachFinalizer(handle) { }\n    function runDestructor($$) {\n        if ($$.smartPtr) {\n            $$.smartPtrType.rawDestructor($$.smartPtr);\n        }\n        else {\n            $$.ptrType.registeredClass.rawDestructor($$.ptr);\n        }\n    }\n    function releaseClassHandle($$) {\n        $$.count.value -= 1;\n        var toDelete = 0 === $$.count.value;\n        if (toDelete) {\n            runDestructor($$);\n        }\n    }\n    function attachFinalizer(handle) {\n        if ('undefined' === typeof FinalizationGroup) {\n            attachFinalizer = function (handle) {\n                return handle;\n            };\n            return handle;\n        }\n        finalizationGroup = new FinalizationGroup(function (iter) {\n            for (var result = iter.next(); !result.done; result = iter.next()) {\n                var $$ = result.value;\n                if (!$$.ptr) {\n                    console.warn('object already deleted: ' + $$.ptr);\n                }\n                else {\n                    releaseClassHandle($$);\n                }\n            }\n        });\n        attachFinalizer = function (handle) {\n            finalizationGroup.register(handle, handle.$$, handle.$$);\n            return handle;\n        };\n        detachFinalizer = function (handle) {\n            finalizationGroup.unregister(handle.$$);\n        };\n        return attachFinalizer(handle);\n    }\n    function ClassHandle_clone() {\n        if (!this.$$.ptr) {\n            throwInstanceAlreadyDeleted(this);\n        }\n        if (this.$$.preservePointerOnDelete) {\n            this.$$.count.value += 1;\n            return this;\n        }\n        else {\n            var clone = attachFinalizer(Object.create(Object.getPrototypeOf(this), {\n                $$: {\n                    value: shallowCopyInternalPointer(this.$$)\n                }\n            }));\n            clone.$$.count.value += 1;\n            clone.$$.deleteScheduled = false;\n            return clone;\n        }\n    }\n    function ClassHandle_delete() {\n        if (!this.$$.ptr) {\n            throwInstanceAlreadyDeleted(this);\n        }\n        if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) {\n            throwBindingError('Object already scheduled for deletion');\n        }\n        detachFinalizer(this);\n        releaseClassHandle(this.$$);\n        if (!this.$$.preservePointerOnDelete) {\n            this.$$.smartPtr = undefined;\n            this.$$.ptr = undefined;\n        }\n    }\n    function ClassHandle_isDeleted() {\n        return !this.$$.ptr;\n    }\n    var delayFunction = undefined;\n    var deletionQueue = [];\n    function flushPendingDeletes() {\n        while (deletionQueue.length) {\n            var obj = deletionQueue.pop();\n            obj.$$.deleteScheduled = false;\n            obj['delete']();\n        }\n    }\n    function ClassHandle_deleteLater() {\n        if (!this.$$.ptr) {\n            throwInstanceAlreadyDeleted(this);\n        }\n        if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) {\n            throwBindingError('Object already scheduled for deletion');\n        }\n        deletionQueue.push(this);\n        if (deletionQueue.length === 1 && delayFunction) {\n            delayFunction(flushPendingDeletes);\n        }\n        this.$$.deleteScheduled = true;\n        return this;\n    }\n    function init_ClassHandle() {\n        ClassHandle.prototype['isAliasOf'] = ClassHandle_isAliasOf;\n        ClassHandle.prototype['clone'] = ClassHandle_clone;\n        ClassHandle.prototype['delete'] = ClassHandle_delete;\n        ClassHandle.prototype['isDeleted'] = ClassHandle_isDeleted;\n        ClassHandle.prototype['deleteLater'] = ClassHandle_deleteLater;\n    }\n    function ClassHandle() { }\n    var registeredPointers = {};\n    function ensureOverloadTable(proto, methodName, humanName) {\n        if (undefined === proto[methodName].overloadTable) {\n            var prevFunc = proto[methodName];\n            proto[methodName] = function () {\n                if (!proto[methodName].overloadTable.hasOwnProperty(arguments.length)) {\n                    throwBindingError(\"Function '\" +\n                        humanName +\n                        \"' called with an invalid number of arguments (\" +\n                        arguments.length +\n                        ') - expects one of (' +\n                        proto[methodName].overloadTable +\n                        ')!');\n                }\n                return proto[methodName].overloadTable[arguments.length].apply(this, arguments);\n            };\n            proto[methodName].overloadTable = [];\n            proto[methodName].overloadTable[prevFunc.argCount] = prevFunc;\n        }\n    }\n    function exposePublicSymbol(name, value, numArguments) {\n        if (Module.hasOwnProperty(name)) {\n            if (undefined === numArguments ||\n                (undefined !== Module[name].overloadTable &&\n                    undefined !== Module[name].overloadTable[numArguments])) {\n                throwBindingError(\"Cannot register public name '\" + name + \"' twice\");\n            }\n            ensureOverloadTable(Module, name, name);\n            if (Module.hasOwnProperty(numArguments)) {\n                throwBindingError('Cannot register multiple overloads of a function with the same number of arguments (' +\n                    numArguments +\n                    ')!');\n            }\n            Module[name].overloadTable[numArguments] = value;\n        }\n        else {\n            Module[name] = value;\n            if (undefined !== numArguments) {\n                Module[name].numArguments = numArguments;\n            }\n        }\n    }\n    function RegisteredClass(name, constructor, instancePrototype, rawDestructor, baseClass, getActualType, upcast, downcast) {\n        this.name = name;\n        this.constructor = constructor;\n        this.instancePrototype = instancePrototype;\n        this.rawDestructor = rawDestructor;\n        this.baseClass = baseClass;\n        this.getActualType = getActualType;\n        this.upcast = upcast;\n        this.downcast = downcast;\n        this.pureVirtualFunctions = [];\n    }\n    function upcastPointer(ptr, ptrClass, desiredClass) {\n        while (ptrClass !== desiredClass) {\n            if (!ptrClass.upcast) {\n                throwBindingError('Expected null or instance of ' +\n                    desiredClass.name +\n                    ', got an instance of ' +\n                    ptrClass.name);\n            }\n            ptr = ptrClass.upcast(ptr);\n            ptrClass = ptrClass.baseClass;\n        }\n        return ptr;\n    }\n    function constNoSmartPtrRawPointerToWireType(destructors, handle) {\n        if (handle === null) {\n            if (this.isReference) {\n                throwBindingError('null is not a valid ' + this.name);\n            }\n            return 0;\n        }\n        if (!handle.$$) {\n            throwBindingError('Cannot pass \"' + _embind_repr(handle) + '\" as a ' + this.name);\n        }\n        if (!handle.$$.ptr) {\n            throwBindingError('Cannot pass deleted object as a pointer of type ' + this.name);\n        }\n        var handleClass = handle.$$.ptrType.registeredClass;\n        var ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass);\n        return ptr;\n    }\n    function genericPointerToWireType(destructors, handle) {\n        var ptr;\n        if (handle === null) {\n            if (this.isReference) {\n                throwBindingError('null is not a valid ' + this.name);\n            }\n            if (this.isSmartPointer) {\n                ptr = this.rawConstructor();\n                if (destructors !== null) {\n                    destructors.push(this.rawDestructor, ptr);\n                }\n                return ptr;\n            }\n            else {\n                return 0;\n            }\n        }\n        if (!handle.$$) {\n            throwBindingError('Cannot pass \"' + _embind_repr(handle) + '\" as a ' + this.name);\n        }\n        if (!handle.$$.ptr) {\n            throwBindingError('Cannot pass deleted object as a pointer of type ' + this.name);\n        }\n        if (!this.isConst && handle.$$.ptrType.isConst) {\n            throwBindingError('Cannot convert argument of type ' +\n                (handle.$$.smartPtrType ? handle.$$.smartPtrType.name : handle.$$.ptrType.name) +\n                ' to parameter type ' +\n                this.name);\n        }\n        var handleClass = handle.$$.ptrType.registeredClass;\n        ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass);\n        if (this.isSmartPointer) {\n            if (undefined === handle.$$.smartPtr) {\n                throwBindingError('Passing raw pointer to smart pointer is illegal');\n            }\n            switch (this.sharingPolicy) {\n                case 0:\n                    if (handle.$$.smartPtrType === this) {\n                        ptr = handle.$$.smartPtr;\n                    }\n                    else {\n                        throwBindingError('Cannot convert argument of type ' +\n                            (handle.$$.smartPtrType ? handle.$$.smartPtrType.name : handle.$$.ptrType.name) +\n                            ' to parameter type ' +\n                            this.name);\n                    }\n                    break;\n                case 1:\n                    ptr = handle.$$.smartPtr;\n                    break;\n                case 2:\n                    if (handle.$$.smartPtrType === this) {\n                        ptr = handle.$$.smartPtr;\n                    }\n                    else {\n                        var clonedHandle = handle['clone']();\n                        ptr = this.rawShare(ptr, __emval_register(function () {\n                            clonedHandle['delete']();\n                        }));\n                        if (destructors !== null) {\n                            destructors.push(this.rawDestructor, ptr);\n                        }\n                    }\n                    break;\n                default:\n                    throwBindingError('Unsupporting sharing policy');\n            }\n        }\n        return ptr;\n    }\n    function nonConstNoSmartPtrRawPointerToWireType(destructors, handle) {\n        if (handle === null) {\n            if (this.isReference) {\n                throwBindingError('null is not a valid ' + this.name);\n            }\n            return 0;\n        }\n        if (!handle.$$) {\n            throwBindingError('Cannot pass \"' + _embind_repr(handle) + '\" as a ' + this.name);\n        }\n        if (!handle.$$.ptr) {\n            throwBindingError('Cannot pass deleted object as a pointer of type ' + this.name);\n        }\n        if (handle.$$.ptrType.isConst) {\n            throwBindingError('Cannot convert argument of type ' +\n                handle.$$.ptrType.name +\n                ' to parameter type ' +\n                this.name);\n        }\n        var handleClass = handle.$$.ptrType.registeredClass;\n        var ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass);\n        return ptr;\n    }\n    function simpleReadValueFromPointer(pointer) {\n        return this['fromWireType'](HEAPU32[pointer >> 2]);\n    }\n    function RegisteredPointer_getPointee(ptr) {\n        if (this.rawGetPointee) {\n            ptr = this.rawGetPointee(ptr);\n        }\n        return ptr;\n    }\n    function RegisteredPointer_destructor(ptr) {\n        if (this.rawDestructor) {\n            this.rawDestructor(ptr);\n        }\n    }\n    function RegisteredPointer_deleteObject(handle) {\n        if (handle !== null) {\n            handle['delete']();\n        }\n    }\n    function downcastPointer(ptr, ptrClass, desiredClass) {\n        if (ptrClass === desiredClass) {\n            return ptr;\n        }\n        if (undefined === desiredClass.baseClass) {\n            return null;\n        }\n        var rv = downcastPointer(ptr, ptrClass, desiredClass.baseClass);\n        if (rv === null) {\n            return null;\n        }\n        return desiredClass.downcast(rv);\n    }\n    function getInheritedInstanceCount() {\n        return Object.keys(registeredInstances).length;\n    }\n    function getLiveInheritedInstances() {\n        var rv = [];\n        for (var k in registeredInstances) {\n            if (registeredInstances.hasOwnProperty(k)) {\n                rv.push(registeredInstances[k]);\n            }\n        }\n        return rv;\n    }\n    function setDelayFunction(fn) {\n        delayFunction = fn;\n        if (deletionQueue.length && delayFunction) {\n            delayFunction(flushPendingDeletes);\n        }\n    }\n    function init_embind() {\n        Module['getInheritedInstanceCount'] = getInheritedInstanceCount;\n        Module['getLiveInheritedInstances'] = getLiveInheritedInstances;\n        Module['flushPendingDeletes'] = flushPendingDeletes;\n        Module['setDelayFunction'] = setDelayFunction;\n    }\n    var registeredInstances = {};\n    function getBasestPointer(class_, ptr) {\n        if (ptr === undefined) {\n            throwBindingError('ptr should not be undefined');\n        }\n        while (class_.baseClass) {\n            ptr = class_.upcast(ptr);\n            class_ = class_.baseClass;\n        }\n        return ptr;\n    }\n    function getInheritedInstance(class_, ptr) {\n        ptr = getBasestPointer(class_, ptr);\n        return registeredInstances[ptr];\n    }\n    function makeClassHandle(prototype, record) {\n        if (!record.ptrType || !record.ptr) {\n            throwInternalError('makeClassHandle requires ptr and ptrType');\n        }\n        var hasSmartPtrType = !!record.smartPtrType;\n        var hasSmartPtr = !!record.smartPtr;\n        if (hasSmartPtrType !== hasSmartPtr) {\n            throwInternalError('Both smartPtrType and smartPtr must be specified');\n        }\n        record.count = {\n            value: 1\n        };\n        return attachFinalizer(Object.create(prototype, {\n            $$: {\n                value: record\n            }\n        }));\n    }\n    function RegisteredPointer_fromWireType(ptr) {\n        var rawPointer = this.getPointee(ptr);\n        if (!rawPointer) {\n            this.destructor(ptr);\n            return null;\n        }\n        var registeredInstance = getInheritedInstance(this.registeredClass, rawPointer);\n        if (undefined !== registeredInstance) {\n            if (0 === registeredInstance.$$.count.value) {\n                registeredInstance.$$.ptr = rawPointer;\n                registeredInstance.$$.smartPtr = ptr;\n                return registeredInstance['clone']();\n            }\n            else {\n                var rv = registeredInstance['clone']();\n                this.destructor(ptr);\n                return rv;\n            }\n        }\n        function makeDefaultHandle() {\n            if (this.isSmartPointer) {\n                return makeClassHandle(this.registeredClass.instancePrototype, {\n                    ptrType: this.pointeeType,\n                    ptr: rawPointer,\n                    smartPtrType: this,\n                    smartPtr: ptr\n                });\n            }\n            else {\n                return makeClassHandle(this.registeredClass.instancePrototype, {\n                    ptrType: this,\n                    ptr: ptr\n                });\n            }\n        }\n        var actualType = this.registeredClass.getActualType(rawPointer);\n        var registeredPointerRecord = registeredPointers[actualType];\n        if (!registeredPointerRecord) {\n            return makeDefaultHandle.call(this);\n        }\n        var toType;\n        if (this.isConst) {\n            toType = registeredPointerRecord.constPointerType;\n        }\n        else {\n            toType = registeredPointerRecord.pointerType;\n        }\n        var dp = downcastPointer(rawPointer, this.registeredClass, toType.registeredClass);\n        if (dp === null) {\n            return makeDefaultHandle.call(this);\n        }\n        if (this.isSmartPointer) {\n            return makeClassHandle(toType.registeredClass.instancePrototype, {\n                ptrType: toType,\n                ptr: dp,\n                smartPtrType: this,\n                smartPtr: ptr\n            });\n        }\n        else {\n            return makeClassHandle(toType.registeredClass.instancePrototype, {\n                ptrType: toType,\n                ptr: dp\n            });\n        }\n    }\n    function init_RegisteredPointer() {\n        RegisteredPointer.prototype.getPointee = RegisteredPointer_getPointee;\n        RegisteredPointer.prototype.destructor = RegisteredPointer_destructor;\n        RegisteredPointer.prototype['argPackAdvance'] = 8;\n        RegisteredPointer.prototype['readValueFromPointer'] = simpleReadValueFromPointer;\n        RegisteredPointer.prototype['deleteObject'] = RegisteredPointer_deleteObject;\n        RegisteredPointer.prototype['fromWireType'] = RegisteredPointer_fromWireType;\n    }\n    function RegisteredPointer(name, registeredClass, isReference, isConst, isSmartPointer, pointeeType, sharingPolicy, rawGetPointee, rawConstructor, rawShare, rawDestructor) {\n        this.name = name;\n        this.registeredClass = registeredClass;\n        this.isReference = isReference;\n        this.isConst = isConst;\n        this.isSmartPointer = isSmartPointer;\n        this.pointeeType = pointeeType;\n        this.sharingPolicy = sharingPolicy;\n        this.rawGetPointee = rawGetPointee;\n        this.rawConstructor = rawConstructor;\n        this.rawShare = rawShare;\n        this.rawDestructor = rawDestructor;\n        if (!isSmartPointer && registeredClass.baseClass === undefined) {\n            if (isConst) {\n                this['toWireType'] = constNoSmartPtrRawPointerToWireType;\n                this.destructorFunction = null;\n            }\n            else {\n                this['toWireType'] = nonConstNoSmartPtrRawPointerToWireType;\n                this.destructorFunction = null;\n            }\n        }\n        else {\n            this['toWireType'] = genericPointerToWireType;\n        }\n    }\n    function replacePublicSymbol(name, value, numArguments) {\n        if (!Module.hasOwnProperty(name)) {\n            throwInternalError('Replacing nonexistant public symbol');\n        }\n        if (undefined !== Module[name].overloadTable && undefined !== numArguments) {\n            Module[name].overloadTable[numArguments] = value;\n        }\n        else {\n            Module[name] = value;\n            Module[name].argCount = numArguments;\n        }\n    }\n    function embind__requireFunction(signature, rawFunction) {\n        signature = readLatin1String(signature);\n        function makeDynCaller(dynCall) {\n            var args = [];\n            for (var i = 1; i < signature.length; ++i) {\n                args.push('a' + i);\n            }\n            var name = 'dynCall_' + signature + '_' + rawFunction;\n            var body = 'return function ' + name + '(' + args.join(', ') + ') {\\n';\n            body +=\n                '    return dynCall(rawFunction' + (args.length ? ', ' : '') + args.join(', ') + ');\\n';\n            body += '};\\n';\n            return new Function('dynCall', 'rawFunction', body)(dynCall, rawFunction);\n        }\n        var dc = Module['dynCall_' + signature];\n        var fp = makeDynCaller(dc);\n        if (typeof fp !== 'function') {\n            throwBindingError('unknown function pointer with signature ' + signature + ': ' + rawFunction);\n        }\n        return fp;\n    }\n    var UnboundTypeError = undefined;\n    function getTypeName(type) {\n        var ptr = ___getTypeName(type);\n        var rv = readLatin1String(ptr);\n        _free(ptr);\n        return rv;\n    }\n    function throwUnboundTypeError(message, types) {\n        var unboundTypes = [];\n        var seen = {};\n        function visit(type) {\n            if (seen[type]) {\n                return;\n            }\n            if (registeredTypes[type]) {\n                return;\n            }\n            if (typeDependencies[type]) {\n                typeDependencies[type].forEach(visit);\n                return;\n            }\n            unboundTypes.push(type);\n            seen[type] = true;\n        }\n        types.forEach(visit);\n        throw new UnboundTypeError(message + ': ' + unboundTypes.map(getTypeName).join([', ']));\n    }\n    function __embind_register_class(rawType, rawPointerType, rawConstPointerType, baseClassRawType, getActualTypeSignature, getActualType, upcastSignature, upcast, downcastSignature, downcast, name, destructorSignature, rawDestructor) {\n        name = readLatin1String(name);\n        getActualType = embind__requireFunction(getActualTypeSignature, getActualType);\n        if (upcast) {\n            upcast = embind__requireFunction(upcastSignature, upcast);\n        }\n        if (downcast) {\n            downcast = embind__requireFunction(downcastSignature, downcast);\n        }\n        rawDestructor = embind__requireFunction(destructorSignature, rawDestructor);\n        var legalFunctionName = makeLegalFunctionName(name);\n        exposePublicSymbol(legalFunctionName, function () {\n            throwUnboundTypeError('Cannot construct ' + name + ' due to unbound types', [\n                baseClassRawType\n            ]);\n        });\n        whenDependentTypesAreResolved([rawType, rawPointerType, rawConstPointerType], baseClassRawType ? [baseClassRawType] : [], function (base) {\n            base = base[0];\n            var baseClass;\n            var basePrototype;\n            if (baseClassRawType) {\n                baseClass = base.registeredClass;\n                basePrototype = baseClass.instancePrototype;\n            }\n            else {\n                basePrototype = ClassHandle.prototype;\n            }\n            var constructor = createNamedFunction(legalFunctionName, function () {\n                if (Object.getPrototypeOf(this) !== instancePrototype) {\n                    throw new BindingError(\"Use 'new' to construct \" + name);\n                }\n                if (undefined === registeredClass.constructor_body) {\n                    throw new BindingError(name + ' has no accessible constructor');\n                }\n                var body = registeredClass.constructor_body[arguments.length];\n                if (undefined === body) {\n                    throw new BindingError('Tried to invoke ctor of ' +\n                        name +\n                        ' with invalid number of parameters (' +\n                        arguments.length +\n                        ') - expected (' +\n                        Object.keys(registeredClass.constructor_body).toString() +\n                        ') parameters instead!');\n                }\n                return body.apply(this, arguments);\n            });\n            var instancePrototype = Object.create(basePrototype, {\n                constructor: {\n                    value: constructor\n                }\n            });\n            constructor.prototype = instancePrototype;\n            var registeredClass = new RegisteredClass(name, constructor, instancePrototype, rawDestructor, baseClass, getActualType, upcast, downcast);\n            var referenceConverter = new RegisteredPointer(name, registeredClass, true, false, false);\n            var pointerConverter = new RegisteredPointer(name + '*', registeredClass, false, false, false);\n            var constPointerConverter = new RegisteredPointer(name + ' const*', registeredClass, false, true, false);\n            registeredPointers[rawType] = {\n                pointerType: pointerConverter,\n                constPointerType: constPointerConverter\n            };\n            replacePublicSymbol(legalFunctionName, constructor);\n            return [referenceConverter, pointerConverter, constPointerConverter];\n        });\n    }\n    function heap32VectorToArray(count, firstElement) {\n        var array = [];\n        for (var i = 0; i < count; i++) {\n            array.push(HEAP32[(firstElement >> 2) + i]);\n        }\n        return array;\n    }\n    function runDestructors(destructors) {\n        while (destructors.length) {\n            var ptr = destructors.pop();\n            var del = destructors.pop();\n            del(ptr);\n        }\n    }\n    function __embind_register_class_constructor(rawClassType, argCount, rawArgTypesAddr, invokerSignature, invoker, rawConstructor) {\n        assert(argCount > 0);\n        var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);\n        invoker = embind__requireFunction(invokerSignature, invoker);\n        var args = [rawConstructor];\n        var destructors = [];\n        whenDependentTypesAreResolved([], [rawClassType], function (classType) {\n            classType = classType[0];\n            var humanName = 'constructor ' + classType.name;\n            if (undefined === classType.registeredClass.constructor_body) {\n                classType.registeredClass.constructor_body = [];\n            }\n            if (undefined !== classType.registeredClass.constructor_body[argCount - 1]) {\n                throw new BindingError('Cannot register multiple constructors with identical number of parameters (' +\n                    (argCount - 1) +\n                    \") for class '\" +\n                    classType.name +\n                    \"'! Overload resolution is currently only performed using the parameter count, not actual type info!\");\n            }\n            classType.registeredClass.constructor_body[argCount - 1] = function unboundTypeHandler() {\n                throwUnboundTypeError('Cannot construct ' + classType.name + ' due to unbound types', rawArgTypes);\n            };\n            whenDependentTypesAreResolved([], rawArgTypes, function (argTypes) {\n                classType.registeredClass.constructor_body[argCount - 1] = function constructor_body() {\n                    if (arguments.length !== argCount - 1) {\n                        throwBindingError(humanName +\n                            ' called with ' +\n                            arguments.length +\n                            ' arguments, expected ' +\n                            (argCount - 1));\n                    }\n                    destructors.length = 0;\n                    args.length = argCount;\n                    for (var i = 1; i < argCount; ++i) {\n                        args[i] = argTypes[i]['toWireType'](destructors, arguments[i - 1]);\n                    }\n                    var ptr = invoker.apply(null, args);\n                    runDestructors(destructors);\n                    return argTypes[0]['fromWireType'](ptr);\n                };\n                return [];\n            });\n            return [];\n        });\n    }\n    function new_(constructor, argumentList) {\n        if (!(constructor instanceof Function)) {\n            throw new TypeError('new_ called with constructor type ' + typeof constructor + ' which is not a function');\n        }\n        var dummy = createNamedFunction(constructor.name || 'unknownFunctionName', function () { });\n        dummy.prototype = constructor.prototype;\n        var obj = new dummy();\n        var r = constructor.apply(obj, argumentList);\n        return r instanceof Object ? r : obj;\n    }\n    function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc) {\n        var argCount = argTypes.length;\n        if (argCount < 2) {\n            throwBindingError(\"argTypes array size mismatch! Must at least get return value and 'this' types!\");\n        }\n        var isClassMethodFunc = argTypes[1] !== null && classType !== null;\n        var needsDestructorStack = false;\n        for (var i = 1; i < argTypes.length; ++i) {\n            if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) {\n                needsDestructorStack = true;\n                break;\n            }\n        }\n        var returns = argTypes[0].name !== 'void';\n        var argsList = '';\n        var argsListWired = '';\n        for (var i = 0; i < argCount - 2; ++i) {\n            argsList += (i !== 0 ? ', ' : '') + 'arg' + i;\n            argsListWired += (i !== 0 ? ', ' : '') + 'arg' + i + 'Wired';\n        }\n        var invokerFnBody = 'return function ' +\n            makeLegalFunctionName(humanName) +\n            '(' +\n            argsList +\n            ') {\\n' +\n            'if (arguments.length !== ' +\n            (argCount - 2) +\n            ') {\\n' +\n            \"throwBindingError('function \" +\n            humanName +\n            \" called with ' + arguments.length + ' arguments, expected \" +\n            (argCount - 2) +\n            \" args!');\\n\" +\n            '}\\n';\n        if (needsDestructorStack) {\n            invokerFnBody += 'var destructors = [];\\n';\n        }\n        var dtorStack = needsDestructorStack ? 'destructors' : 'null';\n        var args1 = ['throwBindingError', 'invoker', 'fn', 'runDestructors', 'retType', 'classParam'];\n        var args2 = [\n            throwBindingError,\n            cppInvokerFunc,\n            cppTargetFunc,\n            runDestructors,\n            argTypes[0],\n            argTypes[1]\n        ];\n        if (isClassMethodFunc) {\n            invokerFnBody += 'var thisWired = classParam.toWireType(' + dtorStack + ', this);\\n';\n        }\n        for (var i = 0; i < argCount - 2; ++i) {\n            invokerFnBody +=\n                'var arg' +\n                    i +\n                    'Wired = argType' +\n                    i +\n                    '.toWireType(' +\n                    dtorStack +\n                    ', arg' +\n                    i +\n                    '); // ' +\n                    argTypes[i + 2].name +\n                    '\\n';\n            args1.push('argType' + i);\n            args2.push(argTypes[i + 2]);\n        }\n        if (isClassMethodFunc) {\n            argsListWired = 'thisWired' + (argsListWired.length > 0 ? ', ' : '') + argsListWired;\n        }\n        invokerFnBody +=\n            (returns ? 'var rv = ' : '') +\n                'invoker(fn' +\n                (argsListWired.length > 0 ? ', ' : '') +\n                argsListWired +\n                ');\\n';\n        if (needsDestructorStack) {\n            invokerFnBody += 'runDestructors(destructors);\\n';\n        }\n        else {\n            for (var i = isClassMethodFunc ? 1 : 2; i < argTypes.length; ++i) {\n                var paramName = i === 1 ? 'thisWired' : 'arg' + (i - 2) + 'Wired';\n                if (argTypes[i].destructorFunction !== null) {\n                    invokerFnBody += paramName + '_dtor(' + paramName + '); // ' + argTypes[i].name + '\\n';\n                    args1.push(paramName + '_dtor');\n                    args2.push(argTypes[i].destructorFunction);\n                }\n            }\n        }\n        if (returns) {\n            invokerFnBody += 'var ret = retType.fromWireType(rv);\\n' + 'return ret;\\n';\n        }\n        invokerFnBody += '}\\n';\n        args1.push(invokerFnBody);\n        var invokerFunction = new_(Function, args1).apply(null, args2);\n        return invokerFunction;\n    }\n    function __embind_register_class_function(rawClassType, methodName, argCount, rawArgTypesAddr, invokerSignature, rawInvoker, context, isPureVirtual) {\n        var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);\n        methodName = readLatin1String(methodName);\n        rawInvoker = embind__requireFunction(invokerSignature, rawInvoker);\n        whenDependentTypesAreResolved([], [rawClassType], function (classType) {\n            classType = classType[0];\n            var humanName = classType.name + '.' + methodName;\n            if (isPureVirtual) {\n                classType.registeredClass.pureVirtualFunctions.push(methodName);\n            }\n            function unboundTypesHandler() {\n                throwUnboundTypeError('Cannot call ' + humanName + ' due to unbound types', rawArgTypes);\n            }\n            var proto = classType.registeredClass.instancePrototype;\n            var method = proto[methodName];\n            if (undefined === method ||\n                (undefined === method.overloadTable &&\n                    method.className !== classType.name &&\n                    method.argCount === argCount - 2)) {\n                unboundTypesHandler.argCount = argCount - 2;\n                unboundTypesHandler.className = classType.name;\n                proto[methodName] = unboundTypesHandler;\n            }\n            else {\n                ensureOverloadTable(proto, methodName, humanName);\n                proto[methodName].overloadTable[argCount - 2] = unboundTypesHandler;\n            }\n            whenDependentTypesAreResolved([], rawArgTypes, function (argTypes) {\n                var memberFunction = craftInvokerFunction(humanName, argTypes, classType, rawInvoker, context);\n                if (undefined === proto[methodName].overloadTable) {\n                    memberFunction.argCount = argCount - 2;\n                    proto[methodName] = memberFunction;\n                }\n                else {\n                    proto[methodName].overloadTable[argCount - 2] = memberFunction;\n                }\n                return [];\n            });\n            return [];\n        });\n    }\n    var emval_free_list = [];\n    var emval_handle_array = [\n        {},\n        {\n            value: undefined\n        },\n        {\n            value: null\n        },\n        {\n            value: true\n        },\n        {\n            value: false\n        }\n    ];\n    function __emval_decref(handle) {\n        if (handle > 4 && 0 === --emval_handle_array[handle].refcount) {\n            emval_handle_array[handle] = undefined;\n            emval_free_list.push(handle);\n        }\n    }\n    function count_emval_handles() {\n        var count = 0;\n        for (var i = 5; i < emval_handle_array.length; ++i) {\n            if (emval_handle_array[i] !== undefined) {\n                ++count;\n            }\n        }\n        return count;\n    }\n    function get_first_emval() {\n        for (var i = 5; i < emval_handle_array.length; ++i) {\n            if (emval_handle_array[i] !== undefined) {\n                return emval_handle_array[i];\n            }\n        }\n        return null;\n    }\n    function init_emval() {\n        Module['count_emval_handles'] = count_emval_handles;\n        Module['get_first_emval'] = get_first_emval;\n    }\n    function __emval_register(value) {\n        switch (value) {\n            case undefined: {\n                return 1;\n            }\n            case null: {\n                return 2;\n            }\n            case true: {\n                return 3;\n            }\n            case false: {\n                return 4;\n            }\n            default: {\n                var handle = emval_free_list.length ? emval_free_list.pop() : emval_handle_array.length;\n                emval_handle_array[handle] = {\n                    refcount: 1,\n                    value: value\n                };\n                return handle;\n            }\n        }\n    }\n    function __embind_register_emval(rawType, name) {\n        name = readLatin1String(name);\n        registerType(rawType, {\n            name: name,\n            fromWireType: function (handle) {\n                var rv = emval_handle_array[handle].value;\n                __emval_decref(handle);\n                return rv;\n            },\n            toWireType: function (destructors, value) {\n                return __emval_register(value);\n            },\n            argPackAdvance: 8,\n            readValueFromPointer: simpleReadValueFromPointer,\n            destructorFunction: null\n        });\n    }\n    function _embind_repr(v) {\n        if (v === null) {\n            return 'null';\n        }\n        var t = typeof v;\n        if (t === 'object' || t === 'array' || t === 'function') {\n            return v.toString();\n        }\n        else {\n            return '' + v;\n        }\n    }\n    function floatReadValueFromPointer(name, shift) {\n        switch (shift) {\n            case 2:\n                return function (pointer) {\n                    return this['fromWireType'](HEAPF32[pointer >> 2]);\n                };\n            case 3:\n                return function (pointer) {\n                    return this['fromWireType'](HEAPF64[pointer >> 3]);\n                };\n            default:\n                throw new TypeError('Unknown float type: ' + name);\n        }\n    }\n    function __embind_register_float(rawType, name, size) {\n        var shift = getShiftFromSize(size);\n        name = readLatin1String(name);\n        registerType(rawType, {\n            name: name,\n            fromWireType: function (value) {\n                return value;\n            },\n            toWireType: function (destructors, value) {\n                if (typeof value !== 'number' && typeof value !== 'boolean') {\n                    throw new TypeError('Cannot convert \"' + _embind_repr(value) + '\" to ' + this.name);\n                }\n                return value;\n            },\n            argPackAdvance: 8,\n            readValueFromPointer: floatReadValueFromPointer(name, shift),\n            destructorFunction: null\n        });\n    }\n    function integerReadValueFromPointer(name, shift, signed) {\n        switch (shift) {\n            case 0:\n                return signed\n                    ? function readS8FromPointer(pointer) {\n                        return HEAP8[pointer];\n                    }\n                    : function readU8FromPointer(pointer) {\n                        return HEAPU8[pointer];\n                    };\n            case 1:\n                return signed\n                    ? function readS16FromPointer(pointer) {\n                        return HEAP16[pointer >> 1];\n                    }\n                    : function readU16FromPointer(pointer) {\n                        return HEAPU16[pointer >> 1];\n                    };\n            case 2:\n                return signed\n                    ? function readS32FromPointer(pointer) {\n                        return HEAP32[pointer >> 2];\n                    }\n                    : function readU32FromPointer(pointer) {\n                        return HEAPU32[pointer >> 2];\n                    };\n            default:\n                throw new TypeError('Unknown integer type: ' + name);\n        }\n    }\n    function __embind_register_integer(primitiveType, name, size, minRange, maxRange) {\n        name = readLatin1String(name);\n        if (maxRange === -1) {\n            maxRange = 4294967295;\n        }\n        var shift = getShiftFromSize(size);\n        var fromWireType = function (value) {\n            return value;\n        };\n        if (minRange === 0) {\n            var bitshift = 32 - 8 * size;\n            fromWireType = function (value) {\n                return (value << bitshift) >>> bitshift;\n            };\n        }\n        var isUnsignedType = name.indexOf('unsigned') != -1;\n        registerType(primitiveType, {\n            name: name,\n            fromWireType: fromWireType,\n            toWireType: function (destructors, value) {\n                if (typeof value !== 'number' && typeof value !== 'boolean') {\n                    throw new TypeError('Cannot convert \"' + _embind_repr(value) + '\" to ' + this.name);\n                }\n                if (value < minRange || value > maxRange) {\n                    throw new TypeError('Passing a number \"' +\n                        _embind_repr(value) +\n                        '\" from JS side to C/C++ side to an argument of type \"' +\n                        name +\n                        '\", which is outside the valid range [' +\n                        minRange +\n                        ', ' +\n                        maxRange +\n                        ']!');\n                }\n                return isUnsignedType ? value >>> 0 : value | 0;\n            },\n            argPackAdvance: 8,\n            readValueFromPointer: integerReadValueFromPointer(name, shift, minRange !== 0),\n            destructorFunction: null\n        });\n    }\n    function __embind_register_memory_view(rawType, dataTypeIndex, name) {\n        var typeMapping = [\n            Int8Array,\n            Uint8Array,\n            Int16Array,\n            Uint16Array,\n            Int32Array,\n            Uint32Array,\n            Float32Array,\n            Float64Array\n        ];\n        var TA = typeMapping[dataTypeIndex];\n        function decodeMemoryView(handle) {\n            handle = handle >> 2;\n            var heap = HEAPU32;\n            var size = heap[handle];\n            var data = heap[handle + 1];\n            return new TA(buffer, data, size);\n        }\n        name = readLatin1String(name);\n        registerType(rawType, {\n            name: name,\n            fromWireType: decodeMemoryView,\n            argPackAdvance: 8,\n            readValueFromPointer: decodeMemoryView\n        }, {\n            ignoreDuplicateRegistrations: true\n        });\n    }\n    function __embind_register_std_string(rawType, name) {\n        name = readLatin1String(name);\n        var stdStringIsUTF8 = name === 'std::string';\n        registerType(rawType, {\n            name: name,\n            fromWireType: function (value) {\n                var length = HEAPU32[value >> 2];\n                var str;\n                if (stdStringIsUTF8) {\n                    var decodeStartPtr = value + 4;\n                    for (var i = 0; i <= length; ++i) {\n                        var currentBytePtr = value + 4 + i;\n                        if (HEAPU8[currentBytePtr] == 0 || i == length) {\n                            var maxRead = currentBytePtr - decodeStartPtr;\n                            var stringSegment = UTF8ToString(decodeStartPtr, maxRead);\n                            if (str === undefined) {\n                                str = stringSegment;\n                            }\n                            else {\n                                str += String.fromCharCode(0);\n                                str += stringSegment;\n                            }\n                            decodeStartPtr = currentBytePtr + 1;\n                        }\n                    }\n                }\n                else {\n                    var a = new Array(length);\n                    for (var i = 0; i < length; ++i) {\n                        a[i] = String.fromCharCode(HEAPU8[value + 4 + i]);\n                    }\n                    str = a.join('');\n                }\n                _free(value);\n                return str;\n            },\n            toWireType: function (destructors, value) {\n                if (value instanceof ArrayBuffer) {\n                    value = new Uint8Array(value);\n                }\n                var getLength;\n                var valueIsOfTypeString = typeof value === 'string';\n                if (!(valueIsOfTypeString ||\n                    value instanceof Uint8Array ||\n                    value instanceof Uint8ClampedArray ||\n                    value instanceof Int8Array)) {\n                    throwBindingError('Cannot pass non-string to std::string');\n                }\n                if (stdStringIsUTF8 && valueIsOfTypeString) {\n                    getLength = function () {\n                        return lengthBytesUTF8(value);\n                    };\n                }\n                else {\n                    getLength = function () {\n                        return value.length;\n                    };\n                }\n                var length = getLength();\n                var ptr = _malloc(4 + length + 1);\n                HEAPU32[ptr >> 2] = length;\n                if (stdStringIsUTF8 && valueIsOfTypeString) {\n                    stringToUTF8(value, ptr + 4, length + 1);\n                }\n                else {\n                    if (valueIsOfTypeString) {\n                        for (var i = 0; i < length; ++i) {\n                            var charCode = value.charCodeAt(i);\n                            if (charCode > 255) {\n                                _free(ptr);\n                                throwBindingError('String has UTF-16 code units that do not fit in 8 bits');\n                            }\n                            HEAPU8[ptr + 4 + i] = charCode;\n                        }\n                    }\n                    else {\n                        for (var i = 0; i < length; ++i) {\n                            HEAPU8[ptr + 4 + i] = value[i];\n                        }\n                    }\n                }\n                if (destructors !== null) {\n                    destructors.push(_free, ptr);\n                }\n                return ptr;\n            },\n            argPackAdvance: 8,\n            readValueFromPointer: simpleReadValueFromPointer,\n            destructorFunction: function (ptr) {\n                _free(ptr);\n            }\n        });\n    }\n    function __embind_register_std_wstring(rawType, charSize, name) {\n        name = readLatin1String(name);\n        var decodeString, encodeString, getHeap, lengthBytesUTF, shift;\n        if (charSize === 2) {\n            decodeString = UTF16ToString;\n            encodeString = stringToUTF16;\n            lengthBytesUTF = lengthBytesUTF16;\n            getHeap = function () {\n                return HEAPU16;\n            };\n            shift = 1;\n        }\n        else if (charSize === 4) {\n            decodeString = UTF32ToString;\n            encodeString = stringToUTF32;\n            lengthBytesUTF = lengthBytesUTF32;\n            getHeap = function () {\n                return HEAPU32;\n            };\n            shift = 2;\n        }\n        registerType(rawType, {\n            name: name,\n            fromWireType: function (value) {\n                var length = HEAPU32[value >> 2];\n                var HEAP = getHeap();\n                var str;\n                var decodeStartPtr = value + 4;\n                for (var i = 0; i <= length; ++i) {\n                    var currentBytePtr = value + 4 + i * charSize;\n                    if (HEAP[currentBytePtr >> shift] == 0 || i == length) {\n                        var maxReadBytes = currentBytePtr - decodeStartPtr;\n                        var stringSegment = decodeString(decodeStartPtr, maxReadBytes);\n                        if (str === undefined) {\n                            str = stringSegment;\n                        }\n                        else {\n                            str += String.fromCharCode(0);\n                            str += stringSegment;\n                        }\n                        decodeStartPtr = currentBytePtr + charSize;\n                    }\n                }\n                _free(value);\n                return str;\n            },\n            toWireType: function (destructors, value) {\n                if (!(typeof value === 'string')) {\n                    throwBindingError('Cannot pass non-string to C++ string type ' + name);\n                }\n                var length = lengthBytesUTF(value);\n                var ptr = _malloc(4 + length + charSize);\n                HEAPU32[ptr >> 2] = length >> shift;\n                encodeString(value, ptr + 4, length + charSize);\n                if (destructors !== null) {\n                    destructors.push(_free, ptr);\n                }\n                return ptr;\n            },\n            argPackAdvance: 8,\n            readValueFromPointer: simpleReadValueFromPointer,\n            destructorFunction: function (ptr) {\n                _free(ptr);\n            }\n        });\n    }\n    function __embind_register_void(rawType, name) {\n        name = readLatin1String(name);\n        registerType(rawType, {\n            isVoid: true,\n            name: name,\n            argPackAdvance: 0,\n            fromWireType: function () {\n                return undefined;\n            },\n            toWireType: function (destructors, o) {\n                return undefined;\n            }\n        });\n    }\n    function _abort() {\n        abort();\n    }\n    function _emscripten_get_heap_size() {\n        return HEAPU8.length;\n    }\n    function abortOnCannotGrowMemory(requestedSize) {\n        abort('OOM');\n    }\n    function _emscripten_resize_heap(requestedSize) {\n        abortOnCannotGrowMemory();\n    }\n    function _llvm_trap() {\n        abort('trap!');\n    }\n    function _emscripten_memcpy_big(dest, src, num) {\n        HEAPU8.copyWithin(dest, src, src + num);\n    }\n    embind_init_charCodes();\n    BindingError = Module['BindingError'] = extendError(Error, 'BindingError');\n    InternalError = Module['InternalError'] = extendError(Error, 'InternalError');\n    init_ClassHandle();\n    init_RegisteredPointer();\n    init_embind();\n    UnboundTypeError = Module['UnboundTypeError'] = extendError(Error, 'UnboundTypeError');\n    init_emval();\n    function intArrayToString(array) {\n        var ret = [];\n        for (var i = 0; i < array.length; i++) {\n            var chr = array[i];\n            if (chr > 255) {\n                chr &= 255;\n            }\n            ret.push(String.fromCharCode(chr));\n        }\n        return ret.join('');\n    }\n    var decodeBase64 = typeof atob === 'function'\n        ? atob\n        : function (input) {\n            var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n            var output = '';\n            var chr1, chr2, chr3;\n            var enc1, enc2, enc3, enc4;\n            var i = 0;\n            input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, '');\n            do {\n                enc1 = keyStr.indexOf(input.charAt(i++));\n                enc2 = keyStr.indexOf(input.charAt(i++));\n                enc3 = keyStr.indexOf(input.charAt(i++));\n                enc4 = keyStr.indexOf(input.charAt(i++));\n                chr1 = (enc1 << 2) | (enc2 >> 4);\n                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n                chr3 = ((enc3 & 3) << 6) | enc4;\n                output = output + String.fromCharCode(chr1);\n                if (enc3 !== 64) {\n                    output = output + String.fromCharCode(chr2);\n                }\n                if (enc4 !== 64) {\n                    output = output + String.fromCharCode(chr3);\n                }\n            } while (i < input.length);\n            return output;\n        };\n    function intArrayFromBase64(s) {\n        if (typeof ENVIRONMENT_IS_NODE === 'boolean' && ENVIRONMENT_IS_NODE) {\n            var buf;\n            try {\n                buf = Buffer.from(s, 'base64');\n            }\n            catch (_) {\n                buf = new Buffer(s, 'base64');\n            }\n            return new Uint8Array(buf['buffer'], buf['byteOffset'], buf['byteLength']);\n        }\n        try {\n            var decoded = decodeBase64(s);\n            var bytes = new Uint8Array(decoded.length);\n            for (var i = 0; i < decoded.length; ++i) {\n                bytes[i] = decoded.charCodeAt(i);\n            }\n            return bytes;\n        }\n        catch (_) {\n            throw new Error('Converting base64 string to bytes failed.');\n        }\n    }\n    function tryParseAsDataURI(filename) {\n        if (!isDataURI(filename)) {\n            return;\n        }\n        return intArrayFromBase64(filename.slice(dataURIPrefix.length));\n    }\n    var asmGlobalArg = {\n        Math: Math,\n        Int8Array: Int8Array,\n        Int16Array: Int16Array,\n        Int32Array: Int32Array,\n        Uint8Array: Uint8Array,\n        Uint16Array: Uint16Array,\n        Float32Array: Float32Array,\n        Float64Array: Float64Array\n    };\n    var asmLibraryArg = {\n        A: _emscripten_memcpy_big,\n        B: _emscripten_resize_heap,\n        C: _llvm_trap,\n        D: tempDoublePtr,\n        a: abort,\n        b: setTempRet0,\n        c: getTempRet0,\n        d: ___cxa_allocate_exception,\n        e: ___cxa_begin_catch,\n        f: ___cxa_throw,\n        g: ___cxa_uncaught_exceptions,\n        h: ___exception_addRef,\n        i: ___exception_deAdjust,\n        j: ___gxx_personality_v0,\n        k: __embind_register_bool,\n        l: __embind_register_class,\n        m: __embind_register_class_constructor,\n        n: __embind_register_class_function,\n        o: __embind_register_emval,\n        p: __embind_register_float,\n        q: __embind_register_integer,\n        r: __embind_register_memory_view,\n        s: __embind_register_std_string,\n        t: __embind_register_std_wstring,\n        u: __embind_register_void,\n        v: __emval_decref,\n        w: __emval_register,\n        x: _abort,\n        y: _embind_repr,\n        z: _emscripten_get_heap_size\n    }; // EMSCRIPTEN_START_ASM\n    var asm = /** @suppress {uselessCode} */ (function (global, env, buffer) {\n        'use asm';\n        var a = new global.Int8Array(buffer), b = new global.Int16Array(buffer), c = new global.Int32Array(buffer), d = new global.Uint8Array(buffer), e = new global.Uint16Array(buffer), f = new global.Float32Array(buffer), g = new global.Float64Array(buffer), h = env.D | 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0.0, q = global.Math.imul, r = global.Math.clz32, s = env.a, t = env.b, u = env.c, v = env.d, w = env.e, x = env.f, y = env.g, z = env.h, A = env.i, B = env.j, C = env.k, D = env.l, E = env.m, F = env.n, G = env.o, H = env.p, I = env.q, J = env.r, K = env.s, L = env.t, M = env.u, N = env.v, O = env.w, P = env.x, Q = env.y, R = env.z, S = env.A, T = env.B, U = env.C, V = 22384, W = 5265264, X = 0.0;\n        // EMSCRIPTEN_START_FUNCS\n        function ia() {\n            em();\n            fm();\n        }\n        function ja() {\n            ka(0);\n            return;\n        }\n        function ka(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0;\n            a = V;\n            V = (V + 16) | 0;\n            b = (a + 8) | 0;\n            d = a;\n            vk();\n            m = xk() | 0;\n            g = yk() | 0;\n            f = Ak() | 0;\n            h = Bk() | 0;\n            i = Ck() | 0;\n            j = Dk() | 0;\n            k = Jk() | 0;\n            l = Kk() | 0;\n            e = Kk() | 0;\n            D(f | 0, h | 0, i | 0, j | 0, k | 0, 9, l | 0, m | 0, e | 0, g | 0, 6204, Lk() | 0, 138);\n            Nk(1);\n            c[d >> 2] = 5;\n            c[(d + 4) >> 2] = 0;\n            c[b >> 2] = c[d >> 2];\n            c[(b + 4) >> 2] = c[(d + 4) >> 2];\n            Uk(6211, b);\n            c[d >> 2] = 3;\n            c[(d + 4) >> 2] = 0;\n            c[b >> 2] = c[d >> 2];\n            c[(b + 4) >> 2] = c[(d + 4) >> 2];\n            cl(6216, b);\n            c[d >> 2] = 10;\n            c[(d + 4) >> 2] = 0;\n            c[b >> 2] = c[d >> 2];\n            c[(b + 4) >> 2] = c[(d + 4) >> 2];\n            kl(6225, b);\n            sl();\n            g = ul() | 0;\n            e = vl() | 0;\n            m = xl() | 0;\n            l = yl() | 0;\n            k = zl() | 0;\n            j = Dk() | 0;\n            i = Jk() | 0;\n            h = Kk() | 0;\n            f = Kk() | 0;\n            D(m | 0, l | 0, k | 0, j | 0, i | 0, 11, h | 0, g | 0, f | 0, e | 0, 6234, Lk() | 0, 139);\n            Gl(2);\n            c[d >> 2] = 6;\n            c[(d + 4) >> 2] = 0;\n            c[b >> 2] = c[d >> 2];\n            c[(b + 4) >> 2] = c[(d + 4) >> 2];\n            Nl(6211, b);\n            c[d >> 2] = 4;\n            c[(d + 4) >> 2] = 0;\n            c[b >> 2] = c[d >> 2];\n            c[(b + 4) >> 2] = c[(d + 4) >> 2];\n            Ul(6248, b);\n            c[d >> 2] = 5;\n            c[(d + 4) >> 2] = 0;\n            c[b >> 2] = c[d >> 2];\n            c[(b + 4) >> 2] = c[(d + 4) >> 2];\n            Ul(6265, b);\n            c[d >> 2] = 6;\n            c[(d + 4) >> 2] = 0;\n            c[b >> 2] = c[d >> 2];\n            c[(b + 4) >> 2] = c[(d + 4) >> 2];\n            Ul(6280, b);\n            c[d >> 2] = 7;\n            c[(d + 4) >> 2] = 0;\n            c[b >> 2] = c[d >> 2];\n            c[(b + 4) >> 2] = c[(d + 4) >> 2];\n            _l(6216, b);\n            V = a;\n            return;\n        }\n        function la(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0, i = 0;\n            e = V;\n            V = (V + 32) | 0;\n            h = (e + 16) | 0;\n            f = (e + 8) | 0;\n            i = e;\n            g = eq(20) | 0;\n            ta(g, b, d);\n            c[i >> 2] = 0;\n            c[h >> 2] = c[i >> 2];\n            va(f, g, h);\n            b = c[f >> 2] | 0;\n            c[f >> 2] = c[a >> 2];\n            c[a >> 2] = b;\n            b = (f + 4) | 0;\n            d = (a + 4) | 0;\n            g = c[b >> 2] | 0;\n            c[b >> 2] = c[d >> 2];\n            c[d >> 2] = g;\n            wa(f);\n            d = eq(352) | 0;\n            ua(d, c[a >> 2] | 0);\n            g = (a + 8) | 0;\n            c[i >> 2] = 0;\n            c[h >> 2] = c[i >> 2];\n            Fa(f, d, h);\n            d = c[f >> 2] | 0;\n            c[f >> 2] = c[g >> 2];\n            c[g >> 2] = d;\n            g = (f + 4) | 0;\n            d = (a + 12) | 0;\n            b = c[g >> 2] | 0;\n            c[g >> 2] = c[d >> 2];\n            c[d >> 2] = b;\n            Ga(f);\n            V = e;\n            return;\n        }\n        function ma(a, b) {\n            a = a | 0;\n            b = b | 0;\n            dd(c[(a + 8) >> 2] | 0, b);\n            return;\n        }\n        function na(a) {\n            a = a | 0;\n            a = ((Qh(c[(a + 8) >> 2] | 0) | 0) + 107) | 0;\n            return (d[a >> 0] | (d[(a + 1) >> 0] << 8) | (d[(a + 2) >> 0] << 16) | (d[(a + 3) >> 0] << 24) | 0);\n        }\n        function oa(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0, i = 0;\n            e = V;\n            V = (V + 32) | 0;\n            g = (e + 16) | 0;\n            f = (e + 8) | 0;\n            h = e;\n            i = eq(12) | 0;\n            Rh(i, b, d);\n            c[h >> 2] = 0;\n            c[g >> 2] = c[h >> 2];\n            Vh(f, i, g);\n            i = c[f >> 2] | 0;\n            c[f >> 2] = c[a >> 2];\n            c[a >> 2] = i;\n            i = (f + 4) | 0;\n            d = (a + 4) | 0;\n            b = c[i >> 2] | 0;\n            c[i >> 2] = c[d >> 2];\n            c[d >> 2] = b;\n            Wh(f);\n            d = (a + 8) | 0;\n            b = eq(12) | 0;\n            Sh(b, c[a >> 2] | 0);\n            c[h >> 2] = 0;\n            c[g >> 2] = c[h >> 2];\n            ai(f, b, g);\n            b = c[f >> 2] | 0;\n            c[f >> 2] = c[d >> 2];\n            c[d >> 2] = b;\n            b = (f + 4) | 0;\n            h = (a + 12) | 0;\n            i = c[b >> 2] | 0;\n            c[b >> 2] = c[h >> 2];\n            c[h >> 2] = i;\n            bi(f);\n            Th(f, c[d >> 2] | 0);\n            d = (a + 16) | 0;\n            h = c[f >> 2] | 0;\n            i = (f + 4) | 0;\n            b = c[i >> 2] | 0;\n            c[f >> 2] = 0;\n            c[i >> 2] = 0;\n            c[g >> 2] = c[d >> 2];\n            c[d >> 2] = h;\n            d = (a + 20) | 0;\n            c[(g + 4) >> 2] = c[d >> 2];\n            c[d >> 2] = b;\n            Uh(g);\n            Uh(f);\n            V = e;\n            return;\n        }\n        function pa(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0;\n            a = (a + 16) | 0;\n            d = c[a >> 2] | 0;\n            a: do\n                if (d | 0)\n                    switch (b | 0) {\n                        case 4: {\n                            ui(d);\n                            break a;\n                        }\n                        case 8: {\n                            vi(d);\n                            vi(c[a >> 2] | 0);\n                            break a;\n                        }\n                        default:\n                            break a;\n                    }\n            while (0);\n            return;\n        }\n        function qa(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0;\n            d = (a + 16) | 0;\n            a = c[d >> 2] | 0;\n            a: do\n                if (a | 0) {\n                    switch (b | 0) {\n                        case 1: {\n                            hj(a);\n                            break a;\n                        }\n                        case 2: {\n                            ij(a);\n                            break a;\n                        }\n                        case 8: {\n                            ui(a);\n                            a = c[d >> 2] | 0;\n                            break;\n                        }\n                        case 4:\n                            break;\n                        default:\n                            break a;\n                    }\n                    ui(a);\n                }\n            while (0);\n            return;\n        }\n        function ra(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0;\n            d = (a + 16) | 0;\n            a = c[d >> 2] | 0;\n            a: do\n                if (a | 0) {\n                    switch (b | 0) {\n                        case 1: {\n                            Rj(a);\n                            break a;\n                        }\n                        case 2: {\n                            Sj(a);\n                            break a;\n                        }\n                        case 8: {\n                            vi(a);\n                            a = c[d >> 2] | 0;\n                            break;\n                        }\n                        case 4:\n                            break;\n                        default:\n                            break a;\n                    }\n                    vi(a);\n                }\n            while (0);\n            return;\n        }\n        function sa(a, b) {\n            a = a | 0;\n            b = b | 0;\n            a = c[(a + 16) >> 2] | 0;\n            if (a | 0)\n                $[c[c[a >> 2] >> 2] & 63](a, b) | 0;\n            return;\n        }\n        function ta(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            c[b >> 2] = d;\n            c[(b + 4) >> 2] = e;\n            c[(b + 8) >> 2] = 0;\n            a[(b + 12) >> 0] = 0;\n            a[(b + 13) >> 0] = 0;\n            c[(b + 16) >> 2] = 0;\n            return;\n        }\n        function ua(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = b;\n            Va((a + 4) | 0, b);\n            Wa((a + 247) | 0);\n            c[(a + 288) >> 2] = 0;\n            c[(a + 292) >> 2] = 0;\n            c[(a + 296) >> 2] = 0;\n            Xa((a + 300) | 0);\n            b = (a + 312) | 0;\n            c[b >> 2] = 0;\n            c[(b + 4) >> 2] = 0;\n            c[(b + 8) >> 2] = 0;\n            c[(b + 12) >> 2] = 0;\n            Ya((a + 328) | 0);\n            Za(a);\n            return;\n        }\n        function va(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 4296;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            xa(a, e);\n            V = d;\n            return;\n        }\n        function wa(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            a = c[(a + 4) >> 2] | 0;\n            if (a | 0 ? ((d = (a + 4) | 0), (b = c[d >> 2] | 0), (c[d >> 2] = b + -1), (b | 0) == 0) : 0) {\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n                qq(a);\n            }\n            return;\n        }\n        function xa(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return;\n        }\n        function ya(a) {\n            a = a | 0;\n            w(a | 0) | 0;\n            lp();\n        }\n        function za(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Aa(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                jp(a);\n            return;\n        }\n        function Ba(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 6407 ? (a + 12) | 0 : 0) | 0;\n        }\n        function Ca(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Da(a, b) {\n            a = a | 0;\n            b = b | 0;\n            Ea(a);\n            return;\n        }\n        function Ea(a) {\n            a = a | 0;\n            jp(a);\n            return;\n        }\n        function Fa(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 4324;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Ha(a, e);\n            V = d;\n            return;\n        }\n        function Ga(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            a = c[(a + 4) >> 2] | 0;\n            if (a | 0 ? ((d = (a + 4) | 0), (b = c[d >> 2] | 0), (c[d >> 2] = b + -1), (b | 0) == 0) : 0) {\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n                qq(a);\n            }\n            return;\n        }\n        function Ha(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return;\n        }\n        function Ia(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Ja(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0) {\n                Ma(a);\n                jp(a);\n            }\n            return;\n        }\n        function Ka(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 6605 ? (a + 12) | 0 : 0) | 0;\n        }\n        function La(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Ma(a) {\n            a = a | 0;\n            Na((a + 320) | 0);\n            Oa((a + 312) | 0);\n            Pa((a + 300) | 0);\n            Ta((a + 288) | 0);\n            Qa((a + 247) | 0);\n            Ra((a + 4) | 0);\n            return;\n        }\n        function Na(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            a = c[(a + 4) >> 2] | 0;\n            if (a | 0 ? ((d = (a + 4) | 0), (b = c[d >> 2] | 0), (c[d >> 2] = b + -1), (b | 0) == 0) : 0) {\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n                qq(a);\n            }\n            return;\n        }\n        function Oa(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            a = c[(a + 4) >> 2] | 0;\n            if (a | 0 ? ((d = (a + 4) | 0), (b = c[d >> 2] | 0), (c[d >> 2] = b + -1), (b | 0) == 0) : 0) {\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n                qq(a);\n            }\n            return;\n        }\n        function Pa(a) {\n            a = a | 0;\n            Sa(a);\n            return;\n        }\n        function Qa(a) {\n            a = a | 0;\n            a = (a + 34) | 0;\n            a = d[a >> 0] | (d[(a + 1) >> 0] << 8) | (d[(a + 2) >> 0] << 16) | (d[(a + 3) >> 0] << 24);\n            if (a | 0)\n                gq(a);\n            return;\n        }\n        function Ra(a) {\n            a = a | 0;\n            Ua(c[(a + 12) >> 2] | 0);\n            return;\n        }\n        function Sa(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = c[a >> 2] | 0;\n            d = b;\n            if (b | 0) {\n                c[(a + 4) >> 2] = d;\n                Da(b, ((c[(a + 8) >> 2] | 0) - d) | 0);\n            }\n            return;\n        }\n        function Ta(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = c[a >> 2] | 0;\n            d = b;\n            if (b | 0) {\n                c[(a + 4) >> 2] = d;\n                Da(b, ((c[(a + 8) >> 2] | 0) - d) | 0);\n            }\n            return;\n        }\n        function Ua(a) {\n            a = a | 0;\n            er(c[(a + -4) >> 2] | 0);\n            return;\n        }\n        function Va(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = b;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = 0;\n            c[(a + 12) >> 2] = _a(1048576) | 0;\n            return;\n        }\n        function Wa(b) {\n            b = b | 0;\n            var c = 0;\n            c = (b + 32) | 0;\n            a[c >> 0] = 0;\n            a[(c + 1) >> 0] = 0;\n            b = (b + 34) | 0;\n            a[b >> 0] = 0;\n            a[(b + 1) >> 0] = 0;\n            a[(b + 2) >> 0] = 0;\n            a[(b + 3) >> 0] = 0;\n            return;\n        }\n        function Xa(a) {\n            a = a | 0;\n            c[a >> 2] = 0;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = 0;\n            return;\n        }\n        function Ya(a) {\n            a = a | 0;\n            c[a >> 2] = 0;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = 0;\n            c[(a + 12) >> 2] = 0;\n            a = (a + 16) | 0;\n            c[a >> 2] = -1;\n            c[(a + 4) >> 2] = -1;\n            return;\n        }\n        function Za(b) {\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0;\n            i = V;\n            V = (V + 64) | 0;\n            g = (i + 32) | 0;\n            e = (i + 56) | 0;\n            d = (i + 16) | 0;\n            h = i;\n            $a(c[b >> 2] | 0, e, 4);\n            mb(g, e, (e + 4) | 0);\n            e = lb(6693) | 0;\n            f = a[(g + 11) >> 0] | 0;\n            if ((e | 0) == (((f << 24) >> 24 < 0 ? c[(g + 4) >> 2] | 0 : f & 255) | 0)) {\n                f = (Hq(g, 0, -1, 6693, e) | 0) == 0;\n                Cq(g);\n                if (f) {\n                    e = c[b >> 2] | 0;\n                    c[d >> 2] = 0;\n                    c[(d + 4) >> 2] = 0;\n                    c[(d + 8) >> 2] = 0;\n                    c[(d + 12) >> 2] = 0;\n                    c[g >> 2] = c[d >> 2];\n                    c[(g + 4) >> 2] = c[(d + 4) >> 2];\n                    c[(g + 8) >> 2] = c[(d + 8) >> 2];\n                    c[(g + 12) >> 2] = c[(d + 12) >> 2];\n                    bb(e, g);\n                    e = (b + 20) | 0;\n                    $a(c[b >> 2] | 0, e, 227);\n                    cb(b, e);\n                    f = db() | 0;\n                    d = c[f >> 2] | 0;\n                    f = c[(f + 4) >> 2] | 0;\n                    if ((d | 0) != (f | 0))\n                        do {\n                            eb(g, d);\n                            fb(g, e);\n                            gb(g);\n                            d = (d + 24) | 0;\n                        } while ((d | 0) != (f | 0));\n                    hb(b);\n                    ib(b);\n                    jb(c[b >> 2] | 0);\n                    f = c[b >> 2] | 0;\n                    d = ((c[(b + 116) >> 2] | 0) + 8) | 0;\n                    e = h;\n                    c[e >> 2] = 0;\n                    c[(e + 4) >> 2] = 0;\n                    e = (h + 8) | 0;\n                    c[e >> 2] = d;\n                    c[(e + 4) >> 2] = 0;\n                    c[g >> 2] = c[h >> 2];\n                    c[(g + 4) >> 2] = c[(h + 4) >> 2];\n                    c[(g + 8) >> 2] = c[(h + 8) >> 2];\n                    c[(g + 12) >> 2] = c[(h + 12) >> 2];\n                    bb(f, g);\n                    kb((b + 4) | 0);\n                    V = i;\n                    return;\n                }\n            }\n            else\n                Cq(g);\n            i = v(8) | 0;\n            ab(i);\n            x(i | 0, 2592, 8);\n        }\n        function _a(a) {\n            a = a | 0;\n            var b = 0;\n            b = dr((a + 68) | 0) | 0;\n            a = (b + 68) & -64;\n            c[(a + -4) >> 2] = b;\n            return a | 0;\n        }\n        function $a(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            i = (b + 13) | 0;\n            if (!(a[i >> 0] | 0)) {\n                h = (b + 4) | 0;\n                f = c[h >> 2] | 0;\n                j = (b + 8) | 0;\n                g = c[j >> 2] | 0;\n                k = (f - g) | 0;\n                e = (k | 0) < (e | 0) ? k : e;\n                if (e) {\n                    vr(d | 0, ((c[b >> 2] | 0) + g) | 0, e | 0) | 0;\n                    g = c[j >> 2] | 0;\n                    f = c[h >> 2] | 0;\n                }\n                k = (g + e) | 0;\n                c[j >> 2] = k;\n                c[(b + 16) >> 2] = e;\n                if ((k | 0) >= (f | 0))\n                    a[i >> 0] = 1;\n            }\n            else\n                a[(b + 12) >> 0] = 1;\n            return;\n        }\n        function ab(a) {\n            a = a | 0;\n            xq(a, 6791);\n            c[a >> 2] = 4352;\n            return;\n        }\n        function bb(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0;\n            g = (d + 8) | 0;\n            d = c[g >> 2] | 0;\n            g = c[(g + 4) >> 2] | 0;\n            e = c[(b + 4) >> 2] | 0;\n            f = (((e | 0) < 0) << 31) >> 31;\n            if (((g | 0) < (f | 0)) | (((g | 0) == (f | 0)) & (d >>> 0 < e >>> 0)))\n                c[(b + 8) >> 2] = d;\n            else\n                a[(b + 12) >> 0] = 1;\n            return;\n        }\n        function cb(b, c) {\n            b = b | 0;\n            c = c | 0;\n            var d = 0.0, e = 0.0, f = 0, i = 0.0, j = 0, k = 0.0, l = 0, m = 0.0, n = 0, o = 0.0;\n            n = (c + 179) | 0;\n            a[h >> 0] = a[n >> 0];\n            a[(h + 1) >> 0] = a[(n + 1) >> 0];\n            a[(h + 2) >> 0] = a[(n + 2) >> 0];\n            a[(h + 3) >> 0] = a[(n + 3) >> 0];\n            a[(h + 4) >> 0] = a[(n + 4) >> 0];\n            a[(h + 5) >> 0] = a[(n + 5) >> 0];\n            a[(h + 6) >> 0] = a[(n + 6) >> 0];\n            a[(h + 7) >> 0] = a[(n + 7) >> 0];\n            m = +g[h >> 3];\n            j = (c + 187) | 0;\n            a[h >> 0] = a[j >> 0];\n            a[(h + 1) >> 0] = a[(j + 1) >> 0];\n            a[(h + 2) >> 0] = a[(j + 2) >> 0];\n            a[(h + 3) >> 0] = a[(j + 3) >> 0];\n            a[(h + 4) >> 0] = a[(j + 4) >> 0];\n            a[(h + 5) >> 0] = a[(j + 5) >> 0];\n            a[(h + 6) >> 0] = a[(j + 6) >> 0];\n            a[(h + 7) >> 0] = a[(j + 7) >> 0];\n            o = +g[h >> 3];\n            b = (c + 195) | 0;\n            a[h >> 0] = a[b >> 0];\n            a[(h + 1) >> 0] = a[(b + 1) >> 0];\n            a[(h + 2) >> 0] = a[(b + 2) >> 0];\n            a[(h + 3) >> 0] = a[(b + 3) >> 0];\n            a[(h + 4) >> 0] = a[(b + 4) >> 0];\n            a[(h + 5) >> 0] = a[(b + 5) >> 0];\n            a[(h + 6) >> 0] = a[(b + 6) >> 0];\n            a[(h + 7) >> 0] = a[(b + 7) >> 0];\n            i = +g[h >> 3];\n            l = (c + 203) | 0;\n            a[h >> 0] = a[l >> 0];\n            a[(h + 1) >> 0] = a[(l + 1) >> 0];\n            a[(h + 2) >> 0] = a[(l + 2) >> 0];\n            a[(h + 3) >> 0] = a[(l + 3) >> 0];\n            a[(h + 4) >> 0] = a[(l + 4) >> 0];\n            a[(h + 5) >> 0] = a[(l + 5) >> 0];\n            a[(h + 6) >> 0] = a[(l + 6) >> 0];\n            a[(h + 7) >> 0] = a[(l + 7) >> 0];\n            k = +g[h >> 3];\n            f = (c + 211) | 0;\n            a[h >> 0] = a[f >> 0];\n            a[(h + 1) >> 0] = a[(f + 1) >> 0];\n            a[(h + 2) >> 0] = a[(f + 2) >> 0];\n            a[(h + 3) >> 0] = a[(f + 3) >> 0];\n            a[(h + 4) >> 0] = a[(f + 4) >> 0];\n            a[(h + 5) >> 0] = a[(f + 5) >> 0];\n            a[(h + 6) >> 0] = a[(f + 6) >> 0];\n            a[(h + 7) >> 0] = a[(f + 7) >> 0];\n            d = +g[h >> 3];\n            c = (c + 219) | 0;\n            a[h >> 0] = a[c >> 0];\n            a[(h + 1) >> 0] = a[(c + 1) >> 0];\n            a[(h + 2) >> 0] = a[(c + 2) >> 0];\n            a[(h + 3) >> 0] = a[(c + 3) >> 0];\n            a[(h + 4) >> 0] = a[(c + 4) >> 0];\n            a[(h + 5) >> 0] = a[(c + 5) >> 0];\n            a[(h + 6) >> 0] = a[(c + 6) >> 0];\n            a[(h + 7) >> 0] = a[(c + 7) >> 0];\n            e = +g[h >> 3];\n            g[h >> 3] = o;\n            a[n >> 0] = a[h >> 0];\n            a[(n + 1) >> 0] = a[(h + 1) >> 0];\n            a[(n + 2) >> 0] = a[(h + 2) >> 0];\n            a[(n + 3) >> 0] = a[(h + 3) >> 0];\n            a[(n + 4) >> 0] = a[(h + 4) >> 0];\n            a[(n + 5) >> 0] = a[(h + 5) >> 0];\n            a[(n + 6) >> 0] = a[(h + 6) >> 0];\n            a[(n + 7) >> 0] = a[(h + 7) >> 0];\n            g[h >> 3] = m;\n            a[l >> 0] = a[h >> 0];\n            a[(l + 1) >> 0] = a[(h + 1) >> 0];\n            a[(l + 2) >> 0] = a[(h + 2) >> 0];\n            a[(l + 3) >> 0] = a[(h + 3) >> 0];\n            a[(l + 4) >> 0] = a[(h + 4) >> 0];\n            a[(l + 5) >> 0] = a[(h + 5) >> 0];\n            a[(l + 6) >> 0] = a[(h + 6) >> 0];\n            a[(l + 7) >> 0] = a[(h + 7) >> 0];\n            g[h >> 3] = k;\n            a[j >> 0] = a[h >> 0];\n            a[(j + 1) >> 0] = a[(h + 1) >> 0];\n            a[(j + 2) >> 0] = a[(h + 2) >> 0];\n            a[(j + 3) >> 0] = a[(h + 3) >> 0];\n            a[(j + 4) >> 0] = a[(h + 4) >> 0];\n            a[(j + 5) >> 0] = a[(h + 5) >> 0];\n            a[(j + 6) >> 0] = a[(h + 6) >> 0];\n            a[(j + 7) >> 0] = a[(h + 7) >> 0];\n            g[h >> 3] = i;\n            a[f >> 0] = a[h >> 0];\n            a[(f + 1) >> 0] = a[(h + 1) >> 0];\n            a[(f + 2) >> 0] = a[(h + 2) >> 0];\n            a[(f + 3) >> 0] = a[(h + 3) >> 0];\n            a[(f + 4) >> 0] = a[(h + 4) >> 0];\n            a[(f + 5) >> 0] = a[(h + 5) >> 0];\n            a[(f + 6) >> 0] = a[(h + 6) >> 0];\n            a[(f + 7) >> 0] = a[(h + 7) >> 0];\n            g[h >> 3] = e;\n            a[b >> 0] = a[h >> 0];\n            a[(b + 1) >> 0] = a[(h + 1) >> 0];\n            a[(b + 2) >> 0] = a[(h + 2) >> 0];\n            a[(b + 3) >> 0] = a[(h + 3) >> 0];\n            a[(b + 4) >> 0] = a[(h + 4) >> 0];\n            a[(b + 5) >> 0] = a[(h + 5) >> 0];\n            a[(b + 6) >> 0] = a[(h + 6) >> 0];\n            a[(b + 7) >> 0] = a[(h + 7) >> 0];\n            g[h >> 3] = d;\n            a[c >> 0] = a[h >> 0];\n            a[(c + 1) >> 0] = a[(h + 1) >> 0];\n            a[(c + 2) >> 0] = a[(h + 2) >> 0];\n            a[(c + 3) >> 0] = a[(h + 3) >> 0];\n            a[(c + 4) >> 0] = a[(h + 4) >> 0];\n            a[(c + 5) >> 0] = a[(h + 5) >> 0];\n            a[(c + 6) >> 0] = a[(h + 6) >> 0];\n            a[(c + 7) >> 0] = a[(h + 7) >> 0];\n            return;\n        }\n        function db() {\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0;\n            g = V;\n            V = (V + 48) | 0;\n            e = (g + 24) | 0;\n            f = g;\n            b = (g + 44) | 0;\n            if ((a[21440] | 0) == 0 ? Tp(21440) | 0 : 0) {\n                c[5374] = 0;\n                c[5375] = 0;\n                c[5376] = 0;\n                $p(21440);\n            }\n            if ((a[21448] | 0) == 0 ? Tp(21448) | 0 : 0)\n                $p(21448);\n            if ((c[5374] | 0) == (c[5375] | 0)) {\n                rq(21508);\n                if ((c[5374] | 0) == (c[5375] | 0)) {\n                    a[e >> 0] = a[b >> 0] | 0;\n                    pb(f, e);\n                    b = c[5375] | 0;\n                    do\n                        if (b >>> 0 >= (c[5376] | 0) >>> 0) {\n                            b = (((((b - (c[5374] | 0)) | 0) / 24) | 0) + 1) | 0;\n                            d = xb(21496) | 0;\n                            if (d >>> 0 < b >>> 0)\n                                cr(21496);\n                            else {\n                                h = c[5374] | 0;\n                                j = ((((c[5376] | 0) - h) | 0) / 24) | 0;\n                                i = j << 1;\n                                ub(e, j >>> 0 < (d >>> 1) >>> 0 ? (i >>> 0 < b >>> 0 ? b : i) : d, ((((c[5375] | 0) - h) | 0) / 24) | 0, 21504);\n                                d = (e + 8) | 0;\n                                sb(c[d >> 2] | 0, f);\n                                c[d >> 2] = (c[d >> 2] | 0) + 24;\n                                vb(21496, e);\n                                wb(e);\n                                break;\n                            }\n                        }\n                        else {\n                            qb(e, 21496, 1);\n                            j = (e + 4) | 0;\n                            sb(c[j >> 2] | 0, f);\n                            c[j >> 2] = (c[j >> 2] | 0) + 24;\n                            rb(e);\n                        }\n                    while (0);\n                    gb(f);\n                }\n                sq(21508);\n            }\n            V = g;\n            return 21496;\n        }\n        function eb(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0;\n            d = (b + 16) | 0;\n            e = c[d >> 2] | 0;\n            do\n                if (e)\n                    if ((b | 0) == (e | 0)) {\n                        e = tb(a) | 0;\n                        c[(a + 16) >> 2] = e;\n                        d = c[d >> 2] | 0;\n                        da[c[((c[d >> 2] | 0) + 12) >> 2] & 15](d, e);\n                        break;\n                    }\n                    else {\n                        c[(a + 16) >> 2] = Z[c[((c[e >> 2] | 0) + 8) >> 2] & 15](e) | 0;\n                        break;\n                    }\n                else\n                    c[(a + 16) >> 2] = 0;\n            while (0);\n            return;\n        }\n        function fb(a, b) {\n            a = a | 0;\n            b = b | 0;\n            a = c[(a + 16) >> 2] | 0;\n            if (!a) {\n                b = v(4) | 0;\n                c[b >> 2] = 0;\n                Nb(b);\n                x(b | 0, 4168, 131);\n            }\n            else {\n                da[c[((c[a >> 2] | 0) + 24) >> 2] & 15](a, b);\n                return;\n            }\n        }\n        function gb(a) {\n            a = a | 0;\n            var b = 0;\n            b = c[(a + 16) >> 2] | 0;\n            if ((a | 0) != (b | 0)) {\n                if (b | 0)\n                    ca[c[((c[b >> 2] | 0) + 20) >> 2] & 255](b);\n            }\n            else\n                ca[c[((c[b >> 2] | 0) + 16) >> 2] & 255](b);\n            return;\n        }\n        function hb(b) {\n            b = b | 0;\n            var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0;\n            q = V;\n            V = (V + 96) | 0;\n            i = (q + 16) | 0;\n            o = q;\n            l = (q + 72) | 0;\n            j = c[b >> 2] | 0;\n            m = e[(b + 114) >> 1] | 0;\n            n = o;\n            c[n >> 2] = 0;\n            c[(n + 4) >> 2] = 0;\n            n = (o + 8) | 0;\n            c[n >> 2] = m;\n            c[(n + 4) >> 2] = 0;\n            c[i >> 2] = c[o >> 2];\n            c[(i + 4) >> 2] = c[(o + 4) >> 2];\n            c[(i + 8) >> 2] = c[(o + 8) >> 2];\n            c[(i + 12) >> 2] = c[(o + 12) >> 2];\n            bb(j, i);\n            j = (b + 120) | 0;\n            a: do\n                if (c[j >> 2] | 0) {\n                    k = (i + 2) | 0;\n                    m = (i + 16) | 0;\n                    n = (i + 20) | 0;\n                    o = (i + 18) | 0;\n                    g = 0;\n                    while (1) {\n                        if (!(Ob(c[b >> 2] | 0) | 0))\n                            break a;\n                        if (Pb(c[b >> 2] | 0) | 0)\n                            break a;\n                        $a(c[b >> 2] | 0, i, 54);\n                        f = 7277;\n                        h = k;\n                        while (1) {\n                            if ((a[h >> 0] | 0) != (a[f >> 0] | 0))\n                                break;\n                            h = (h + 1) | 0;\n                            if ((h | 0) == (m | 0)) {\n                                p = 8;\n                                break;\n                            }\n                            else\n                                f = (f + 1) | 0;\n                        }\n                        if ((p | 0) == 8\n                            ? ((p = 0), ((d[o >> 0] | (d[(o + 1) >> 0] << 8)) << 16) >> 16 == 22204)\n                            : 0)\n                            break;\n                        Rb(c[b >> 2] | 0, (d[n >> 0] | (d[(n + 1) >> 0] << 8)) & 65535, 0, 1);\n                        g = (g + 1) | 0;\n                        if (g >>> 0 >= (c[j >> 2] | 0) >>> 0)\n                            break a;\n                    }\n                    o = (d[n >> 0] | (d[(n + 1) >> 0] << 8)) & 65535;\n                    p = fq(o) | 0;\n                    $a(c[b >> 2] | 0, p, o);\n                    Qb(b, p);\n                    jp(p);\n                    p = (b + 125) | 0;\n                    Tb(l, (b + 247) | 0, (d[p >> 0] | (d[(p + 1) >> 0] << 8)) & 65535);\n                    Ub((b + 300) | 0, l) | 0;\n                    Pa(l);\n                    V = q;\n                    return;\n                }\n            while (0);\n            q = v(8) | 0;\n            Sb(q);\n            x(q | 0, 2672, 8);\n        }\n        function ib(a) {\n            a = a | 0;\n            var b = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0;\n            n = V;\n            V = (V + 176) | 0;\n            g = (n + 40) | 0;\n            h = (n + 24) | 0;\n            b = (n + 16) | 0;\n            f = n;\n            k = (n + 152) | 0;\n            l = (n + 136) | 0;\n            m = (n + 56) | 0;\n            j = c[a >> 2] | 0;\n            i = (a + 116) | 0;\n            o = c[i >> 2] | 0;\n            e = h;\n            c[e >> 2] = 0;\n            c[(e + 4) >> 2] = 0;\n            e = (h + 8) | 0;\n            c[e >> 2] = o;\n            c[(e + 4) >> 2] = 0;\n            c[g >> 2] = c[h >> 2];\n            c[(g + 4) >> 2] = c[(h + 4) >> 2];\n            c[(g + 8) >> 2] = c[(h + 8) >> 2];\n            c[(g + 12) >> 2] = c[(h + 12) >> 2];\n            bb(j, g);\n            j = b;\n            c[j >> 2] = 0;\n            c[(j + 4) >> 2] = 0;\n            $a(c[a >> 2] | 0, b, 8);\n            if (!(Ob(c[a >> 2] | 0) | 0)) {\n                o = v(8) | 0;\n                hc(o);\n                x(o | 0, 2704, 8);\n            }\n            e = b;\n            b = c[e >> 2] | 0;\n            e = c[(e + 4) >> 2] | 0;\n            if (((b | 0) == -1) & ((e | 0) == -1)) {\n                o = v(8) | 0;\n                ic(o, 7488);\n                x(o | 0, 2720, 8);\n            }\n            o = c[a >> 2] | 0;\n            j = f;\n            c[j >> 2] = 0;\n            c[(j + 4) >> 2] = 0;\n            j = (f + 8) | 0;\n            c[j >> 2] = b;\n            c[(j + 4) >> 2] = e;\n            c[g >> 2] = c[f >> 2];\n            c[(g + 4) >> 2] = c[(f + 4) >> 2];\n            c[(g + 8) >> 2] = c[(f + 8) >> 2];\n            c[(g + 12) >> 2] = c[(f + 12) >> 2];\n            bb(o, g);\n            if (!(Ob(c[a >> 2] | 0) | 0)) {\n                o = v(8) | 0;\n                hc(o);\n                x(o | 0, 2704, 8);\n            }\n            $a(c[a >> 2] | 0, g, 8);\n            if (!(Ob(c[a >> 2] | 0) | 0)) {\n                o = v(8) | 0;\n                hc(o);\n                x(o | 0, 2704, 8);\n            }\n            if (c[g >> 2] | 0) {\n                o = v(8) | 0;\n                jc(o);\n                x(o | 0, 2736, 8);\n            }\n            h = (a + 288) | 0;\n            j = (a + 292) | 0;\n            c[j >> 2] = c[h >> 2];\n            o = (a + 259) | 0;\n            if ((d[o >> 0] |\n                (d[(o + 1) >> 0] << 8) |\n                (d[(o + 2) >> 0] << 16) |\n                (d[(o + 3) >> 0] << 24) |\n                0) ==\n                -1) {\n                o = v(8) | 0;\n                ic(o, 7606);\n                x(o | 0, 2720, 8);\n            }\n            f = (g + 4) | 0;\n            kc(h, ((c[f >> 2] | 0) + 1) | 0);\n            o = c[h >> 2] | 0;\n            c[o >> 2] = (c[i >> 2] | 0) + 8;\n            c[(o + 4) >> 2] = 0;\n            if ((c[f >> 2] | 0) >>> 0 > 1) {\n                Va(k, c[a >> 2] | 0);\n                lc(l, k);\n                mc(m, 32, 2, 8, 0);\n                nc(l);\n                oc(m);\n                if (!(c[f >> 2] | 0)) {\n                    h = c[h >> 2] | 0;\n                    e = h;\n                }\n                else {\n                    e = 1;\n                    do {\n                        if (e >>> 0 > 1)\n                            b = c[((c[h >> 2] | 0) + ((e + -1) << 3)) >> 2] | 0;\n                        else\n                            b = 0;\n                        i = pc(m, l, b, 1) | 0;\n                        b = c[h >> 2] | 0;\n                        o = (b + (e << 3)) | 0;\n                        c[o >> 2] = i;\n                        c[(o + 4) >> 2] = (((i | 0) < 0) << 31) >> 31;\n                        e = (e + 1) | 0;\n                    } while (e >>> 0 <= (c[f >> 2] | 0) >>> 0);\n                    e = b;\n                    h = b;\n                }\n                b = c[j >> 2] | 0;\n                if (((b - e) >> 3) >>> 0 > 1) {\n                    g = (b - h) >> 3;\n                    f = h;\n                    b = 1;\n                    e = c[f >> 2] | 0;\n                    f = c[(f + 4) >> 2] | 0;\n                    do {\n                        o = (h + (b << 3)) | 0;\n                        j = o;\n                        e = lr(c[j >> 2] | 0, c[(j + 4) >> 2] | 0, e | 0, f | 0) | 0;\n                        f = u() | 0;\n                        c[o >> 2] = e;\n                        c[(o + 4) >> 2] = f;\n                        b = (b + 1) | 0;\n                    } while (b >>> 0 < g >>> 0);\n                }\n                qc(m);\n                rc(l);\n                Ra(k);\n            }\n            V = n;\n            return;\n        }\n        function jb(b) {\n            b = b | 0;\n            a[(b + 12) >> 0] = 0;\n            a[(b + 13) >> 0] = 0;\n            return;\n        }\n        function kb(a) {\n            a = a | 0;\n            c[(a + 8) >> 2] = 0;\n            c[(a + 4) >> 2] = 0;\n            return;\n        }\n        function lb(a) {\n            a = a | 0;\n            return fo(a) | 0;\n        }\n        function mb(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            i = V;\n            V = (V + 16) | 0;\n            g = d;\n            h = i;\n            f = (e - g) | 0;\n            if (f >>> 0 > 4294967279)\n                yq(b);\n            if (f >>> 0 < 11)\n                a[(b + 11) >> 0] = f;\n            else {\n                k = (f + 16) & -16;\n                j = eq(k) | 0;\n                c[b >> 2] = j;\n                c[(b + 8) >> 2] = k | -2147483648;\n                c[(b + 4) >> 2] = f;\n                b = j;\n            }\n            if ((d | 0) != (e | 0)) {\n                g = (e - g) | 0;\n                f = b;\n                while (1) {\n                    nb(f, d);\n                    d = (d + 1) | 0;\n                    if ((d | 0) == (e | 0))\n                        break;\n                    else\n                        f = (f + 1) | 0;\n                }\n                b = (b + g) | 0;\n            }\n            a[h >> 0] = 0;\n            nb(b, h);\n            V = i;\n            return;\n        }\n        function nb(b, c) {\n            b = b | 0;\n            c = c | 0;\n            a[b >> 0] = a[c >> 0] | 0;\n            return;\n        }\n        function ob(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function pb(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = 4372;\n            c[(a + 16) >> 2] = a;\n            return;\n        }\n        function qb(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = b;\n            b = c[(b + 4) >> 2] | 0;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = b + ((d * 24) | 0);\n            return;\n        }\n        function rb(a) {\n            a = a | 0;\n            c[((c[a >> 2] | 0) + 4) >> 2] = c[(a + 4) >> 2];\n            return;\n        }\n        function sb(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0;\n            d = (b + 16) | 0;\n            e = c[d >> 2] | 0;\n            do\n                if (e)\n                    if ((b | 0) == (e | 0)) {\n                        e = tb(a) | 0;\n                        c[(a + 16) >> 2] = e;\n                        d = c[d >> 2] | 0;\n                        da[c[((c[d >> 2] | 0) + 12) >> 2] & 15](d, e);\n                        break;\n                    }\n                    else {\n                        c[(a + 16) >> 2] = e;\n                        c[d >> 2] = 0;\n                        break;\n                    }\n                else\n                    c[(a + 16) >> 2] = 0;\n            while (0);\n            return;\n        }\n        function tb(a) {\n            a = a | 0;\n            return a | 0;\n        }\n        function ub(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0;\n            f = (a + 12) | 0;\n            c[f >> 2] = 0;\n            c[(a + 16) >> 2] = e;\n            do\n                if (b)\n                    if (b >>> 0 > 178956970) {\n                        f = v(8) | 0;\n                        vq(f, 6723);\n                        c[f >> 2] = 5956;\n                        x(f | 0, 3928, 123);\n                    }\n                    else {\n                        e = eq((b * 24) | 0) | 0;\n                        break;\n                    }\n                else\n                    e = 0;\n            while (0);\n            c[a >> 2] = e;\n            d = (e + ((d * 24) | 0)) | 0;\n            c[(a + 8) >> 2] = d;\n            c[(a + 4) >> 2] = d;\n            c[f >> 2] = e + ((b * 24) | 0);\n            return;\n        }\n        function vb(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0;\n            i = c[a >> 2] | 0;\n            j = (a + 4) | 0;\n            d = c[j >> 2] | 0;\n            h = (b + 4) | 0;\n            if ((d | 0) == (i | 0)) {\n                f = h;\n                g = a;\n                e = c[h >> 2] | 0;\n                d = i;\n            }\n            else {\n                e = c[h >> 2] | 0;\n                do {\n                    d = (d + -24) | 0;\n                    sb((e + -24) | 0, d);\n                    e = ((c[h >> 2] | 0) + -24) | 0;\n                    c[h >> 2] = e;\n                } while ((d | 0) != (i | 0));\n                f = h;\n                g = a;\n                d = c[a >> 2] | 0;\n            }\n            c[g >> 2] = e;\n            c[f >> 2] = d;\n            i = (b + 8) | 0;\n            h = c[j >> 2] | 0;\n            c[j >> 2] = c[i >> 2];\n            c[i >> 2] = h;\n            i = (a + 8) | 0;\n            j = (b + 12) | 0;\n            a = c[i >> 2] | 0;\n            c[i >> 2] = c[j >> 2];\n            c[j >> 2] = a;\n            c[b >> 2] = c[f >> 2];\n            return;\n        }\n        function wb(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            d = c[(a + 4) >> 2] | 0;\n            e = (a + 8) | 0;\n            b = c[e >> 2] | 0;\n            if ((b | 0) != (d | 0))\n                do {\n                    f = (b + -24) | 0;\n                    c[e >> 2] = f;\n                    gb(f);\n                    b = c[e >> 2] | 0;\n                } while ((b | 0) != (d | 0));\n            b = c[a >> 2] | 0;\n            if (b | 0)\n                Da(b, ((c[(a + 12) >> 2] | 0) - b) | 0);\n            return;\n        }\n        function xb(a) {\n            a = a | 0;\n            return 178956970;\n        }\n        function yb(a) {\n            a = a | 0;\n            jp(a);\n            return;\n        }\n        function zb(a) {\n            a = a | 0;\n            a = eq(8) | 0;\n            c[a >> 2] = 4372;\n            return a | 0;\n        }\n        function Ab(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[b >> 2] = 4372;\n            return;\n        }\n        function Bb(a) {\n            a = a | 0;\n            return;\n        }\n        function Cb(a) {\n            a = a | 0;\n            Da(a, 8);\n            return;\n        }\n        function Db(a, b) {\n            a = a | 0;\n            b = b | 0;\n            Hb((a + 4) | 0, b);\n            return;\n        }\n        function Eb(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 7183 ? (a + 4) | 0 : 0) | 0;\n        }\n        function Fb(a) {\n            a = a | 0;\n            return 2664;\n        }\n        function Gb(a) {\n            a = a | 0;\n            return;\n        }\n        function Hb(a, b) {\n            a = a | 0;\n            b = b | 0;\n            Ib(a, b);\n            return;\n        }\n        function Ib(b, c) {\n            b = b | 0;\n            c = c | 0;\n            var e = 0, f = 0;\n            b = (c + 104) | 0;\n            c = d[b >> 0] | 0;\n            e = c >>> 7;\n            f = (c >>> 6) & 1;\n            if (((e | 0) == 1) & ((f | 0) != 0)) {\n                f = v(8) | 0;\n                Jb(f);\n                x(f | 0, 2632, 8);\n            }\n            if ((e | 0) == (f | 0)) {\n                f = v(8) | 0;\n                Kb(f);\n                x(f | 0, 2648, 8);\n            }\n            else {\n                a[b >> 0] = c & 63;\n                return;\n            }\n        }\n        function Jb(a) {\n            a = a | 0;\n            xq(a, 7076);\n            c[a >> 2] = 4416;\n            return;\n        }\n        function Kb(a) {\n            a = a | 0;\n            xq(a, 7144);\n            c[a >> 2] = 4436;\n            return;\n        }\n        function Lb(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function Mb(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function Nb(a) {\n            a = a | 0;\n            c[a >> 2] = 6092;\n            return;\n        }\n        function Ob(b) {\n            b = b | 0;\n            var c = 0;\n            c = (b + 12) | 0;\n            b = (a[c >> 0] | 0) == 0;\n            a[c >> 0] = 0;\n            return b | 0;\n        }\n        function Pb(b) {\n            b = b | 0;\n            return ((a[(b + 13) >> 0] | 0) != 0) | 0;\n        }\n        function Qb(a, b) {\n            a = a | 0;\n            b = b | 0;\n            a = (a + 247) | 0;\n            Vb(a, b);\n            if (((d[a >> 0] | (d[(a + 1) >> 0] << 8)) << 16) >> 16 == 2)\n                return;\n            else {\n                b = v(8) | 0;\n                Wb(b);\n                x(b | 0, 2688, 8);\n            }\n        }\n        function Rb(b, d, e, f) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0, h = 0;\n            switch (f | 0) {\n                case 0:\n                    break;\n                case 2: {\n                    f = c[(b + 4) >> 2] | 0;\n                    d =\n                        lr(lr(d | 0, e | 0, -1, -1) | 0, u() | 0, f | 0, ((((f | 0) < 0) << 31) >> 31) | 0) | 0;\n                    e = u() | 0;\n                    break;\n                }\n                case 1: {\n                    f = c[(b + 8) >> 2] | 0;\n                    d = lr(f | 0, ((((f | 0) < 0) << 31) >> 31) | 0, d | 0, e | 0) | 0;\n                    e = u() | 0;\n                    break;\n                }\n                default: {\n                    e = 0;\n                    d = 0;\n                }\n            }\n            g = c[(b + 4) >> 2] | 0;\n            h = (((g | 0) < 0) << 31) >> 31;\n            f = (b + 12) | 0;\n            if (((e | 0) < 0) | (((e | 0) > (h | 0)) | (((e | 0) == (h | 0)) & (d >>> 0 >= g >>> 0))))\n                a[f >> 0] = 1;\n            else {\n                a[f >> 0] = 0;\n                c[(b + 8) >> 2] = d;\n            }\n            return;\n        }\n        function Sb(a) {\n            a = a | 0;\n            xq(a, 7410);\n            c[a >> 2] = 4476;\n            return;\n        }\n        function Tb(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            h = V;\n            V = (V + 16) | 0;\n            g = h;\n            Xa(a);\n            f = (b + 32) | 0;\n            if (((d[f >> 0] | (d[(f + 1) >> 0] << 8)) << 16) >> 16) {\n                e = (b + 34) | 0;\n                b = 0;\n                do {\n                    j =\n                        d[e >> 0] | (d[(e + 1) >> 0] << 8) | (d[(e + 2) >> 0] << 16) | (d[(e + 3) >> 0] << 24);\n                    k = (j + ((b * 6) | 0)) | 0;\n                    i = (j + ((b * 6) | 0) + 2) | 0;\n                    j = (j + ((b * 6) | 0) + 4) | 0;\n                    _b(g, (d[k >> 0] | (d[(k + 1) >> 0] << 8)) & 65535, (d[i >> 0] | (d[(i + 1) >> 0] << 8)) & 65535, (d[j >> 0] | (d[(j + 1) >> 0] << 8)) & 65535);\n                    Zb(a, g);\n                    c = (c - ((d[i >> 0] | (d[(i + 1) >> 0] << 8)) & 65535)) | 0;\n                    b = (b + 1) | 0;\n                } while (b >>> 0 < ((d[f >> 0] | (d[(f + 1) >> 0] << 8)) & 65535) >>> 0);\n            }\n            if ((c | 0) < 0) {\n                k = v(8) | 0;\n                Wb(k);\n                x(k | 0, 2688, 8);\n            }\n            if (c | 0) {\n                _b(g, 0, c, 2);\n                Zb(a, g);\n            }\n            V = h;\n            return;\n        }\n        function Ub(b, c) {\n            b = b | 0;\n            c = c | 0;\n            var d = 0, e = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = (d + 1) | 0;\n            a[e >> 0] = a[d >> 0] | 0;\n            fc(b, c, e);\n            V = d;\n            return b | 0;\n        }\n        function Vb(b, c) {\n            b = b | 0;\n            c = c | 0;\n            var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            f = (c + 2) | 0;\n            h = d[c >> 0] | (d[(c + 1) >> 0] << 8);\n            a[b >> 0] = h;\n            a[(b + 1) >> 0] = h >> 8;\n            h = (b + 2) | 0;\n            f = d[f >> 0] | (d[(f + 1) >> 0] << 8);\n            a[h >> 0] = f;\n            a[(h + 1) >> 0] = f >> 8;\n            a[(b + 4) >> 0] = a[(c + 4) >> 0] | 0;\n            h = (c + 6) | 0;\n            a[(b + 5) >> 0] = a[(c + 5) >> 0] | 0;\n            f = (c + 8) | 0;\n            e = (b + 6) | 0;\n            h = d[h >> 0] | (d[(h + 1) >> 0] << 8);\n            a[e >> 0] = h;\n            a[(e + 1) >> 0] = h >> 8;\n            e = (c + 12) | 0;\n            h = (b + 8) | 0;\n            f = d[f >> 0] | (d[(f + 1) >> 0] << 8) | (d[(f + 2) >> 0] << 16) | (d[(f + 3) >> 0] << 24);\n            a[h >> 0] = f;\n            a[(h + 1) >> 0] = f >> 8;\n            a[(h + 2) >> 0] = f >> 16;\n            a[(h + 3) >> 0] = f >> 24;\n            h = (b + 12) | 0;\n            e = d[e >> 0] | (d[(e + 1) >> 0] << 8) | (d[(e + 2) >> 0] << 16) | (d[(e + 3) >> 0] << 24);\n            a[h >> 0] = e;\n            a[(h + 1) >> 0] = e >> 8;\n            a[(h + 2) >> 0] = e >> 16;\n            a[(h + 3) >> 0] = e >> 24;\n            h = (c + 16) | 0;\n            e = h;\n            e = d[e >> 0] | (d[(e + 1) >> 0] << 8) | (d[(e + 2) >> 0] << 16) | (d[(e + 3) >> 0] << 24);\n            h = (h + 4) | 0;\n            h = d[h >> 0] | (d[(h + 1) >> 0] << 8) | (d[(h + 2) >> 0] << 16) | (d[(h + 3) >> 0] << 24);\n            f = (b + 16) | 0;\n            i = f;\n            a[i >> 0] = e;\n            a[(i + 1) >> 0] = e >> 8;\n            a[(i + 2) >> 0] = e >> 16;\n            a[(i + 3) >> 0] = e >> 24;\n            f = (f + 4) | 0;\n            a[f >> 0] = h;\n            a[(f + 1) >> 0] = h >> 8;\n            a[(f + 2) >> 0] = h >> 16;\n            a[(f + 3) >> 0] = h >> 24;\n            f = (c + 32) | 0;\n            h = (c + 24) | 0;\n            i = h;\n            i = d[i >> 0] | (d[(i + 1) >> 0] << 8) | (d[(i + 2) >> 0] << 16) | (d[(i + 3) >> 0] << 24);\n            h = (h + 4) | 0;\n            h = d[h >> 0] | (d[(h + 1) >> 0] << 8) | (d[(h + 2) >> 0] << 16) | (d[(h + 3) >> 0] << 24);\n            e = (b + 24) | 0;\n            g = e;\n            a[g >> 0] = i;\n            a[(g + 1) >> 0] = i >> 8;\n            a[(g + 2) >> 0] = i >> 16;\n            a[(g + 3) >> 0] = i >> 24;\n            e = (e + 4) | 0;\n            a[e >> 0] = h;\n            a[(e + 1) >> 0] = h >> 8;\n            a[(e + 2) >> 0] = h >> 16;\n            a[(e + 3) >> 0] = h >> 24;\n            e = (c + 34) | 0;\n            h = (b + 32) | 0;\n            f = d[f >> 0] | (d[(f + 1) >> 0] << 8);\n            a[h >> 0] = f;\n            a[(h + 1) >> 0] = f >> 8;\n            g = (b + 34) | 0;\n            b = d[g >> 0] | (d[(g + 1) >> 0] << 8) | (d[(g + 2) >> 0] << 16) | (d[(g + 3) >> 0] << 24);\n            if (!b)\n                b = f;\n            else {\n                gq(b);\n                b = d[h >> 0] | (d[(h + 1) >> 0] << 8);\n            }\n            f = fq(((b & 65535) * 6) | 0) | 0;\n            a[g >> 0] = f;\n            a[(g + 1) >> 0] = f >> 8;\n            a[(g + 2) >> 0] = f >> 16;\n            a[(g + 3) >> 0] = f >> 24;\n            if ((b << 16) >> 16\n                ? ((b = (c + 36) | 0),\n                    (i = d[e >> 0] | (d[(e + 1) >> 0] << 8)),\n                    (a[f >> 0] = i),\n                    (a[(f + 1) >> 0] = i >> 8),\n                    (c = (c + 38) | 0),\n                    (i = (f + 2) | 0),\n                    (b = d[b >> 0] | (d[(b + 1) >> 0] << 8)),\n                    (a[i >> 0] = b),\n                    (a[(i + 1) >> 0] = b >> 8),\n                    (i = (f + 4) | 0),\n                    (c = d[c >> 0] | (d[(c + 1) >> 0] << 8)),\n                    (a[i >> 0] = c),\n                    (a[(i + 1) >> 0] = c >> 8),\n                    ((d[h >> 0] | (d[(h + 1) >> 0] << 8)) & 65535) > 1)\n                : 0) {\n                b = 1;\n                do {\n                    c = e;\n                    e = (e + 6) | 0;\n                    i =\n                        d[g >> 0] | (d[(g + 1) >> 0] << 8) | (d[(g + 2) >> 0] << 16) | (d[(g + 3) >> 0] << 24);\n                    j = (c + 8) | 0;\n                    f = (i + ((b * 6) | 0)) | 0;\n                    k = d[e >> 0] | (d[(e + 1) >> 0] << 8);\n                    a[f >> 0] = k;\n                    a[(f + 1) >> 0] = k >> 8;\n                    c = (c + 10) | 0;\n                    f = (i + ((b * 6) | 0) + 2) | 0;\n                    j = d[j >> 0] | (d[(j + 1) >> 0] << 8);\n                    a[f >> 0] = j;\n                    a[(f + 1) >> 0] = j >> 8;\n                    i = (i + ((b * 6) | 0) + 4) | 0;\n                    c = d[c >> 0] | (d[(c + 1) >> 0] << 8);\n                    a[i >> 0] = c;\n                    a[(i + 1) >> 0] = c >> 8;\n                    b = (b + 1) | 0;\n                } while (b >>> 0 < ((d[h >> 0] | (d[(h + 1) >> 0] << 8)) & 65535) >>> 0);\n            }\n            return;\n        }\n        function Wb(a) {\n            a = a | 0;\n            xq(a, 7354);\n            c[a >> 2] = 4456;\n            return;\n        }\n        function Xb(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function Yb(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function Zb(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            i = V;\n            V = (V + 32) | 0;\n            f = i;\n            g = (a + 4) | 0;\n            d = c[g >> 2] | 0;\n            h = (a + 8) | 0;\n            do\n                if ((d | 0) == (c[h >> 2] | 0)) {\n                    d = (((((d - (c[a >> 2] | 0)) | 0) / 12) | 0) + 1) | 0;\n                    e = ec(a) | 0;\n                    if (e >>> 0 < d >>> 0)\n                        cr(a);\n                    else {\n                        j = c[a >> 2] | 0;\n                        k = ((((c[h >> 2] | 0) - j) | 0) / 12) | 0;\n                        h = k << 1;\n                        bc(f, k >>> 0 < (e >>> 1) >>> 0 ? (h >>> 0 < d >>> 0 ? d : h) : e, ((((c[g >> 2] | 0) - j) | 0) / 12) | 0, (a + 8) | 0);\n                        h = (f + 8) | 0;\n                        g = c[h >> 2] | 0;\n                        c[g >> 2] = c[b >> 2];\n                        c[(g + 4) >> 2] = c[(b + 4) >> 2];\n                        c[(g + 8) >> 2] = c[(b + 8) >> 2];\n                        c[h >> 2] = (c[h >> 2] | 0) + 12;\n                        cc(a, f);\n                        dc(f);\n                        break;\n                    }\n                }\n                else {\n                    $b(f, a, 1);\n                    k = (f + 4) | 0;\n                    j = c[k >> 2] | 0;\n                    c[j >> 2] = c[b >> 2];\n                    c[(j + 4) >> 2] = c[(b + 4) >> 2];\n                    c[(j + 8) >> 2] = c[(b + 8) >> 2];\n                    c[k >> 2] = (c[k >> 2] | 0) + 12;\n                    ac(f);\n                }\n            while (0);\n            V = i;\n            return;\n        }\n        function _b(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            c[a >> 2] = b;\n            c[(a + 4) >> 2] = d;\n            c[(a + 8) >> 2] = e;\n            return;\n        }\n        function $b(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = b;\n            b = c[(b + 4) >> 2] | 0;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = b + ((d * 12) | 0);\n            return;\n        }\n        function ac(a) {\n            a = a | 0;\n            c[((c[a >> 2] | 0) + 4) >> 2] = c[(a + 4) >> 2];\n            return;\n        }\n        function bc(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0;\n            f = (a + 12) | 0;\n            c[f >> 2] = 0;\n            c[(a + 16) >> 2] = e;\n            do\n                if (b)\n                    if (b >>> 0 > 357913941) {\n                        f = v(8) | 0;\n                        vq(f, 6723);\n                        c[f >> 2] = 5956;\n                        x(f | 0, 3928, 123);\n                    }\n                    else {\n                        e = eq((b * 12) | 0) | 0;\n                        break;\n                    }\n                else\n                    e = 0;\n            while (0);\n            c[a >> 2] = e;\n            d = (e + ((d * 12) | 0)) | 0;\n            c[(a + 8) >> 2] = d;\n            c[(a + 4) >> 2] = d;\n            c[f >> 2] = e + ((b * 12) | 0);\n            return;\n        }\n        function cc(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0;\n            e = c[a >> 2] | 0;\n            h = (a + 4) | 0;\n            g = (b + 4) | 0;\n            f = ((c[h >> 2] | 0) - e) | 0;\n            d = ((c[g >> 2] | 0) + (((((f | 0) / -12) | 0) * 12) | 0)) | 0;\n            c[g >> 2] = d;\n            if ((f | 0) > 0) {\n                ur(d | 0, e | 0, f | 0) | 0;\n                e = g;\n                d = c[g >> 2] | 0;\n            }\n            else\n                e = g;\n            g = c[a >> 2] | 0;\n            c[a >> 2] = d;\n            c[e >> 2] = g;\n            g = (b + 8) | 0;\n            f = c[h >> 2] | 0;\n            c[h >> 2] = c[g >> 2];\n            c[g >> 2] = f;\n            g = (a + 8) | 0;\n            h = (b + 12) | 0;\n            a = c[g >> 2] | 0;\n            c[g >> 2] = c[h >> 2];\n            c[h >> 2] = a;\n            c[b >> 2] = c[e >> 2];\n            return;\n        }\n        function dc(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = c[(a + 4) >> 2] | 0;\n            d = (a + 8) | 0;\n            e = c[d >> 2] | 0;\n            if ((e | 0) != (b | 0))\n                c[d >> 2] = e + ((~(((((e + -12 - b) | 0) >>> 0) / 12) | 0) * 12) | 0);\n            b = c[a >> 2] | 0;\n            if (b | 0)\n                Da(b, ((c[(a + 12) >> 2] | 0) - b) | 0);\n            return;\n        }\n        function ec(a) {\n            a = a | 0;\n            return 357913941;\n        }\n        function fc(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0;\n            gc(a);\n            c[a >> 2] = c[b >> 2];\n            d = (b + 4) | 0;\n            c[(a + 4) >> 2] = c[d >> 2];\n            e = (b + 8) | 0;\n            c[(a + 8) >> 2] = c[e >> 2];\n            c[e >> 2] = 0;\n            c[d >> 2] = 0;\n            c[b >> 2] = 0;\n            return;\n        }\n        function gc(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            b = c[a >> 2] | 0;\n            d = b;\n            if (b | 0) {\n                e = (a + 4) | 0;\n                c[e >> 2] = d;\n                f = (a + 8) | 0;\n                Da(b, ((c[f >> 2] | 0) - d) | 0);\n                c[f >> 2] = 0;\n                c[e >> 2] = 0;\n                c[a >> 2] = 0;\n            }\n            return;\n        }\n        function hc(a) {\n            a = a | 0;\n            xq(a, 7660);\n            c[a >> 2] = 4496;\n            return;\n        }\n        function ic(a, b) {\n            a = a | 0;\n            b = b | 0;\n            xq(a, b);\n            c[a >> 2] = 4516;\n            return;\n        }\n        function jc(a) {\n            a = a | 0;\n            xq(a, 7704);\n            c[a >> 2] = 4536;\n            return;\n        }\n        function kc(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0;\n            d = (a + 4) | 0;\n            f = c[a >> 2] | 0;\n            e = ((c[d >> 2] | 0) - f) >> 3;\n            if (e >>> 0 >= b >>> 0) {\n                if (e >>> 0 > b >>> 0)\n                    c[d >> 2] = f + (b << 3);\n            }\n            else\n                vc(a, (b - e) | 0);\n            return;\n        }\n        function lc(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = b;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = -1;\n            return;\n        }\n        function mc(a, b, d, e, f) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = d;\n            c[(a + 12) >> 2] = e;\n            c[(a + 16) >> 2] = f;\n            c[(a + 36) >> 2] = 0;\n            c[(a + 40) >> 2] = 0;\n            c[(a + 44) >> 2] = 0;\n            Gc((a + 48) | 0);\n            c[(a + 68) >> 2] = 0;\n            c[(a + 72) >> 2] = 0;\n            c[(a + 76) >> 2] = 0;\n            do\n                if (!f) {\n                    d = (a + 20) | 0;\n                    if (((b + -1) | 0) >>> 0 < 31) {\n                        c[d >> 2] = b;\n                        f = 1 << b;\n                        c[(a + 24) >> 2] = f;\n                        d = f >>> 1;\n                        c[(a + 28) >> 2] = 0 - d;\n                        d = (f + -1 - d) | 0;\n                        break;\n                    }\n                    else {\n                        c[d >> 2] = 32;\n                        c[(a + 24) >> 2] = 0;\n                        c[(a + 28) >> 2] = -2147483648;\n                        d = 2147483647;\n                        break;\n                    }\n                }\n                else {\n                    e = (a + 20) | 0;\n                    c[e >> 2] = 0;\n                    c[(a + 24) >> 2] = f;\n                    d = f;\n                    g = 0;\n                    while (1) {\n                        d = d >>> 1;\n                        b = (g + 1) | 0;\n                        if (!d)\n                            break;\n                        else\n                            g = b;\n                    }\n                    c[e >> 2] = ((1 << g) | 0) == (f | 0) ? g : b;\n                    d = f >>> 1;\n                    c[(a + 28) >> 2] = 0 - d;\n                    d = (f + -1 - d) | 0;\n                }\n            while (0);\n            c[(a + 32) >> 2] = d;\n            c[a >> 2] = 0;\n            return;\n        }\n        function nc(a) {\n            a = a | 0;\n            var b = 0;\n            b = ((Jc(c[a >> 2] | 0) | 0) & 255) << 24;\n            b = (((Jc(c[a >> 2] | 0) | 0) & 255) << 16) | b;\n            b = b | (((Jc(c[a >> 2] | 0) | 0) & 255) << 8);\n            c[(a + 4) >> 2] = b | ((Jc(c[a >> 2] | 0) | 0) & 255);\n            return;\n        }\n        function oc(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0;\n            q = V;\n            V = (V + 64) | 0;\n            o = (q + 44) | 0;\n            p = q;\n            k = (a + 36) | 0;\n            l = (a + 40) | 0;\n            a: do\n                if ((c[k >> 2] | 0) == (c[l >> 2] | 0)) {\n                    m = (a + 8) | 0;\n                    b: do\n                        if (!(c[m >> 2] | 0))\n                            n = (a + 20) | 0;\n                        else {\n                            f = (a + 20) | 0;\n                            g = (a + 44) | 0;\n                            h = (o + 4) | 0;\n                            i = (a + 44) | 0;\n                            j = (o + 8) | 0;\n                            e = 0;\n                            while (1) {\n                                Oc(p, ((c[f >> 2] | 0) + 1) | 0, 0, 0);\n                                b = c[l >> 2] | 0;\n                                if (b >>> 0 < (c[g >> 2] | 0) >>> 0) {\n                                    Pc(o, k, 1);\n                                    Rc(c[h >> 2] | 0, p);\n                                    c[h >> 2] = (c[h >> 2] | 0) + 44;\n                                    Qc(o);\n                                }\n                                else {\n                                    b = (((((b - (c[k >> 2] | 0)) | 0) / 44) | 0) + 1) | 0;\n                                    d = Vc(k) | 0;\n                                    if (d >>> 0 < b >>> 0)\n                                        break;\n                                    r = c[k >> 2] | 0;\n                                    t = ((((c[g >> 2] | 0) - r) | 0) / 44) | 0;\n                                    s = t << 1;\n                                    Sc(o, t >>> 0 < (d >>> 1) >>> 0 ? (s >>> 0 < b >>> 0 ? b : s) : d, ((((c[l >> 2] | 0) - r) | 0) / 44) | 0, i);\n                                    Rc(c[j >> 2] | 0, p);\n                                    c[j >> 2] = (c[j >> 2] | 0) + 44;\n                                    Tc(k, o);\n                                    Uc(o);\n                                }\n                                Ic(p);\n                                e = (e + 1) | 0;\n                                if (e >>> 0 >= (c[m >> 2] | 0) >>> 0) {\n                                    n = f;\n                                    break b;\n                                }\n                            }\n                            cr(k);\n                        }\n                    while (0);\n                    if (c[n >> 2] | 0) {\n                        h = (a + 12) | 0;\n                        i = (a + 68) | 0;\n                        j = (a + 72) | 0;\n                        k = (a + 76) | 0;\n                        l = (o + 4) | 0;\n                        f = (a + 76) | 0;\n                        g = (o + 8) | 0;\n                        e = 1;\n                        while (1) {\n                            b = c[h >> 2] | 0;\n                            Oc(p, 1 << (e >>> 0 > b >>> 0 ? b : e), 0, 0);\n                            b = c[j >> 2] | 0;\n                            if (b >>> 0 < (c[k >> 2] | 0) >>> 0) {\n                                Pc(o, i, 1);\n                                Rc(c[l >> 2] | 0, p);\n                                c[l >> 2] = (c[l >> 2] | 0) + 44;\n                                Qc(o);\n                            }\n                            else {\n                                b = (((((b - (c[i >> 2] | 0)) | 0) / 44) | 0) + 1) | 0;\n                                d = Vc(i) | 0;\n                                if (d >>> 0 < b >>> 0)\n                                    break;\n                                t = c[i >> 2] | 0;\n                                r = ((((c[k >> 2] | 0) - t) | 0) / 44) | 0;\n                                s = r << 1;\n                                Sc(o, r >>> 0 < (d >>> 1) >>> 0 ? (s >>> 0 < b >>> 0 ? b : s) : d, ((((c[j >> 2] | 0) - t) | 0) / 44) | 0, f);\n                                Rc(c[g >> 2] | 0, p);\n                                c[g >> 2] = (c[g >> 2] | 0) + 44;\n                                Tc(i, o);\n                                Uc(o);\n                            }\n                            Ic(p);\n                            e = (e + 1) | 0;\n                            if (e >>> 0 > (c[n >> 2] | 0) >>> 0)\n                                break a;\n                        }\n                        cr(i);\n                    }\n                }\n            while (0);\n            V = q;\n            return;\n        }\n        function pc(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            d = ((Yc(a, b, ((c[(a + 36) >> 2] | 0) + ((e * 44) | 0)) | 0) | 0) + d) | 0;\n            b = c[(a + 24) >> 2] | 0;\n            if ((d | 0) < 0)\n                return (d + b) | 0;\n            else\n                return (d - (d >>> 0 < b >>> 0 ? 0 : b)) | 0;\n            return 0;\n        }\n        function qc(a) {\n            a = a | 0;\n            Hc((a + 68) | 0);\n            Hc((a + 36) | 0);\n            return;\n        }\n        function rc(a) {\n            a = a | 0;\n            return;\n        }\n        function sc(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function tc(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function uc(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function vc(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            i = V;\n            V = (V + 32) | 0;\n            f = i;\n            g = (a + 8) | 0;\n            h = (a + 4) | 0;\n            d = c[h >> 2] | 0;\n            do\n                if ((((c[g >> 2] | 0) - d) >> 3) >>> 0 < b >>> 0) {\n                    d = (((d - (c[a >> 2] | 0)) >> 3) + b) | 0;\n                    e = Dc(a) | 0;\n                    if (e >>> 0 < d >>> 0)\n                        cr(a);\n                    else {\n                        j = c[a >> 2] | 0;\n                        k = ((c[g >> 2] | 0) - j) | 0;\n                        g = k >> 2;\n                        xc(f, (k >> 3) >>> 0 < (e >>> 1) >>> 0 ? (g >>> 0 < d >>> 0 ? d : g) : e, ((c[h >> 2] | 0) - j) >> 3, (a + 8) | 0);\n                        yc(f, b);\n                        zc(a, f);\n                        Ac(f);\n                        break;\n                    }\n                }\n                else\n                    wc(a, b);\n            while (0);\n            V = i;\n            return;\n        }\n        function wc(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0;\n            f = V;\n            V = (V + 16) | 0;\n            e = f;\n            Bc(e, a, b);\n            a = (e + 4) | 0;\n            b = c[a >> 2] | 0;\n            d = c[(e + 8) >> 2] | 0;\n            if ((b | 0) != (d | 0)) {\n                d = (d + -8 - b) | 0;\n                wr(b | 0, 0, ((d + 8) & -8) | 0) | 0;\n                c[a >> 2] = b + (((d >>> 3) + 1) << 3);\n            }\n            Cc(e);\n            V = f;\n            return;\n        }\n        function xc(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0;\n            f = (a + 12) | 0;\n            c[f >> 2] = 0;\n            c[(a + 16) >> 2] = e;\n            do\n                if (b)\n                    if (b >>> 0 > 536870911) {\n                        f = v(8) | 0;\n                        vq(f, 6723);\n                        c[f >> 2] = 5956;\n                        x(f | 0, 3928, 123);\n                    }\n                    else {\n                        e = eq(b << 3) | 0;\n                        break;\n                    }\n                else\n                    e = 0;\n            while (0);\n            c[a >> 2] = e;\n            d = (e + (d << 3)) | 0;\n            c[(a + 8) >> 2] = d;\n            c[(a + 4) >> 2] = d;\n            c[f >> 2] = e + (b << 3);\n            return;\n        }\n        function yc(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0;\n            e = V;\n            V = (V + 16) | 0;\n            d = e;\n            Ec(d, (a + 8) | 0, b);\n            a = c[d >> 2] | 0;\n            b = c[(d + 4) >> 2] | 0;\n            if ((a | 0) != (b | 0)) {\n                b = (b + -8 - a) | 0;\n                wr(a | 0, 0, ((b + 8) & -8) | 0) | 0;\n                c[d >> 2] = a + (((b >>> 3) + 1) << 3);\n            }\n            Fc(d);\n            V = e;\n            return;\n        }\n        function zc(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0;\n            e = c[a >> 2] | 0;\n            h = (a + 4) | 0;\n            g = (b + 4) | 0;\n            f = ((c[h >> 2] | 0) - e) | 0;\n            d = ((c[g >> 2] | 0) + ((0 - (f >> 3)) << 3)) | 0;\n            c[g >> 2] = d;\n            if ((f | 0) > 0) {\n                ur(d | 0, e | 0, f | 0) | 0;\n                e = g;\n                d = c[g >> 2] | 0;\n            }\n            else\n                e = g;\n            g = c[a >> 2] | 0;\n            c[a >> 2] = d;\n            c[e >> 2] = g;\n            g = (b + 8) | 0;\n            f = c[h >> 2] | 0;\n            c[h >> 2] = c[g >> 2];\n            c[g >> 2] = f;\n            g = (a + 8) | 0;\n            h = (b + 12) | 0;\n            a = c[g >> 2] | 0;\n            c[g >> 2] = c[h >> 2];\n            c[h >> 2] = a;\n            c[b >> 2] = c[e >> 2];\n            return;\n        }\n        function Ac(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = c[(a + 4) >> 2] | 0;\n            d = (a + 8) | 0;\n            e = c[d >> 2] | 0;\n            if ((e | 0) != (b | 0))\n                c[d >> 2] = e + (~(((e + -8 - b) | 0) >>> 3) << 3);\n            b = c[a >> 2] | 0;\n            if (b | 0)\n                Da(b, ((c[(a + 12) >> 2] | 0) - b) | 0);\n            return;\n        }\n        function Bc(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = b;\n            b = c[(b + 4) >> 2] | 0;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = b + (d << 3);\n            return;\n        }\n        function Cc(a) {\n            a = a | 0;\n            c[((c[a >> 2] | 0) + 4) >> 2] = c[(a + 4) >> 2];\n            return;\n        }\n        function Dc(a) {\n            a = a | 0;\n            return 536870911;\n        }\n        function Ec(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = c[b >> 2];\n            c[(a + 4) >> 2] = (c[b >> 2] | 0) + (d << 3);\n            c[(a + 8) >> 2] = b;\n            return;\n        }\n        function Fc(a) {\n            a = a | 0;\n            c[c[(a + 8) >> 2] >> 2] = c[a >> 2];\n            return;\n        }\n        function Gc(a) {\n            a = a | 0;\n            c[(a + 12) >> 2] = 1;\n            c[(a + 16) >> 2] = 2;\n            c[(a + 8) >> 2] = 4096;\n            c[(a + 4) >> 2] = 4;\n            c[a >> 2] = 4;\n            return;\n        }\n        function Hc(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            d = c[a >> 2] | 0;\n            if (d | 0) {\n                e = (a + 4) | 0;\n                b = c[e >> 2] | 0;\n                if ((b | 0) == (d | 0))\n                    b = d;\n                else {\n                    do {\n                        b = (b + -44) | 0;\n                        Ic(b);\n                    } while ((b | 0) != (d | 0));\n                    b = c[a >> 2] | 0;\n                }\n                c[e >> 2] = d;\n                Da(b, ((c[(a + 8) >> 2] | 0) - b) | 0);\n            }\n            return;\n        }\n        function Ic(a) {\n            a = a | 0;\n            var b = 0;\n            b = c[(a + 8) >> 2] | 0;\n            if (b | 0)\n                Ua(b);\n            b = c[(a + 12) >> 2] | 0;\n            if (b | 0)\n                Ua(b);\n            b = c[(a + 16) >> 2] | 0;\n            if (b | 0)\n                Ua(b);\n            return;\n        }\n        function Jc(b) {\n            b = b | 0;\n            var d = 0, e = 0;\n            e = (b + 4) | 0;\n            d = c[e >> 2] | 0;\n            if ((d | 0) >= (c[(b + 8) >> 2] | 0)) {\n                Kc(b);\n                d = c[e >> 2] | 0;\n            }\n            b = c[(b + 12) >> 2] | 0;\n            c[e >> 2] = d + 1;\n            return a[(b + d) >> 0] | 0;\n        }\n        function Kc(a) {\n            a = a | 0;\n            var b = 0;\n            c[(a + 4) >> 2] = 0;\n            $a(c[a >> 2] | 0, c[(a + 12) >> 2] | 0, 1048576);\n            b = Lc(c[a >> 2] | 0) | 0;\n            c[(a + 8) >> 2] = b;\n            if (!b) {\n                b = v(8) | 0;\n                Mc(b);\n                x(b | 0, 2752, 8);\n            }\n            else\n                return;\n        }\n        function Lc(a) {\n            a = a | 0;\n            return c[(a + 16) >> 2] | 0;\n        }\n        function Mc(a) {\n            a = a | 0;\n            xq(a, 7769);\n            c[a >> 2] = 4556;\n            return;\n        }\n        function Nc(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function Oc(b, d, e, f) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0, h = 0, i = 0;\n            c[b >> 2] = d;\n            a[(b + 4) >> 0] = e & 1;\n            h = (b + 8) | 0;\n            c[h >> 2] = 0;\n            i = (b + 12) | 0;\n            c[i >> 2] = 0;\n            g = (b + 16) | 0;\n            c[g >> 2] = 0;\n            if (((d + -2) | 0) >>> 0 > 2046) {\n                b = v(8) | 0;\n                xq(b, 7789);\n                x(b | 0, 3912, 8);\n            }\n            c[(b + 32) >> 2] = d + -1;\n            if ((d >>> 0 > 16) & (e ^ 1)) {\n                e = 3;\n                while (1)\n                    if ((1 << (e + 2)) >>> 0 < d >>> 0)\n                        e = (e + 1) | 0;\n                    else\n                        break;\n                d = 1 << e;\n                c[(b + 36) >> 2] = d;\n                c[(b + 40) >> 2] = 15 - e;\n                c[g >> 2] = _a(((d << 2) + 8) | 0) | 0;\n                d = c[b >> 2] | 0;\n            }\n            else {\n                c[g >> 2] = 0;\n                c[(b + 40) >> 2] = 0;\n                c[(b + 36) >> 2] = 0;\n            }\n            c[h >> 2] = _a(d << 2) | 0;\n            g = _a(c[b >> 2] << 2) | 0;\n            c[i >> 2] = g;\n            c[(b + 20) >> 2] = 0;\n            d = c[b >> 2] | 0;\n            e = (b + 24) | 0;\n            c[e >> 2] = d;\n            d = (d | 0) != 0;\n            if (!f) {\n                if (d) {\n                    d = 0;\n                    do {\n                        c[(g + (d << 2)) >> 2] = 1;\n                        d = (d + 1) | 0;\n                    } while (d >>> 0 < (c[b >> 2] | 0) >>> 0);\n                }\n            }\n            else if (d) {\n                d = 0;\n                do {\n                    c[(g + (d << 2)) >> 2] = c[(f + (d << 2)) >> 2];\n                    d = (d + 1) | 0;\n                } while (d >>> 0 < (c[b >> 2] | 0) >>> 0);\n            }\n            Xc(b);\n            f = (((c[b >> 2] | 0) + 6) | 0) >>> 1;\n            c[e >> 2] = f;\n            c[(b + 28) >> 2] = f;\n            return;\n        }\n        function Pc(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = b;\n            b = c[(b + 4) >> 2] | 0;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = b + ((d * 44) | 0);\n            return;\n        }\n        function Qc(a) {\n            a = a | 0;\n            c[((c[a >> 2] | 0) + 4) >> 2] = c[(a + 4) >> 2];\n            return;\n        }\n        function Rc(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0;\n            c[b >> 2] = c[d >> 2];\n            a[(b + 4) >> 0] = a[(d + 4) >> 0] | 0;\n            e = (d + 8) | 0;\n            c[(b + 8) >> 2] = c[e >> 2];\n            c[(b + 12) >> 2] = c[(d + 12) >> 2];\n            c[(b + 16) >> 2] = c[(d + 16) >> 2];\n            c[(b + 20) >> 2] = c[(d + 20) >> 2];\n            c[(b + 24) >> 2] = c[(d + 24) >> 2];\n            c[(b + 28) >> 2] = c[(d + 28) >> 2];\n            c[(b + 32) >> 2] = c[(d + 32) >> 2];\n            c[(b + 36) >> 2] = c[(d + 36) >> 2];\n            c[(b + 40) >> 2] = c[(d + 40) >> 2];\n            c[e >> 2] = 0;\n            c[(e + 4) >> 2] = 0;\n            c[(e + 8) >> 2] = 0;\n            return;\n        }\n        function Sc(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0;\n            f = (a + 12) | 0;\n            c[f >> 2] = 0;\n            c[(a + 16) >> 2] = e;\n            do\n                if (b)\n                    if (b >>> 0 > 97612893) {\n                        f = v(8) | 0;\n                        vq(f, 6723);\n                        c[f >> 2] = 5956;\n                        x(f | 0, 3928, 123);\n                    }\n                    else {\n                        e = eq((b * 44) | 0) | 0;\n                        break;\n                    }\n                else\n                    e = 0;\n            while (0);\n            c[a >> 2] = e;\n            d = (e + ((d * 44) | 0)) | 0;\n            c[(a + 8) >> 2] = d;\n            c[(a + 4) >> 2] = d;\n            c[f >> 2] = e + ((b * 44) | 0);\n            return;\n        }\n        function Tc(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0;\n            i = c[a >> 2] | 0;\n            j = (a + 4) | 0;\n            d = c[j >> 2] | 0;\n            h = (b + 4) | 0;\n            if ((d | 0) == (i | 0)) {\n                f = h;\n                g = a;\n                e = c[h >> 2] | 0;\n                d = i;\n            }\n            else {\n                e = c[h >> 2] | 0;\n                do {\n                    d = (d + -44) | 0;\n                    Wc((e + -44) | 0, d);\n                    e = ((c[h >> 2] | 0) + -44) | 0;\n                    c[h >> 2] = e;\n                } while ((d | 0) != (i | 0));\n                f = h;\n                g = a;\n                d = c[a >> 2] | 0;\n            }\n            c[g >> 2] = e;\n            c[f >> 2] = d;\n            i = (b + 8) | 0;\n            h = c[j >> 2] | 0;\n            c[j >> 2] = c[i >> 2];\n            c[i >> 2] = h;\n            i = (a + 8) | 0;\n            j = (b + 12) | 0;\n            a = c[i >> 2] | 0;\n            c[i >> 2] = c[j >> 2];\n            c[j >> 2] = a;\n            c[b >> 2] = c[f >> 2];\n            return;\n        }\n        function Uc(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            d = c[(a + 4) >> 2] | 0;\n            e = (a + 8) | 0;\n            b = c[e >> 2] | 0;\n            if ((b | 0) != (d | 0))\n                do {\n                    f = (b + -44) | 0;\n                    c[e >> 2] = f;\n                    Ic(f);\n                    b = c[e >> 2] | 0;\n                } while ((b | 0) != (d | 0));\n            b = c[a >> 2] | 0;\n            if (b | 0)\n                Da(b, ((c[(a + 12) >> 2] | 0) - b) | 0);\n            return;\n        }\n        function Vc(a) {\n            a = a | 0;\n            return 97612893;\n        }\n        function Wc(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0;\n            e = c[d >> 2] | 0;\n            c[b >> 2] = e;\n            a[(b + 4) >> 0] = a[(d + 4) >> 0] | 0;\n            c[(b + 20) >> 2] = c[(d + 20) >> 2];\n            c[(b + 24) >> 2] = c[(d + 24) >> 2];\n            c[(b + 28) >> 2] = c[(d + 28) >> 2];\n            c[(b + 32) >> 2] = c[(d + 32) >> 2];\n            h = (b + 36) | 0;\n            c[h >> 2] = c[(d + 36) >> 2];\n            c[(b + 40) >> 2] = c[(d + 40) >> 2];\n            e = e << 2;\n            f = _a(e) | 0;\n            c[(b + 8) >> 2] = f;\n            g = c[b >> 2] | 0;\n            if (g | 0)\n                vr(f | 0, c[(d + 8) >> 2] | 0, (g << 2) | 0) | 0;\n            e = _a(e) | 0;\n            c[(b + 12) >> 2] = e;\n            f = c[b >> 2] | 0;\n            if (f | 0)\n                vr(e | 0, c[(d + 12) >> 2] | 0, (f << 2) | 0) | 0;\n            e = c[h >> 2] | 0;\n            if (e) {\n                f = _a(((e << 2) + 8) | 0) | 0;\n                c[(b + 16) >> 2] = f;\n                e = ((c[h >> 2] << 2) + 8) | 0;\n                if (e | 0)\n                    vr(f | 0, c[(d + 16) >> 2] | 0, e | 0) | 0;\n            }\n            else\n                c[(b + 16) >> 2] = 0;\n            return;\n        }\n        function Xc(b) {\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, r = 0;\n            r = (b + 24) | 0;\n            g = (b + 20) | 0;\n            d = ((c[g >> 2] | 0) + (c[r >> 2] | 0)) | 0;\n            c[g >> 2] = d;\n            if (d >>> 0 > 32768) {\n                c[g >> 2] = 0;\n                if (!(c[b >> 2] | 0))\n                    d = 0;\n                else {\n                    f = c[(b + 12) >> 2] | 0;\n                    e = 0;\n                    do {\n                        n = (f + (e << 2)) | 0;\n                        d = (((c[n >> 2] | 0) + 1) | 0) >>> 1;\n                        c[n >> 2] = d;\n                        d = ((c[g >> 2] | 0) + d) | 0;\n                        c[g >> 2] = d;\n                        e = (e + 1) | 0;\n                    } while (e >>> 0 < (c[b >> 2] | 0) >>> 0);\n                }\n            }\n            n = (2147483648 / (d >>> 0)) | 0;\n            do\n                if ((a[(b + 4) >> 0] | 0) == 0 ? ((o = (b + 36) | 0), (c[o >> 2] | 0) != 0) : 0) {\n                    if (c[b >> 2] | 0) {\n                        j = c[(b + 8) >> 2] | 0;\n                        k = c[(b + 12) >> 2] | 0;\n                        l = (b + 40) | 0;\n                        m = (b + 16) | 0;\n                        d = 0;\n                        h = 0;\n                        i = 0;\n                        do {\n                            e = (q(h, n) | 0) >>> 16;\n                            c[(j + (i << 2)) >> 2] = e;\n                            h = ((c[(k + (i << 2)) >> 2] | 0) + h) | 0;\n                            e = e >>> (c[l >> 2] | 0);\n                            if (d >>> 0 < e >>> 0) {\n                                f = (i + -1) | 0;\n                                g = c[m >> 2] | 0;\n                                do {\n                                    d = (d + 1) | 0;\n                                    c[(g + (d << 2)) >> 2] = f;\n                                } while ((d | 0) != (e | 0));\n                                d = e;\n                            }\n                            i = (i + 1) | 0;\n                        } while (i >>> 0 < (c[b >> 2] | 0) >>> 0);\n                        e = c[m >> 2] | 0;\n                        c[e >> 2] = 0;\n                        if (d >>> 0 > (c[o >> 2] | 0) >>> 0) {\n                            d = b;\n                            break;\n                        }\n                    }\n                    else {\n                        e = c[(b + 16) >> 2] | 0;\n                        c[e >> 2] = 0;\n                        d = 0;\n                    }\n                    do {\n                        d = (d + 1) | 0;\n                        c[(e + (d << 2)) >> 2] = (c[b >> 2] | 0) + -1;\n                    } while (d >>> 0 <= (c[o >> 2] | 0) >>> 0);\n                    d = b;\n                }\n                else\n                    p = 7;\n            while (0);\n            if ((p | 0) == 7)\n                if (!(c[b >> 2] | 0))\n                    d = b;\n                else {\n                    f = c[(b + 8) >> 2] | 0;\n                    g = c[(b + 12) >> 2] | 0;\n                    d = 0;\n                    e = 0;\n                    do {\n                        c[(f + (d << 2)) >> 2] = (q(e, n) | 0) >>> 16;\n                        e = ((c[(g + (d << 2)) >> 2] | 0) + e) | 0;\n                        d = (d + 1) | 0;\n                    } while (d >>> 0 < (c[b >> 2] | 0) >>> 0);\n                    d = b;\n                }\n            p = (((c[r >> 2] | 0) * 5) | 0) >>> 2;\n            o = ((c[d >> 2] << 3) + 48) | 0;\n            p = p >>> 0 > o >>> 0 ? o : p;\n            c[r >> 2] = p;\n            c[(b + 28) >> 2] = p;\n            return;\n        }\n        function Yc(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0;\n            d = Zc(b, d) | 0;\n            c[a >> 2] = d;\n            do\n                if (d) {\n                    if (d >>> 0 >= 32) {\n                        d = c[(a + 28) >> 2] | 0;\n                        break;\n                    }\n                    e = c[(a + 12) >> 2] | 0;\n                    if (d >>> 0 > e >>> 0) {\n                        e = (d - e) | 0;\n                        d = Zc(b, ((c[(a + 68) >> 2] | 0) + ((((d + -1) | 0) * 44) | 0)) | 0) | 0;\n                        e = (d << e) | (_c(b, e) | 0);\n                    }\n                    else\n                        e = Zc(b, ((c[(a + 68) >> 2] | 0) + ((((d + -1) | 0) * 44) | 0)) | 0) | 0;\n                    d = c[a >> 2] | 0;\n                    if ((e | 0) < ((1 << (d + -1)) | 0)) {\n                        d = (e + 1 + (-1 << d)) | 0;\n                        break;\n                    }\n                    else {\n                        d = (e + 1) | 0;\n                        break;\n                    }\n                }\n                else\n                    d = $c(b, (a + 48) | 0) | 0;\n            while (0);\n            return d | 0;\n        }\n        function Zc(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0;\n            n = (a + 8) | 0;\n            m = c[n >> 2] | 0;\n            f = c[(b + 16) >> 2] | 0;\n            if (f) {\n                e = (a + 4) | 0;\n                d = c[e >> 2] | 0;\n                l = m >>> 15;\n                c[n >> 2] = l;\n                j = ((d >>> 0) / (l >>> 0)) | 0;\n                i = j >>> (c[(b + 40) >> 2] | 0);\n                g = c[(f + (i << 2)) >> 2] | 0;\n                i = ((c[(f + ((i + 1) << 2)) >> 2] | 0) + 1) | 0;\n                h = (g + 1) | 0;\n                k = c[(b + 8) >> 2] | 0;\n                if (i >>> 0 > h >>> 0) {\n                    f = g;\n                    g = i;\n                    do {\n                        h = ((g + f) | 0) >>> 1;\n                        i = (c[(k + (h << 2)) >> 2] | 0) >>> 0 > j >>> 0;\n                        f = i ? f : h;\n                        g = i ? h : g;\n                        h = (f + 1) | 0;\n                    } while (g >>> 0 > h >>> 0);\n                    g = f;\n                }\n                f = q(c[(k + (g << 2)) >> 2] | 0, l) | 0;\n                if ((g | 0) == (c[(b + 32) >> 2] | 0))\n                    h = m;\n                else\n                    h = q(c[(k + (h << 2)) >> 2] | 0, l) | 0;\n            }\n            else {\n                k = m >>> 15;\n                c[n >> 2] = k;\n                i = c[b >> 2] | 0;\n                l = c[(b + 8) >> 2] | 0;\n                e = (a + 4) | 0;\n                d = c[e >> 2] | 0;\n                j = i >>> 1;\n                f = 0;\n                h = m;\n                g = 0;\n                do {\n                    o = q(c[(l + (j << 2)) >> 2] | 0, k) | 0;\n                    m = o >>> 0 > d >>> 0;\n                    h = m ? o : h;\n                    f = m ? f : o;\n                    g = m ? g : j;\n                    i = m ? j : i;\n                    j = ((g + i) | 0) >>> 1;\n                } while ((j | 0) != (g | 0));\n            }\n            c[e >> 2] = d - f;\n            o = (h - f) | 0;\n            c[n >> 2] = o;\n            if (o >>> 0 < 16777216)\n                ad(a);\n            n = ((c[(b + 12) >> 2] | 0) + (g << 2)) | 0;\n            c[n >> 2] = (c[n >> 2] | 0) + 1;\n            n = (b + 28) | 0;\n            o = ((c[n >> 2] | 0) + -1) | 0;\n            c[n >> 2] = o;\n            if (!o)\n                Xc(b);\n            return g | 0;\n        }\n        function _c(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0;\n            if (b >>> 0 > 19) {\n                d = (bd(a) | 0) & 65535;\n                return ((_c(a, (b + -16) | 0) | 0) << 16) | d | 0;\n            }\n            e = (a + 4) | 0;\n            f = c[e >> 2] | 0;\n            g = (a + 8) | 0;\n            d = (c[g >> 2] | 0) >>> b;\n            c[g >> 2] = d;\n            b = ((f >>> 0) / (d >>> 0)) | 0;\n            c[e >> 2] = f - (q(b, d) | 0);\n            if (d >>> 0 < 16777216)\n                ad(a);\n            return b | 0;\n        }\n        function $c(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0;\n            e = (a + 8) | 0;\n            f = c[e >> 2] | 0;\n            d = q(f >>> 13, c[(b + 8) >> 2] | 0) | 0;\n            g = (a + 4) | 0;\n            h = c[g >> 2] | 0;\n            i = h >>> 0 >= d >>> 0;\n            if (i) {\n                c[g >> 2] = h - d;\n                d = (f - d) | 0;\n                c[e >> 2] = d;\n            }\n            else {\n                c[e >> 2] = d;\n                h = (b + 12) | 0;\n                c[h >> 2] = (c[h >> 2] | 0) + 1;\n            }\n            if (d >>> 0 < 16777216)\n                ad(a);\n            h = (b + 4) | 0;\n            a = ((c[h >> 2] | 0) + -1) | 0;\n            c[h >> 2] = a;\n            if (!a)\n                cd(b);\n            return (i & 1) | 0;\n        }\n        function ad(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            b = (a + 4) | 0;\n            d = (a + 8) | 0;\n            e = c[b >> 2] | 0;\n            do {\n                e = (e << 8) | ((Jc(c[a >> 2] | 0) | 0) & 255);\n                c[b >> 2] = e;\n                f = c[d >> 2] << 8;\n                c[d >> 2] = f;\n            } while (f >>> 0 < 16777216);\n            return;\n        }\n        function bd(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            d = (a + 4) | 0;\n            f = c[d >> 2] | 0;\n            b = (a + 8) | 0;\n            e = (c[b >> 2] | 0) >>> 16;\n            c[b >> 2] = e;\n            b = ((f >>> 0) / (e >>> 0)) | 0;\n            c[d >> 2] = f - (q(b, e) | 0);\n            ad(a);\n            return (b & 65535) | 0;\n        }\n        function cd(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0;\n            f = c[a >> 2] | 0;\n            d = (a + 16) | 0;\n            b = ((c[d >> 2] | 0) + f) | 0;\n            c[d >> 2] = b;\n            if (b >>> 0 > 8192) {\n                e = ((b + 1) | 0) >>> 1;\n                c[d >> 2] = e;\n                g = (a + 12) | 0;\n                b = (((c[g >> 2] | 0) + 1) | 0) >>> 1;\n                c[g >> 2] = b;\n                if ((b | 0) == (e | 0)) {\n                    b = (e + 1) | 0;\n                    c[d >> 2] = b;\n                    d = b;\n                    b = e;\n                }\n                else\n                    d = e;\n            }\n            else {\n                d = b;\n                b = c[(a + 12) >> 2] | 0;\n            }\n            c[(a + 8) >> 2] = (q(b, (2147483648 / (d >>> 0)) | 0) | 0) >>> 18;\n            g = (f * 5) | 0;\n            g = g >>> 0 > 259 ? 64 : g >>> 2;\n            c[a >> 2] = g;\n            c[(a + 4) >> 2] = g;\n            return;\n        }\n        function dd(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0;\n            m = V;\n            V = (V + 32) | 0;\n            h = (m + 16) | 0;\n            i = (m + 8) | 0;\n            j = m;\n            k = (a + 336) | 0;\n            f = k;\n            g = (a + 259) | 0;\n            if (!((c[(f + 4) >> 2] | 0) == 0\n                ? (c[f >> 2] | 0) ==\n                    (d[g >> 0] |\n                        (d[(g + 1) >> 0] << 8) |\n                        (d[(g + 2) >> 0] << 16) |\n                        (d[(g + 3) >> 0] << 24) |\n                        0)\n                : 0)) {\n                f = (a + 320) | 0;\n                e = c[f >> 2] | 0;\n                g = e;\n                if (!((e | 0) != 0 ? (c[(a + 312) >> 2] | 0) != 0 : 0)) {\n                    e = g;\n                    l = 5;\n                }\n            }\n            else {\n                f = (a + 320) | 0;\n                e = c[(a + 320) >> 2] | 0;\n                l = 5;\n            }\n            if ((l | 0) == 5) {\n                l = (a + 320) | 0;\n                c[h >> 2] = e;\n                c[l >> 2] = 0;\n                e = (a + 324) | 0;\n                c[(h + 4) >> 2] = c[e >> 2];\n                c[e >> 2] = 0;\n                Na(h);\n                g = (a + 312) | 0;\n                c[h >> 2] = c[g >> 2];\n                c[g >> 2] = 0;\n                n = (a + 316) | 0;\n                c[(h + 4) >> 2] = c[n >> 2];\n                c[n >> 2] = 0;\n                Oa(h);\n                o = eq(12) | 0;\n                lc(o, (a + 4) | 0);\n                c[j >> 2] = 0;\n                c[h >> 2] = c[j >> 2];\n                fd(i, o, h);\n                o = c[i >> 2] | 0;\n                c[i >> 2] = c[g >> 2];\n                c[g >> 2] = o;\n                o = (i + 4) | 0;\n                j = c[o >> 2] | 0;\n                c[o >> 2] = c[n >> 2];\n                c[n >> 2] = j;\n                Oa(i);\n                ed(i, c[g >> 2] | 0, (a + 300) | 0);\n                g = c[i >> 2] | 0;\n                n = (i + 4) | 0;\n                j = c[n >> 2] | 0;\n                c[i >> 2] = 0;\n                c[n >> 2] = 0;\n                c[h >> 2] = c[l >> 2];\n                c[l >> 2] = g;\n                c[(h + 4) >> 2] = c[e >> 2];\n                c[e >> 2] = j;\n                Na(h);\n                Na(i);\n                e = (a + 328) | 0;\n                j = e;\n                j = lr(c[j >> 2] | 0, c[(j + 4) >> 2] | 0, 1, 0) | 0;\n                l = u() | 0;\n                c[e >> 2] = j;\n                c[(e + 4) >> 2] = l;\n                e = k;\n                c[e >> 2] = 0;\n                c[(e + 4) >> 2] = 0;\n                e = c[f >> 2] | 0;\n            }\n            $[c[c[e >> 2] >> 2] & 63](e, b) | 0;\n            l = k;\n            l = lr(c[l >> 2] | 0, c[(l + 4) >> 2] | 0, 1, 0) | 0;\n            n = u() | 0;\n            o = k;\n            c[o >> 2] = l;\n            c[(o + 4) >> 2] = n;\n            V = m;\n            return;\n        }\n        function ed(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0;\n            h = V;\n            V = (V + 64) | 0;\n            e = (h + 56) | 0;\n            f = h;\n            g = ld(d) | 0;\n            if ((g | 0) == -1) {\n                h = v(8) | 0;\n                md(h);\n                x(h | 0, 2784, 8);\n            }\n            d = nd(d) | 0;\n            a: do\n                if (!d)\n                    switch (g | 0) {\n                        case 0: {\n                            g = eq(4788) | 0;\n                            xd(g);\n                            wd(a, b, g);\n                            break a;\n                        }\n                        case 1: {\n                            g = eq(5116) | 0;\n                            zd(g);\n                            yd(a, b, g);\n                            break a;\n                        }\n                        case 2: {\n                            g = eq(5104) | 0;\n                            Bd(g);\n                            Ad(a, b, g);\n                            break a;\n                        }\n                        case 3: {\n                            g = eq(5432) | 0;\n                            Dd(g);\n                            Cd(a, b, g);\n                            break a;\n                        }\n                        default: {\n                            c[a >> 2] = 0;\n                            c[(a + 4) >> 2] = 0;\n                            break a;\n                        }\n                    }\n                else {\n                    od(e, b);\n                    pd(c[e >> 2] | 0);\n                    if ((g | 2 | 0) == 3)\n                        qd(c[e >> 2] | 0);\n                    if ((g | 1 | 0) == 3)\n                        rd(c[e >> 2] | 0);\n                    g = c[e >> 2] | 0;\n                    td(f, d);\n                    sd(g, f);\n                    ud(f);\n                    c[a >> 2] = c[e >> 2];\n                    g = (e + 4) | 0;\n                    c[(a + 4) >> 2] = c[g >> 2];\n                    c[e >> 2] = 0;\n                    c[g >> 2] = 0;\n                    vd(e);\n                }\n            while (0);\n            V = h;\n            return;\n        }\n        function fd(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 4576;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            gd(a, e);\n            V = d;\n            return;\n        }\n        function gd(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return;\n        }\n        function hd(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function id(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0) {\n                rc(a);\n                jp(a);\n            }\n            return;\n        }\n        function jd(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 7983 ? (a + 12) | 0 : 0) | 0;\n        }\n        function kd(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function ld(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = ((c[(a + 4) >> 2] | 0) - (c[a >> 2] | 0)) | 0;\n            a: do\n                if (((b | 0) != 0\n                    ? ((d = ((((b | 0) / 12) | 0) + ((((nd(a) | 0) != 0) << 31) >> 31)) | 0),\n                        (d | 0) != 0)\n                    : 0)\n                    ? ((b = c[a >> 2] | 0), !(Ed(b, Fd() | 0) | 0))\n                    : 0) {\n                    switch (d | 0) {\n                        case 1: {\n                            a = 0;\n                            break a;\n                        }\n                        case 2: {\n                            if (Gd(((c[a >> 2] | 0) + 12) | 0, Hd() | 0) | 0) {\n                                a = 1;\n                                break a;\n                            }\n                            if (Gd(((c[a >> 2] | 0) + 12) | 0, Id() | 0) | 0) {\n                                a = 2;\n                                break a;\n                            }\n                            break;\n                        }\n                        case 3: {\n                            if (Gd(((c[a >> 2] | 0) + 12) | 0, Hd() | 0) | 0\n                                ? ((d = ((c[a >> 2] | 0) + 24) | 0), Gd(d, Id() | 0) | 0)\n                                : 0) {\n                                a = 3;\n                                break a;\n                            }\n                            break;\n                        }\n                        default: {\n                        }\n                    }\n                    a = -1;\n                }\n                else\n                    a = -1;\n            while (0);\n            return a | 0;\n        }\n        function md(a) {\n            a = a | 0;\n            xq(a, 8131);\n            c[a >> 2] = 4604;\n            return;\n        }\n        function nd(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = c[(a + 4) >> 2] | 0;\n            if (((b | 0) != (c[a >> 2] | 0) ? ((d = b), (c[(d + -12) >> 2] | 0) == 0) : 0)\n                ? (c[(d + -4) >> 2] | 0) == 2\n                : 0)\n                a = c[(d + -8) >> 2] | 0;\n            else\n                a = 0;\n            return a | 0;\n        }\n        function od(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = (d + 4) | 0;\n            g = d;\n            f = eq(24) | 0;\n            Kd(f, b);\n            c[g >> 2] = 0;\n            c[e >> 2] = c[g >> 2];\n            Ld(a, f, e);\n            V = d;\n            return;\n        }\n        function pd(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            j = V;\n            V = (V + 32) | 0;\n            e = (j + 12) | 0;\n            f = j;\n            b = (j + 8) | 0;\n            h = eq(4792) | 0;\n            Zd(h, c[(a + 4) >> 2] | 0);\n            g = (a + 8) | 0;\n            c[b >> 2] = 0;\n            c[e >> 2] = c[b >> 2];\n            _d(f, h, e);\n            h = (a + 12) | 0;\n            b = c[h >> 2] | 0;\n            i = (a + 16) | 0;\n            do\n                if (b >>> 0 >= (c[i >> 2] | 0) >>> 0) {\n                    b = (((b - (c[g >> 2] | 0)) >> 3) + 1) | 0;\n                    d = ee(g) | 0;\n                    if (d >>> 0 < b >>> 0)\n                        cr(g);\n                    else {\n                        k = c[g >> 2] | 0;\n                        l = ((c[i >> 2] | 0) - k) | 0;\n                        i = l >> 2;\n                        be(e, (l >> 3) >>> 0 < (d >>> 1) >>> 0 ? (i >>> 0 < b >>> 0 ? b : i) : d, ((c[h >> 2] | 0) - k) >> 3, (a + 16) | 0);\n                        i = (e + 8) | 0;\n                        h = c[i >> 2] | 0;\n                        c[h >> 2] = c[f >> 2];\n                        a = (f + 4) | 0;\n                        c[(h + 4) >> 2] = c[a >> 2];\n                        c[f >> 2] = 0;\n                        c[a >> 2] = 0;\n                        c[i >> 2] = h + 8;\n                        ce(g, e);\n                        de(e);\n                        break;\n                    }\n                }\n                else {\n                    $d(e, g, 1);\n                    l = (e + 4) | 0;\n                    k = c[l >> 2] | 0;\n                    c[k >> 2] = c[f >> 2];\n                    i = (f + 4) | 0;\n                    c[(k + 4) >> 2] = c[i >> 2];\n                    c[f >> 2] = 0;\n                    c[i >> 2] = 0;\n                    c[l >> 2] = k + 8;\n                    ae(e);\n                }\n            while (0);\n            Sd(f);\n            V = j;\n            return;\n        }\n        function qd(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            j = V;\n            V = (V + 32) | 0;\n            e = (j + 12) | 0;\n            f = j;\n            b = (j + 8) | 0;\n            h = eq(336) | 0;\n            af(h, c[(a + 4) >> 2] | 0);\n            g = (a + 8) | 0;\n            c[b >> 2] = 0;\n            c[e >> 2] = c[b >> 2];\n            bf(f, h, e);\n            h = (a + 12) | 0;\n            b = c[h >> 2] | 0;\n            i = (a + 16) | 0;\n            do\n                if (b >>> 0 >= (c[i >> 2] | 0) >>> 0) {\n                    b = (((b - (c[g >> 2] | 0)) >> 3) + 1) | 0;\n                    d = ee(g) | 0;\n                    if (d >>> 0 < b >>> 0)\n                        cr(g);\n                    else {\n                        k = c[g >> 2] | 0;\n                        l = ((c[i >> 2] | 0) - k) | 0;\n                        i = l >> 2;\n                        be(e, (l >> 3) >>> 0 < (d >>> 1) >>> 0 ? (i >>> 0 < b >>> 0 ? b : i) : d, ((c[h >> 2] | 0) - k) >> 3, (a + 16) | 0);\n                        i = (e + 8) | 0;\n                        h = c[i >> 2] | 0;\n                        c[h >> 2] = c[f >> 2];\n                        a = (f + 4) | 0;\n                        c[(h + 4) >> 2] = c[a >> 2];\n                        c[f >> 2] = 0;\n                        c[a >> 2] = 0;\n                        c[i >> 2] = h + 8;\n                        ce(g, e);\n                        de(e);\n                        break;\n                    }\n                }\n                else {\n                    $d(e, g, 1);\n                    l = (e + 4) | 0;\n                    k = c[l >> 2] | 0;\n                    c[k >> 2] = c[f >> 2];\n                    i = (f + 4) | 0;\n                    c[(k + 4) >> 2] = c[i >> 2];\n                    c[f >> 2] = 0;\n                    c[i >> 2] = 0;\n                    c[l >> 2] = k + 8;\n                    ae(e);\n                }\n            while (0);\n            Sd(f);\n            V = j;\n            return;\n        }\n        function rd(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            j = V;\n            V = (V + 32) | 0;\n            e = (j + 12) | 0;\n            f = j;\n            b = (j + 8) | 0;\n            h = eq(324) | 0;\n            Af(h, c[(a + 4) >> 2] | 0);\n            g = (a + 8) | 0;\n            c[b >> 2] = 0;\n            c[e >> 2] = c[b >> 2];\n            Bf(f, h, e);\n            h = (a + 12) | 0;\n            b = c[h >> 2] | 0;\n            i = (a + 16) | 0;\n            do\n                if (b >>> 0 >= (c[i >> 2] | 0) >>> 0) {\n                    b = (((b - (c[g >> 2] | 0)) >> 3) + 1) | 0;\n                    d = ee(g) | 0;\n                    if (d >>> 0 < b >>> 0)\n                        cr(g);\n                    else {\n                        k = c[g >> 2] | 0;\n                        l = ((c[i >> 2] | 0) - k) | 0;\n                        i = l >> 2;\n                        be(e, (l >> 3) >>> 0 < (d >>> 1) >>> 0 ? (i >>> 0 < b >>> 0 ? b : i) : d, ((c[h >> 2] | 0) - k) >> 3, (a + 16) | 0);\n                        i = (e + 8) | 0;\n                        h = c[i >> 2] | 0;\n                        c[h >> 2] = c[f >> 2];\n                        a = (f + 4) | 0;\n                        c[(h + 4) >> 2] = c[a >> 2];\n                        c[f >> 2] = 0;\n                        c[a >> 2] = 0;\n                        c[i >> 2] = h + 8;\n                        ce(g, e);\n                        de(e);\n                        break;\n                    }\n                }\n                else {\n                    $d(e, g, 1);\n                    l = (e + 4) | 0;\n                    k = c[l >> 2] | 0;\n                    c[k >> 2] = c[f >> 2];\n                    i = (f + 4) | 0;\n                    c[(k + 4) >> 2] = c[i >> 2];\n                    c[f >> 2] = 0;\n                    c[i >> 2] = 0;\n                    c[l >> 2] = k + 8;\n                    ae(e);\n                }\n            while (0);\n            Sd(f);\n            V = j;\n            return;\n        }\n        function sd(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            j = V;\n            V = (V + 32) | 0;\n            h = (j + 12) | 0;\n            i = j;\n            e = (j + 8) | 0;\n            g = eq(64) | 0;\n            Qf(g, c[(a + 4) >> 2] | 0, b);\n            f = (a + 8) | 0;\n            c[e >> 2] = 0;\n            c[h >> 2] = c[e >> 2];\n            Rf(i, g, h);\n            g = (a + 12) | 0;\n            b = c[g >> 2] | 0;\n            e = (a + 16) | 0;\n            do\n                if (b >>> 0 >= (c[e >> 2] | 0) >>> 0) {\n                    b = (((b - (c[f >> 2] | 0)) >> 3) + 1) | 0;\n                    d = ee(f) | 0;\n                    if (d >>> 0 < b >>> 0)\n                        cr(f);\n                    else {\n                        k = c[f >> 2] | 0;\n                        l = ((c[e >> 2] | 0) - k) | 0;\n                        e = l >> 2;\n                        be(h, (l >> 3) >>> 0 < (d >>> 1) >>> 0 ? (e >>> 0 < b >>> 0 ? b : e) : d, ((c[g >> 2] | 0) - k) >> 3, (a + 16) | 0);\n                        a = (h + 8) | 0;\n                        g = c[a >> 2] | 0;\n                        c[g >> 2] = c[i >> 2];\n                        e = (i + 4) | 0;\n                        c[(g + 4) >> 2] = c[e >> 2];\n                        c[i >> 2] = 0;\n                        c[e >> 2] = 0;\n                        c[a >> 2] = g + 8;\n                        ce(f, h);\n                        de(h);\n                        break;\n                    }\n                }\n                else {\n                    $d(h, f, 1);\n                    l = (h + 4) | 0;\n                    k = c[l >> 2] | 0;\n                    c[k >> 2] = c[i >> 2];\n                    a = (i + 4) | 0;\n                    c[(k + 4) >> 2] = c[a >> 2];\n                    c[i >> 2] = 0;\n                    c[a >> 2] = 0;\n                    c[l >> 2] = k + 8;\n                    ae(h);\n                }\n            while (0);\n            Sd(i);\n            V = j;\n            return;\n        }\n        function td(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            e = V;\n            V = (V + 48) | 0;\n            f = e;\n            c[b >> 2] = d;\n            a[(b + 4) >> 0] = 0;\n            Jg((b + 8) | 0, d);\n            Jg((b + 20) | 0, d);\n            Oc(f, 256, 0, 0);\n            Kg((b + 32) | 0, d, f);\n            Ic(f);\n            V = e;\n            return;\n        }\n        function ud(a) {\n            a = a | 0;\n            Ng((a + 32) | 0);\n            _f((a + 20) | 0);\n            _f((a + 8) | 0);\n            return;\n        }\n        function vd(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            a = c[(a + 4) >> 2] | 0;\n            if (a | 0 ? ((d = (a + 4) | 0), (b = c[d >> 2] | 0), (c[d >> 2] = b + -1), (b | 0) == 0) : 0) {\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n                qq(a);\n            }\n            return;\n        }\n        function wd(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0;\n            e = V;\n            V = (V + 16) | 0;\n            f = (e + 4) | 0;\n            h = e;\n            g = eq(12) | 0;\n            Og(g, b, d);\n            c[h >> 2] = 0;\n            c[f >> 2] = c[h >> 2];\n            Pg(a, g, f);\n            V = e;\n            return;\n        }\n        function xd(a) {\n            a = a | 0;\n            ge(a);\n            $g((a + 4784) | 0);\n            return;\n        }\n        function yd(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0;\n            e = V;\n            V = (V + 16) | 0;\n            f = (e + 4) | 0;\n            h = e;\n            g = eq(12) | 0;\n            ah(g, b, d);\n            c[h >> 2] = 0;\n            c[f >> 2] = c[h >> 2];\n            bh(a, g, f);\n            V = e;\n            return;\n        }\n        function zd(a) {\n            a = a | 0;\n            ge(a);\n            nh((a + 4784) | 0);\n            return;\n        }\n        function Ad(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0;\n            e = V;\n            V = (V + 16) | 0;\n            f = (e + 4) | 0;\n            h = e;\n            g = eq(12) | 0;\n            oh(g, b, d);\n            c[h >> 2] = 0;\n            c[f >> 2] = c[h >> 2];\n            ph(a, g, f);\n            V = e;\n            return;\n        }\n        function Bd(a) {\n            a = a | 0;\n            ge(a);\n            Bh((a + 4784) | 0);\n            return;\n        }\n        function Cd(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0;\n            e = V;\n            V = (V + 16) | 0;\n            f = (e + 4) | 0;\n            h = e;\n            g = eq(12) | 0;\n            Ch(g, b, d);\n            c[h >> 2] = 0;\n            c[f >> 2] = c[h >> 2];\n            Dh(a, g, f);\n            V = e;\n            return;\n        }\n        function Dd(a) {\n            a = a | 0;\n            ge(a);\n            Ph((a + 4784) | 0);\n            return;\n        }\n        function Ed(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((Gd(a, b) | 0) ^ 1) | 0;\n        }\n        function Fd() {\n            if ((a[21456] | 0) == 0 ? Tp(21456) | 0 : 0) {\n                _b(21536, 6, 20, 2);\n                $p(21456);\n            }\n            return 21536;\n        }\n        function Gd(a, b) {\n            a = a | 0;\n            b = b | 0;\n            if ((c[a >> 2] | 0) == (c[b >> 2] | 0) ? (c[(a + 8) >> 2] | 0) == (c[(b + 8) >> 2] | 0) : 0)\n                a = (c[(a + 4) >> 2] | 0) == (c[(b + 4) >> 2] | 0);\n            else\n                a = 0;\n            return a | 0;\n        }\n        function Hd() {\n            if ((a[21464] | 0) == 0 ? Tp(21464) | 0 : 0) {\n                _b(21548, 7, 8, 2);\n                $p(21464);\n            }\n            return 21548;\n        }\n        function Id() {\n            if ((a[21472] | 0) == 0 ? Tp(21472) | 0 : 0) {\n                _b(21560, 8, 6, 2);\n                $p(21472);\n            }\n            return 21560;\n        }\n        function Jd(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function Kd(b, d) {\n            b = b | 0;\n            d = d | 0;\n            Md(b);\n            c[b >> 2] = 4624;\n            c[(b + 4) >> 2] = d;\n            c[(b + 8) >> 2] = 0;\n            c[(b + 12) >> 2] = 0;\n            c[(b + 16) >> 2] = 0;\n            a[(b + 20) >> 0] = 1;\n            return;\n        }\n        function Ld(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 4664;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Ud(a, e);\n            V = d;\n            return;\n        }\n        function Md(a) {\n            a = a | 0;\n            c[a >> 2] = 4644;\n            return;\n        }\n        function Nd(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            k = V;\n            V = (V + 16) | 0;\n            h = k;\n            e = c[(b + 8) >> 2] | 0;\n            i = c[(b + 12) >> 2] | 0;\n            if ((e | 0) != (i | 0)) {\n                j = (h + 4) | 0;\n                do {\n                    f = c[e >> 2] | 0;\n                    c[h >> 2] = f;\n                    g = c[(e + 4) >> 2] | 0;\n                    c[j >> 2] = g;\n                    if (g | 0) {\n                        g = (g + 4) | 0;\n                        c[g >> 2] = (c[g >> 2] | 0) + 1;\n                    }\n                    d = $[c[((c[f >> 2] | 0) + 12) >> 2] & 63](f, d) | 0;\n                    Sd(h);\n                    e = (e + 8) | 0;\n                } while ((e | 0) != (i | 0));\n            }\n            e = (b + 20) | 0;\n            if (a[e >> 0] | 0) {\n                a[e >> 0] = 0;\n                nc(c[(b + 4) >> 2] | 0);\n            }\n            V = k;\n            return d | 0;\n        }\n        function Od(a) {\n            a = a | 0;\n            c[a >> 2] = 4624;\n            Td((a + 8) | 0);\n            Qd(a);\n            return;\n        }\n        function Pd(a) {\n            a = a | 0;\n            Od(a);\n            jp(a);\n            return;\n        }\n        function Qd(a) {\n            a = a | 0;\n            return;\n        }\n        function Rd(a) {\n            a = a | 0;\n            U();\n        }\n        function Sd(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            a = c[(a + 4) >> 2] | 0;\n            if (a | 0 ? ((d = (a + 4) | 0), (b = c[d >> 2] | 0), (c[d >> 2] = b + -1), (b | 0) == 0) : 0) {\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n                qq(a);\n            }\n            return;\n        }\n        function Td(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            d = c[a >> 2] | 0;\n            if (d | 0) {\n                e = (a + 4) | 0;\n                b = c[e >> 2] | 0;\n                if ((b | 0) == (d | 0))\n                    b = d;\n                else {\n                    do {\n                        b = (b + -8) | 0;\n                        Sd(b);\n                    } while ((b | 0) != (d | 0));\n                    b = c[a >> 2] | 0;\n                }\n                c[e >> 2] = d;\n                Da(b, ((c[(a + 8) >> 2] | 0) - b) | 0);\n            }\n            return;\n        }\n        function Ud(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return;\n        }\n        function Vd(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Wd(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n            return;\n        }\n        function Xd(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 8546 ? (a + 12) | 0 : 0) | 0;\n        }\n        function Yd(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Zd(a, b) {\n            a = a | 0;\n            b = b | 0;\n            fe(a);\n            c[a >> 2] = 4692;\n            c[(a + 4) >> 2] = b;\n            ge((a + 8) | 0);\n            return;\n        }\n        function _d(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 4740;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xe(a, e);\n            V = d;\n            return;\n        }\n        function $d(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = b;\n            b = c[(b + 4) >> 2] | 0;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = b + (d << 3);\n            return;\n        }\n        function ae(a) {\n            a = a | 0;\n            c[((c[a >> 2] | 0) + 4) >> 2] = c[(a + 4) >> 2];\n            return;\n        }\n        function be(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0;\n            f = (a + 12) | 0;\n            c[f >> 2] = 0;\n            c[(a + 16) >> 2] = e;\n            do\n                if (b)\n                    if (b >>> 0 > 536870911) {\n                        f = v(8) | 0;\n                        vq(f, 6723);\n                        c[f >> 2] = 5956;\n                        x(f | 0, 3928, 123);\n                    }\n                    else {\n                        e = eq(b << 3) | 0;\n                        break;\n                    }\n                else\n                    e = 0;\n            while (0);\n            c[a >> 2] = e;\n            d = (e + (d << 3)) | 0;\n            c[(a + 8) >> 2] = d;\n            c[(a + 4) >> 2] = d;\n            c[f >> 2] = e + (b << 3);\n            return;\n        }\n        function ce(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0;\n            i = c[a >> 2] | 0;\n            j = (a + 4) | 0;\n            d = c[j >> 2] | 0;\n            h = (b + 4) | 0;\n            if ((d | 0) == (i | 0)) {\n                f = h;\n                g = a;\n                e = c[h >> 2] | 0;\n                d = i;\n            }\n            else {\n                e = c[h >> 2] | 0;\n                do {\n                    g = d;\n                    d = (d + -8) | 0;\n                    c[(e + -8) >> 2] = c[d >> 2];\n                    g = (g + -4) | 0;\n                    c[(e + -4) >> 2] = c[g >> 2];\n                    c[d >> 2] = 0;\n                    c[g >> 2] = 0;\n                    e = ((c[h >> 2] | 0) + -8) | 0;\n                    c[h >> 2] = e;\n                } while ((d | 0) != (i | 0));\n                f = h;\n                g = a;\n                d = c[a >> 2] | 0;\n            }\n            c[g >> 2] = e;\n            c[f >> 2] = d;\n            i = (b + 8) | 0;\n            h = c[j >> 2] | 0;\n            c[j >> 2] = c[i >> 2];\n            c[i >> 2] = h;\n            i = (a + 8) | 0;\n            j = (b + 12) | 0;\n            a = c[i >> 2] | 0;\n            c[i >> 2] = c[j >> 2];\n            c[j >> 2] = a;\n            c[b >> 2] = c[f >> 2];\n            return;\n        }\n        function de(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            d = c[(a + 4) >> 2] | 0;\n            e = (a + 8) | 0;\n            b = c[e >> 2] | 0;\n            if ((b | 0) != (d | 0))\n                do {\n                    f = (b + -8) | 0;\n                    c[e >> 2] = f;\n                    Sd(f);\n                    b = c[e >> 2] | 0;\n                } while ((b | 0) != (d | 0));\n            b = c[a >> 2] | 0;\n            if (b | 0)\n                Da(b, ((c[(a + 12) >> 2] | 0) - b) | 0);\n            return;\n        }\n        function ee(a) {\n            a = a | 0;\n            return 536870911;\n        }\n        function fe(a) {\n            a = a | 0;\n            c[a >> 2] = 4716;\n            return;\n        }\n        function ge(b) {\n            b = b | 0;\n            oe(b);\n            pe((b + 3980) | 0);\n            qe((b + 4380) | 0);\n            a[(b + 4780) >> 0] = 0;\n            a[(b + 4781) >> 0] = 0;\n            return;\n        }\n        function he(a) {\n            a = a | 0;\n            c[a >> 2] = 4692;\n            ze((a + 8) | 0);\n            le(a);\n            return;\n        }\n        function ie(a) {\n            a = a | 0;\n            he(a);\n            jp(a);\n            return;\n        }\n        function je(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return b | 0;\n        }\n        function ke(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return Be((a + 8) | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function le(a) {\n            a = a | 0;\n            return;\n        }\n        function me(a) {\n            a = a | 0;\n            le(a);\n            jp(a);\n            return;\n        }\n        function ne(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return b | 0;\n        }\n        function oe(d) {\n            d = d | 0;\n            var e = 0, f = 0;\n            te(d);\n            ue((d + 52) | 0);\n            ue((d + 436) | 0);\n            Oc((d + 852) | 0, 64, 0, 0);\n            a[(d + 3976) >> 0] = 0;\n            e = (d + 20) | 0;\n            f = (e + 32) | 0;\n            do {\n                b[e >> 1] = 0;\n                e = (e + 2) | 0;\n            } while ((e | 0) < (f | 0));\n            e = eq(44) | 0;\n            Oc(e, 256, 0, 0);\n            c[(d + 896) >> 2] = e;\n            e = eq(44) | 0;\n            Oc(e, 256, 0, 0);\n            c[(d + 900) >> 2] = e;\n            e = (d + 820) | 0;\n            c[e >> 2] = 0;\n            c[(e + 4) >> 2] = 0;\n            c[(e + 8) >> 2] = 0;\n            c[(e + 12) >> 2] = 0;\n            c[(e + 16) >> 2] = 0;\n            c[(e + 20) >> 2] = 0;\n            c[(e + 24) >> 2] = 0;\n            c[(e + 28) >> 2] = 0;\n            e = 0;\n            do {\n                f = eq(44) | 0;\n                Oc(f, 256, 0, 0);\n                c[(d + 904 + (e << 2)) >> 2] = f;\n                f = eq(44) | 0;\n                Oc(f, 256, 0, 0);\n                c[(d + 1928 + (e << 2)) >> 2] = f;\n                f = eq(44) | 0;\n                Oc(f, 256, 0, 0);\n                c[(d + 2952 + (e << 2)) >> 2] = f;\n                e = (e + 1) | 0;\n            } while (e >>> 0 < 256);\n            return;\n        }\n        function pe(a) {\n            a = a | 0;\n            xe(a, 16, 4, 8, 0);\n            xe((a + 80) | 0, 16, 1, 8, 0);\n            xe((a + 160) | 0, 32, 2, 8, 0);\n            xe((a + 240) | 0, 32, 22, 8, 0);\n            xe((a + 320) | 0, 32, 20, 8, 0);\n            return;\n        }\n        function qe(a) {\n            a = a | 0;\n            mc(a, 16, 4, 8, 0);\n            mc((a + 80) | 0, 16, 1, 8, 0);\n            mc((a + 160) | 0, 32, 2, 8, 0);\n            mc((a + 240) | 0, 32, 22, 8, 0);\n            mc((a + 320) | 0, 32, 20, 8, 0);\n            return;\n        }\n        function re(a) {\n            a = a | 0;\n            ye((a + 320) | 0);\n            ye((a + 240) | 0);\n            ye((a + 160) | 0);\n            ye((a + 80) | 0);\n            ye(a);\n            return;\n        }\n        function se(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = c[(a + 896) >> 2] | 0;\n            if (b | 0) {\n                Ic(b);\n                jp(b);\n            }\n            b = c[(a + 900) >> 2] | 0;\n            if (b | 0) {\n                Ic(b);\n                jp(b);\n            }\n            d = 0;\n            do {\n                b = c[(a + 904 + (d << 2)) >> 2] | 0;\n                if (b | 0) {\n                    Ic(b);\n                    jp(b);\n                }\n                b = c[(a + 1928 + (d << 2)) >> 2] | 0;\n                if (b | 0) {\n                    Ic(b);\n                    jp(b);\n                }\n                b = c[(a + 2952 + (d << 2)) >> 2] | 0;\n                if (b | 0) {\n                    Ic(b);\n                    jp(b);\n                }\n                d = (d + 1) | 0;\n            } while ((d | 0) != 256);\n            Ic((a + 852) | 0);\n            return;\n        }\n        function te(b) {\n            b = b | 0;\n            var c = 0;\n            a[b >> 0] = 0;\n            a[(b + 1) >> 0] = 0;\n            a[(b + 2) >> 0] = 0;\n            a[(b + 3) >> 0] = 0;\n            c = (b + 4) | 0;\n            a[c >> 0] = 0;\n            a[(c + 1) >> 0] = 0;\n            a[(c + 2) >> 0] = 0;\n            a[(c + 3) >> 0] = 0;\n            b = (b + 12) | 0;\n            c = b;\n            a[c >> 0] = 0;\n            a[(c + 1) >> 0] = 0;\n            a[(c + 2) >> 0] = 0;\n            a[(c + 3) >> 0] = 0;\n            b = (b + 4) | 0;\n            a[b >> 0] = 0;\n            a[(b + 1) >> 0] = 0;\n            a[(b + 2) >> 0] = 0;\n            a[(b + 3) >> 0] = 0;\n            return;\n        }\n        function ue(a) {\n            a = a | 0;\n            var b = 0;\n            b = (a + 384) | 0;\n            do {\n                ve(a);\n                a = (a + 24) | 0;\n            } while ((a | 0) != (b | 0));\n            return;\n        }\n        function ve(a) {\n            a = a | 0;\n            we(a);\n            return;\n        }\n        function we(b) {\n            b = b | 0;\n            c[b >> 2] = 0;\n            c[(b + 4) >> 2] = 0;\n            c[(b + 8) >> 2] = 0;\n            c[(b + 12) >> 2] = 0;\n            c[(b + 16) >> 2] = 0;\n            a[(b + 20) >> 0] = 1;\n            return;\n        }\n        function xe(a, b, d, e, f) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = d;\n            c[(a + 12) >> 2] = e;\n            c[(a + 16) >> 2] = f;\n            c[(a + 36) >> 2] = 0;\n            c[(a + 40) >> 2] = 0;\n            c[(a + 44) >> 2] = 0;\n            Gc((a + 48) | 0);\n            c[(a + 68) >> 2] = 0;\n            c[(a + 72) >> 2] = 0;\n            c[(a + 76) >> 2] = 0;\n            do\n                if (!f) {\n                    d = (a + 20) | 0;\n                    if (((b + -1) | 0) >>> 0 < 31) {\n                        c[d >> 2] = b;\n                        f = 1 << b;\n                        c[(a + 24) >> 2] = f;\n                        d = f >>> 1;\n                        c[(a + 28) >> 2] = 0 - d;\n                        d = (f + -1 - d) | 0;\n                        break;\n                    }\n                    else {\n                        c[d >> 2] = 32;\n                        c[(a + 24) >> 2] = 0;\n                        c[(a + 28) >> 2] = -2147483648;\n                        d = 2147483647;\n                        break;\n                    }\n                }\n                else {\n                    e = (a + 20) | 0;\n                    c[e >> 2] = 0;\n                    c[(a + 24) >> 2] = f;\n                    d = f;\n                    g = 0;\n                    while (1) {\n                        d = d >>> 1;\n                        b = (g + 1) | 0;\n                        if (!d)\n                            break;\n                        else\n                            g = b;\n                    }\n                    c[e >> 2] = ((1 << g) | 0) == (f | 0) ? g : b;\n                    d = f >>> 1;\n                    c[(a + 28) >> 2] = 0 - d;\n                    d = (f + -1 - d) | 0;\n                }\n            while (0);\n            c[(a + 32) >> 2] = d;\n            c[a >> 2] = 0;\n            return;\n        }\n        function ye(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0;\n            g = (a + 36) | 0;\n            d = c[g >> 2] | 0;\n            e = (a + 40) | 0;\n            b = c[e >> 2] | 0;\n            if ((b | 0) != (d | 0))\n                do {\n                    b = (b + -44) | 0;\n                    Ic(b);\n                } while ((b | 0) != (d | 0));\n            c[e >> 2] = d;\n            e = (a + 68) | 0;\n            f = c[e >> 2] | 0;\n            d = (a + 72) | 0;\n            b = c[d >> 2] | 0;\n            if ((b | 0) != (f | 0))\n                do {\n                    b = (b + -44) | 0;\n                    Ic(b);\n                } while ((b | 0) != (f | 0));\n            c[d >> 2] = f;\n            Hc(e);\n            Hc(g);\n            return;\n        }\n        function ze(a) {\n            a = a | 0;\n            Ae((a + 4380) | 0);\n            re((a + 3980) | 0);\n            se(a);\n            return;\n        }\n        function Ae(a) {\n            a = a | 0;\n            qc((a + 320) | 0);\n            qc((a + 240) | 0);\n            qc((a + 160) | 0);\n            qc((a + 80) | 0);\n            qc(a);\n            return;\n        }\n        function Be(f, g, h) {\n            f = f | 0;\n            g = g | 0;\n            h = h | 0;\n            var i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0;\n            p = V;\n            V = (V + 32) | 0;\n            o = p;\n            i = (f + 4781) | 0;\n            if (!(a[i >> 0] | 0)) {\n                Ce((f + 4380) | 0);\n                a[i >> 0] = 1;\n            }\n            i = (f + 3976) | 0;\n            if (!(a[i >> 0] | 0)) {\n                a[i >> 0] = 1;\n                Ee(De(g) | 0, h, 20);\n                Fe(o, h);\n                k = f;\n                i = o;\n                j = (k + 20) | 0;\n                do {\n                    a[k >> 0] = a[i >> 0] | 0;\n                    k = (k + 1) | 0;\n                    i = (i + 1) | 0;\n                } while ((k | 0) < (j | 0));\n                b[(f + 12) >> 1] = 0;\n            }\n            else {\n                m = Zc(g, (f + 852) | 0) | 0;\n                if (m) {\n                    if ((m & 32) | 0)\n                        He((Zc(g, c[(f + 904 + (((Ge(f) | 0) & 255) << 2)) >> 2] | 0) | 0) & 255, f);\n                    n = (f + 14) | 0;\n                    k = a[n >> 0] | 0;\n                    i = k & 7;\n                    k = ((k & 255) >>> 3) & 7;\n                    j = d[(16 + (k << 3) + i) >> 0] | 0;\n                    i = d[(80 + (k << 3) + i) >> 0] | 0;\n                    if (!(m & 16))\n                        l = b[(f + 20 + (j << 1)) >> 1] | 0;\n                    else {\n                        q = (f + 20 + (j << 1)) | 0;\n                        l = (pc((f + 4380) | 0, g, e[q >> 1] | 0, j >>> 0 < 3 ? j : 3) | 0) & 65535;\n                        b[q >> 1] = l;\n                    }\n                    b[(f + 12) >> 1] = l;\n                    if ((m & 8) | 0) {\n                        q = (f + 15) | 0;\n                        a[q >> 0] = Zc(g, c[(f + 1928 + (d[q >> 0] << 2)) >> 2] | 0) | 0;\n                    }\n                    if ((m & 4) | 0) {\n                        n = Zc(g, c[(f + 896 + ((((d[n >> 0] | 0) >>> 6) & 1) << 2)) >> 2] | 0) | 0;\n                        q = (f + 16) | 0;\n                        a[q >> 0] = Ie((n + (a[q >> 0] | 0)) | 0) | 0;\n                    }\n                    if ((m & 2) | 0) {\n                        q = (f + 17) | 0;\n                        a[q >> 0] = Zc(g, c[(f + 2952 + (d[q >> 0] << 2)) >> 2] | 0) | 0;\n                    }\n                    if (m & 1) {\n                        q = (f + 18) | 0;\n                        b[q >> 1] = pc((f + 4460) | 0, g, e[q >> 1] | 0, 0) | 0;\n                    }\n                }\n                else {\n                    q = a[(f + 14) >> 0] | 0;\n                    i = q & 7;\n                    q = ((q & 255) >>> 3) & 7;\n                    k = q;\n                    j = d[(16 + (q << 3) + i) >> 0] | 0;\n                    i = d[(80 + (q << 3) + i) >> 0] | 0;\n                }\n                l = (f + 52 + ((j * 24) | 0)) | 0;\n                m = (f + 4540) | 0;\n                n = ((k | 0) == 1) & 1;\n                k = pc(m, g, Je(l) | 0, n) | 0;\n                c[o >> 2] = k;\n                c[f >> 2] = (c[f >> 2] | 0) + k;\n                Ke(l, o);\n                l = (f + 436 + ((j * 24) | 0)) | 0;\n                k = Je(l) | 0;\n                j = Le(m) | 0;\n                q = (f + 4620) | 0;\n                j = pc(q, g, k, (j >>> 0 < 20 ? j & -2 : 20) | n) | 0;\n                c[o >> 2] = j;\n                k = (f + 4) | 0;\n                c[k >> 2] = (c[k >> 2] | 0) + j;\n                Ke(l, o);\n                o = Le(m) | 0;\n                o = ((Le(q) | 0) + o) | 0;\n                q = (f + 820 + (i << 2)) | 0;\n                o =\n                    pc((f + 4700) | 0, g, c[q >> 2] | 0, (o >>> 0 < 36 ? (o >>> 1) & 2147483646 : 18) | n) |\n                        0;\n                c[(f + 8) >> 2] = o;\n                c[q >> 2] = o;\n                Me(f, h);\n            }\n            V = p;\n            return (h + 20) | 0;\n        }\n        function Ce(a) {\n            a = a | 0;\n            oc(a);\n            oc((a + 80) | 0);\n            oc((a + 160) | 0);\n            oc((a + 240) | 0);\n            oc((a + 320) | 0);\n            return;\n        }\n        function De(a) {\n            a = a | 0;\n            return c[a >> 2] | 0;\n        }\n        function Ee(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            k = (b + 4) | 0;\n            f = c[k >> 2] | 0;\n            j = ((c[(b + 8) >> 2] | 0) - f) | 0;\n            j = j >>> 0 > e >>> 0 ? e : j;\n            i = (b + 12) | 0;\n            g = ((c[i >> 2] | 0) + f) | 0;\n            h = (g + j) | 0;\n            if (j) {\n                f = g;\n                g = d;\n                while (1) {\n                    a[g >> 0] = a[f >> 0] | 0;\n                    f = (f + 1) | 0;\n                    if ((f | 0) == (h | 0))\n                        break;\n                    else\n                        g = (g + 1) | 0;\n                }\n                f = c[k >> 2] | 0;\n            }\n            c[k >> 2] = f + j;\n            e = (e - j) | 0;\n            if (e | 0) {\n                Kc(b);\n                g = ((c[i >> 2] | 0) + (c[k >> 2] | 0)) | 0;\n                h = (g + e) | 0;\n                f = (d + j) | 0;\n                while (1) {\n                    a[f >> 0] = a[g >> 0] | 0;\n                    g = (g + 1) | 0;\n                    if ((g | 0) == (h | 0))\n                        break;\n                    else\n                        f = (f + 1) | 0;\n                }\n                c[k >> 2] = (c[k >> 2] | 0) + e;\n            }\n            return;\n        }\n        function Fe(d, e) {\n            d = d | 0;\n            e = e | 0;\n            te(d);\n            c[d >> 2] = Ne(e) | 0;\n            c[(d + 4) >> 2] = Ne((e + 4) | 0) | 0;\n            c[(d + 8) >> 2] = Ne((e + 8) | 0) | 0;\n            b[(d + 12) >> 1] = Oe((e + 12) | 0) | 0;\n            He(Pe((e + 14) | 0) | 0, d);\n            a[(d + 15) >> 0] = Pe((e + 15) | 0) | 0;\n            a[(d + 16) >> 0] = Qe((e + 16) | 0) | 0;\n            a[(d + 17) >> 0] = Qe((e + 17) | 0) | 0;\n            b[(d + 18) >> 1] = Oe((e + 18) | 0) | 0;\n            return;\n        }\n        function Ge(b) {\n            b = b | 0;\n            return a[(b + 14) >> 0] | 0;\n        }\n        function He(b, c) {\n            b = b | 0;\n            c = c | 0;\n            a[(c + 14) >> 0] = b;\n            return;\n        }\n        function Ie(a) {\n            a = a | 0;\n            return (a & 255) | 0;\n        }\n        function Je(a) {\n            a = a | 0;\n            return c[(a + 8) >> 2] | 0;\n        }\n        function Ke(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            k = (b + 20) | 0;\n            do\n                if (!(a[k >> 0] | 0)) {\n                    j = (b + 8) | 0;\n                    e = c[j >> 2] | 0;\n                    f = c[d >> 2] | 0;\n                    g = (b + 4) | 0;\n                    h = c[g >> 2] | 0;\n                    if ((e | 0) >= (f | 0)) {\n                        if ((h | 0) < (f | 0)) {\n                            c[b >> 2] = h;\n                            c[g >> 2] = c[d >> 2];\n                        }\n                        else\n                            c[b >> 2] = f;\n                        a[k >> 0] = 1;\n                        break;\n                    }\n                    c[b >> 2] = h;\n                    c[g >> 2] = e;\n                    g = (b + 16) | 0;\n                    h = c[g >> 2] | 0;\n                    i = c[d >> 2] | 0;\n                    e = (b + 12) | 0;\n                    f = c[e >> 2] | 0;\n                    if ((h | 0) < (i | 0)) {\n                        c[j >> 2] = f;\n                        c[e >> 2] = h;\n                        c[g >> 2] = c[d >> 2];\n                        break;\n                    }\n                    if ((f | 0) < (i | 0)) {\n                        c[j >> 2] = f;\n                        c[e >> 2] = c[d >> 2];\n                        break;\n                    }\n                    else {\n                        c[j >> 2] = i;\n                        break;\n                    }\n                }\n                else {\n                    g = c[d >> 2] | 0;\n                    i = (b + 8) | 0;\n                    e = c[i >> 2] | 0;\n                    h = (b + 12) | 0;\n                    f = c[h >> 2] | 0;\n                    if ((g | 0) >= (e | 0)) {\n                        e = (b + 16) | 0;\n                        if ((g | 0) < (f | 0)) {\n                            c[e >> 2] = f;\n                            c[h >> 2] = c[d >> 2];\n                        }\n                        else\n                            c[e >> 2] = g;\n                        a[k >> 0] = 0;\n                        break;\n                    }\n                    c[(b + 16) >> 2] = f;\n                    c[h >> 2] = e;\n                    e = c[d >> 2] | 0;\n                    f = c[b >> 2] | 0;\n                    g = (b + 4) | 0;\n                    h = c[g >> 2] | 0;\n                    if ((e | 0) < (f | 0)) {\n                        c[i >> 2] = h;\n                        c[g >> 2] = f;\n                        c[b >> 2] = c[d >> 2];\n                        break;\n                    }\n                    if ((e | 0) < (h | 0)) {\n                        c[i >> 2] = h;\n                        c[g >> 2] = c[d >> 2];\n                        break;\n                    }\n                    else {\n                        c[i >> 2] = e;\n                        break;\n                    }\n                }\n            while (0);\n            return;\n        }\n        function Le(a) {\n            a = a | 0;\n            return c[a >> 2] | 0;\n        }\n        function Me(b, c) {\n            b = b | 0;\n            c = c | 0;\n            var e = 0;\n            Se(d[b >> 0] | (d[(b + 1) >> 0] << 8) | (d[(b + 2) >> 0] << 16) | (d[(b + 3) >> 0] << 24), c);\n            e = (b + 4) | 0;\n            Se(d[e >> 0] | (d[(e + 1) >> 0] << 8) | (d[(e + 2) >> 0] << 16) | (d[(e + 3) >> 0] << 24), (c + 4) | 0);\n            e = (b + 8) | 0;\n            Se(d[e >> 0] | (d[(e + 1) >> 0] << 8) | (d[(e + 2) >> 0] << 16) | (d[(e + 3) >> 0] << 24), (c + 8) | 0);\n            e = (b + 12) | 0;\n            Te(d[e >> 0] | (d[(e + 1) >> 0] << 8), (c + 12) | 0);\n            Ue(Ge(b) | 0, (c + 14) | 0);\n            Ue(a[(b + 15) >> 0] | 0, (c + 15) | 0);\n            Ve(a[(b + 16) >> 0] | 0, (c + 16) | 0);\n            Ve(a[(b + 17) >> 0] | 0, (c + 17) | 0);\n            b = (b + 18) | 0;\n            Te(d[b >> 0] | (d[(b + 1) >> 0] << 8), (c + 18) | 0);\n            return;\n        }\n        function Ne(a) {\n            a = a | 0;\n            return Re(a) | 0;\n        }\n        function Oe(b) {\n            b = b | 0;\n            return (((a[(b + 1) >> 0] << 8) | d[b >> 0]) & 65535) | 0;\n        }\n        function Pe(b) {\n            b = b | 0;\n            return a[b >> 0] | 0;\n        }\n        function Qe(b) {\n            b = b | 0;\n            return a[b >> 0] | 0;\n        }\n        function Re(a) {\n            a = a | 0;\n            return (((d[(a + 1) >> 0] | 0) << 8) |\n                (d[a >> 0] | 0) |\n                ((d[(a + 2) >> 0] | 0) << 16) |\n                ((d[(a + 3) >> 0] | 0) << 24) |\n                0);\n        }\n        function Se(a, b) {\n            a = a | 0;\n            b = b | 0;\n            We(a, b);\n            return;\n        }\n        function Te(b, c) {\n            b = b | 0;\n            c = c | 0;\n            a[(c + 1) >> 0] = (b & 65535) >>> 8;\n            a[c >> 0] = b;\n            return;\n        }\n        function Ue(b, c) {\n            b = b | 0;\n            c = c | 0;\n            a[c >> 0] = b;\n            return;\n        }\n        function Ve(b, c) {\n            b = b | 0;\n            c = c | 0;\n            a[c >> 0] = b;\n            return;\n        }\n        function We(b, c) {\n            b = b | 0;\n            c = c | 0;\n            a[(c + 3) >> 0] = b >>> 24;\n            a[(c + 2) >> 0] = b >>> 16;\n            a[(c + 1) >> 0] = b >>> 8;\n            a[c >> 0] = b;\n            return;\n        }\n        function Xe(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return;\n        }\n        function Ye(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Ze(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 4) >> 2] & 255](a);\n            return;\n        }\n        function _e(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 9202 ? (a + 12) | 0 : 0) | 0;\n        }\n        function $e(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function af(a, b) {\n            a = a | 0;\n            b = b | 0;\n            fe(a);\n            c[a >> 2] = 4768;\n            c[(a + 4) >> 2] = b;\n            cf((a + 8) | 0);\n            return;\n        }\n        function bf(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 4792;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xe(a, e);\n            V = d;\n            return;\n        }\n        function cf(b) {\n            b = b | 0;\n            gf(b);\n            hf((b + 164) | 0);\n            jf((b + 244) | 0);\n            a[(b + 324) >> 0] = 0;\n            a[(b + 325) >> 0] = 0;\n            return;\n        }\n        function df(a) {\n            a = a | 0;\n            c[a >> 2] = 4768;\n            of((a + 8) | 0);\n            le(a);\n            return;\n        }\n        function ef(a) {\n            a = a | 0;\n            df(a);\n            jp(a);\n            return;\n        }\n        function ff(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return qf((a + 8) | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function gf(b) {\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0;\n            h = V;\n            V = (V + 16) | 0;\n            f = h;\n            a[b >> 0] = 0;\n            Oc((b + 4) | 0, 516, 0, 0);\n            Oc((b + 48) | 0, 6, 0, 0);\n            c[(b + 92) >> 2] = 0;\n            c[(b + 96) >> 2] = 0;\n            e = (b + 100) | 0;\n            mf(e);\n            nf(f);\n            g = c[f >> 2] | 0;\n            f = c[(f + 4) >> 2] | 0;\n            d = 4;\n            while (1) {\n                i = e;\n                j = i;\n                a[j >> 0] = g;\n                a[(j + 1) >> 0] = g >> 8;\n                a[(j + 2) >> 0] = g >> 16;\n                a[(j + 3) >> 0] = g >> 24;\n                i = (i + 4) | 0;\n                a[i >> 0] = f;\n                a[(i + 1) >> 0] = f >> 8;\n                a[(i + 2) >> 0] = f >> 16;\n                a[(i + 3) >> 0] = f >> 24;\n                d = (d + -1) | 0;\n                if (!d)\n                    break;\n                else\n                    e = (e + 8) | 0;\n            }\n            j = (b + 132) | 0;\n            c[j >> 2] = 0;\n            c[(j + 4) >> 2] = 0;\n            c[(j + 8) >> 2] = 0;\n            c[(j + 12) >> 2] = 0;\n            c[(j + 16) >> 2] = 0;\n            c[(j + 20) >> 2] = 0;\n            c[(j + 24) >> 2] = 0;\n            c[(j + 28) >> 2] = 0;\n            V = h;\n            return;\n        }\n        function hf(a) {\n            a = a | 0;\n            xe(a, 32, 9, 8, 0);\n            return;\n        }\n        function jf(a) {\n            a = a | 0;\n            mc(a, 32, 9, 8, 0);\n            return;\n        }\n        function kf(a) {\n            a = a | 0;\n            ye(a);\n            return;\n        }\n        function lf(a) {\n            a = a | 0;\n            Ic((a + 48) | 0);\n            Ic((a + 4) | 0);\n            return;\n        }\n        function mf(a) {\n            a = a | 0;\n            var b = 0;\n            b = (a + 32) | 0;\n            do {\n                nf(a);\n                a = (a + 8) | 0;\n            } while ((a | 0) != (b | 0));\n            return;\n        }\n        function nf(b) {\n            b = b | 0;\n            var c = 0;\n            c = b;\n            a[c >> 0] = 0;\n            a[(c + 1) >> 0] = 0;\n            a[(c + 2) >> 0] = 0;\n            a[(c + 3) >> 0] = 0;\n            b = (b + 4) | 0;\n            a[b >> 0] = 0;\n            a[(b + 1) >> 0] = 0;\n            a[(b + 2) >> 0] = 0;\n            a[(b + 3) >> 0] = 0;\n            return;\n        }\n        function of(a) {\n            a = a | 0;\n            pf((a + 244) | 0);\n            kf((a + 164) | 0);\n            lf(a);\n            return;\n        }\n        function pf(a) {\n            a = a | 0;\n            qc(a);\n            return;\n        }\n        function qf(b, e, f) {\n            b = b | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0, h = 0, i = 0, j = 0, k = 0;\n            g = (b + 325) | 0;\n            if (!(a[g >> 0] | 0)) {\n                rf((b + 244) | 0);\n                a[g >> 0] = 1;\n            }\n            if (!(a[b >> 0] | 0)) {\n                a[b >> 0] = 1;\n                Ee(De(e) | 0, f, 8);\n                i = sf(f) | 0;\n                j = u() | 0;\n                b = (b + 100) | 0;\n                e = b;\n                a[e >> 0] = i;\n                a[(e + 1) >> 0] = i >> 8;\n                a[(e + 2) >> 0] = i >> 16;\n                a[(e + 3) >> 0] = i >> 24;\n                b = (b + 4) | 0;\n                a[b >> 0] = j;\n                a[(b + 1) >> 0] = j >> 8;\n                a[(b + 2) >> 0] = j >> 16;\n                a[(b + 3) >> 0] = j >> 24;\n            }\n            else {\n                j = (b + 92) | 0;\n                a: do\n                    if (!(c[(b + 132 + (c[j >> 2] << 2)) >> 2] | 0)) {\n                        g = Zc(e, (b + 48) | 0) | 0;\n                        switch (g | 0) {\n                            case 1: {\n                                e = pc((b + 244) | 0, e, 0, 0) | 0;\n                                c[(b + 132 + (c[j >> 2] << 2)) >> 2] = e;\n                                e = c[j >> 2] | 0;\n                                k = c[(b + 132 + (e << 2)) >> 2] | 0;\n                                i = (b + 100 + (e << 3)) | 0;\n                                h = i;\n                                g = h;\n                                h = (h + 4) | 0;\n                                k =\n                                    lr(d[g >> 0] |\n                                        (d[(g + 1) >> 0] << 8) |\n                                        (d[(g + 2) >> 0] << 16) |\n                                        (d[(g + 3) >> 0] << 24) |\n                                        0, d[h >> 0] |\n                                        (d[(h + 1) >> 0] << 8) |\n                                        (d[(h + 2) >> 0] << 16) |\n                                        (d[(h + 3) >> 0] << 24) |\n                                        0, k | 0, ((((k | 0) < 0) << 31) >> 31) | 0) | 0;\n                                h = u() | 0;\n                                g = i;\n                                a[g >> 0] = k;\n                                a[(g + 1) >> 0] = k >> 8;\n                                a[(g + 2) >> 0] = k >> 16;\n                                a[(g + 3) >> 0] = k >> 24;\n                                i = (i + 4) | 0;\n                                a[i >> 0] = h;\n                                a[(i + 1) >> 0] = h >> 8;\n                                a[(i + 2) >> 0] = h >> 16;\n                                a[(i + 3) >> 0] = h >> 24;\n                                c[(b + 148 + (e << 2)) >> 2] = 0;\n                                break a;\n                            }\n                            case 2: {\n                                k = (b + 96) | 0;\n                                c[k >> 2] = ((c[k >> 2] | 0) + 1) & 3;\n                                i = (b + 100 + (c[j >> 2] << 3) + 4) | 0;\n                                i =\n                                    pc((b + 244) | 0, e, d[i >> 0] |\n                                        (d[(i + 1) >> 0] << 8) |\n                                        (d[(i + 2) >> 0] << 16) |\n                                        (d[(i + 3) >> 0] << 24), 8) | 0;\n                                g = (b + 100 + (c[k >> 2] << 3)) | 0;\n                                h = g;\n                                a[h >> 0] = 0;\n                                a[(h + 1) >> 0] = 0;\n                                a[(h + 2) >> 0] = 0;\n                                a[(h + 3) >> 0] = 0;\n                                g = (g + 4) | 0;\n                                a[g >> 0] = i;\n                                a[(g + 1) >> 0] = i >> 8;\n                                a[(g + 2) >> 0] = i >> 16;\n                                a[(g + 3) >> 0] = i >> 24;\n                                g = tf(e) | 0;\n                                k = c[k >> 2] | 0;\n                                e = (b + 100 + (k << 3)) | 0;\n                                i = e;\n                                h = i;\n                                i = (i + 4) | 0;\n                                i =\n                                    d[i >> 0] |\n                                        (d[(i + 1) >> 0] << 8) |\n                                        (d[(i + 2) >> 0] << 16) |\n                                        (d[(i + 3) >> 0] << 24);\n                                g =\n                                    d[h >> 0] |\n                                        (d[(h + 1) >> 0] << 8) |\n                                        (d[(h + 2) >> 0] << 16) |\n                                        (d[(h + 3) >> 0] << 24) |\n                                        g;\n                                h = e;\n                                a[h >> 0] = g;\n                                a[(h + 1) >> 0] = g >> 8;\n                                a[(h + 2) >> 0] = g >> 16;\n                                a[(h + 3) >> 0] = g >> 24;\n                                e = (e + 4) | 0;\n                                a[e >> 0] = i;\n                                a[(e + 1) >> 0] = i >> 8;\n                                a[(e + 2) >> 0] = i >> 16;\n                                a[(e + 3) >> 0] = i >> 24;\n                                c[j >> 2] = k;\n                                c[(b + 132 + (k << 2)) >> 2] = 0;\n                                c[(b + 148 + (c[j >> 2] << 2)) >> 2] = 0;\n                                break a;\n                            }\n                            default: {\n                                if ((g | 0) <= 2)\n                                    break a;\n                                c[j >> 2] = (g + 2 + (c[j >> 2] | 0)) & 3;\n                                qf(b, e, f) | 0;\n                                break a;\n                            }\n                        }\n                    }\n                    else {\n                        i = Zc(e, (b + 4) | 0) | 0;\n                        if ((i | 0) == 1) {\n                            g = pc((b + 244) | 0, e, c[(b + 132 + (c[j >> 2] << 2)) >> 2] | 0, 1) | 0;\n                            k = c[j >> 2] | 0;\n                            e = (b + 100 + (k << 3)) | 0;\n                            i = e;\n                            h = i;\n                            i = (i + 4) | 0;\n                            g =\n                                lr(d[h >> 0] |\n                                    (d[(h + 1) >> 0] << 8) |\n                                    (d[(h + 2) >> 0] << 16) |\n                                    (d[(h + 3) >> 0] << 24) |\n                                    0, d[i >> 0] |\n                                    (d[(i + 1) >> 0] << 8) |\n                                    (d[(i + 2) >> 0] << 16) |\n                                    (d[(i + 3) >> 0] << 24) |\n                                    0, g | 0, ((((g | 0) < 0) << 31) >> 31) | 0) | 0;\n                            i = u() | 0;\n                            h = e;\n                            a[h >> 0] = g;\n                            a[(h + 1) >> 0] = g >> 8;\n                            a[(h + 2) >> 0] = g >> 16;\n                            a[(h + 3) >> 0] = g >> 24;\n                            e = (e + 4) | 0;\n                            a[e >> 0] = i;\n                            a[(e + 1) >> 0] = i >> 8;\n                            a[(e + 2) >> 0] = i >> 16;\n                            a[(e + 3) >> 0] = i >> 24;\n                            c[(b + 148 + (k << 2)) >> 2] = 0;\n                            break;\n                        }\n                        if ((i | 0) >= 511) {\n                            if ((i | 0) == 512) {\n                                k = (b + 96) | 0;\n                                c[k >> 2] = ((c[k >> 2] | 0) + 1) & 3;\n                                i = (b + 100 + (c[j >> 2] << 3) + 4) | 0;\n                                i =\n                                    pc((b + 244) | 0, e, d[i >> 0] |\n                                        (d[(i + 1) >> 0] << 8) |\n                                        (d[(i + 2) >> 0] << 16) |\n                                        (d[(i + 3) >> 0] << 24), 8) | 0;\n                                g = (b + 100 + (c[k >> 2] << 3)) | 0;\n                                h = g;\n                                a[h >> 0] = 0;\n                                a[(h + 1) >> 0] = 0;\n                                a[(h + 2) >> 0] = 0;\n                                a[(h + 3) >> 0] = 0;\n                                g = (g + 4) | 0;\n                                a[g >> 0] = i;\n                                a[(g + 1) >> 0] = i >> 8;\n                                a[(g + 2) >> 0] = i >> 16;\n                                a[(g + 3) >> 0] = i >> 24;\n                                g = tf(e) | 0;\n                                k = c[k >> 2] | 0;\n                                e = (b + 100 + (k << 3)) | 0;\n                                i = e;\n                                h = i;\n                                i = (i + 4) | 0;\n                                i =\n                                    d[i >> 0] |\n                                        (d[(i + 1) >> 0] << 8) |\n                                        (d[(i + 2) >> 0] << 16) |\n                                        (d[(i + 3) >> 0] << 24);\n                                g =\n                                    d[h >> 0] |\n                                        (d[(h + 1) >> 0] << 8) |\n                                        (d[(h + 2) >> 0] << 16) |\n                                        (d[(h + 3) >> 0] << 24) |\n                                        g;\n                                h = e;\n                                a[h >> 0] = g;\n                                a[(h + 1) >> 0] = g >> 8;\n                                a[(h + 2) >> 0] = g >> 16;\n                                a[(h + 3) >> 0] = g >> 24;\n                                e = (e + 4) | 0;\n                                a[e >> 0] = i;\n                                a[(e + 1) >> 0] = i >> 8;\n                                a[(e + 2) >> 0] = i >> 16;\n                                a[(e + 3) >> 0] = i >> 24;\n                                c[j >> 2] = k;\n                                c[(b + 132 + (k << 2)) >> 2] = 0;\n                                c[(b + 148 + (c[j >> 2] << 2)) >> 2] = 0;\n                                break;\n                            }\n                            if ((i | 0) <= 511)\n                                break;\n                            c[j >> 2] = ((c[j >> 2] | 0) + i) & 3;\n                            qf(b, e, f) | 0;\n                            break;\n                        }\n                        do\n                            if (!i) {\n                                g = pc((b + 244) | 0, e, 0, 7) | 0;\n                                h = (b + 148 + (c[j >> 2] << 2)) | 0;\n                                c[h >> 2] = (c[h >> 2] | 0) + 1;\n                                h = c[j >> 2] | 0;\n                                if ((c[(b + 148 + (h << 2)) >> 2] | 0) > 3) {\n                                    c[(b + 132 + (h << 2)) >> 2] = g;\n                                    c[(b + 148 + (c[j >> 2] << 2)) >> 2] = 0;\n                                }\n                            }\n                            else {\n                                if ((i | 0) < 500) {\n                                    g = (b + 244) | 0;\n                                    h = q(c[(b + 132 + (c[j >> 2] << 2)) >> 2] | 0, i) | 0;\n                                    if ((i | 0) < 10) {\n                                        g = pc(g, e, h, 2) | 0;\n                                        break;\n                                    }\n                                    else {\n                                        g = pc(g, e, h, 3) | 0;\n                                        break;\n                                    }\n                                }\n                                if ((i | 0) == 500) {\n                                    g =\n                                        pc((b + 244) | 0, e, ((c[(b + 132 + (c[j >> 2] << 2)) >> 2] | 0) * 500) | 0, 4) | 0;\n                                    h = (b + 148 + (c[j >> 2] << 2)) | 0;\n                                    c[h >> 2] = (c[h >> 2] | 0) + 1;\n                                    h = c[j >> 2] | 0;\n                                    if ((c[(b + 148 + (h << 2)) >> 2] | 0) <= 3)\n                                        break;\n                                    c[(b + 132 + (h << 2)) >> 2] = g;\n                                    c[(b + 148 + (c[j >> 2] << 2)) >> 2] = 0;\n                                    break;\n                                }\n                                g = (500 - i) | 0;\n                                h = (b + 244) | 0;\n                                i = c[(b + 132 + (c[j >> 2] << 2)) >> 2] | 0;\n                                if ((g | 0) > -10) {\n                                    g = pc(h, e, q(i, g) | 0, 5) | 0;\n                                    break;\n                                }\n                                g = pc(h, e, q(i, -10) | 0, 6) | 0;\n                                h = (b + 148 + (c[j >> 2] << 2)) | 0;\n                                c[h >> 2] = (c[h >> 2] | 0) + 1;\n                                h = c[j >> 2] | 0;\n                                if ((c[(b + 148 + (h << 2)) >> 2] | 0) > 3) {\n                                    c[(b + 132 + (h << 2)) >> 2] = g;\n                                    c[(b + 148 + (c[j >> 2] << 2)) >> 2] = 0;\n                                }\n                            }\n                        while (0);\n                        k = (b + 100 + (c[j >> 2] << 3)) | 0;\n                        h = k;\n                        e = h;\n                        h = (h + 4) | 0;\n                        h =\n                            lr(d[e >> 0] |\n                                (d[(e + 1) >> 0] << 8) |\n                                (d[(e + 2) >> 0] << 16) |\n                                (d[(e + 3) >> 0] << 24) |\n                                0, d[h >> 0] |\n                                (d[(h + 1) >> 0] << 8) |\n                                (d[(h + 2) >> 0] << 16) |\n                                (d[(h + 3) >> 0] << 24) |\n                                0, g | 0, ((((g | 0) < 0) << 31) >> 31) | 0) | 0;\n                        e = u() | 0;\n                        i = k;\n                        a[i >> 0] = h;\n                        a[(i + 1) >> 0] = h >> 8;\n                        a[(i + 2) >> 0] = h >> 16;\n                        a[(i + 3) >> 0] = h >> 24;\n                        k = (k + 4) | 0;\n                        a[k >> 0] = e;\n                        a[(k + 1) >> 0] = e >> 8;\n                        a[(k + 2) >> 0] = e >> 16;\n                        a[(k + 3) >> 0] = e >> 24;\n                    }\n                while (0);\n                uf((b + 100 + (c[j >> 2] << 3)) | 0, f);\n            }\n            return (f + 8) | 0;\n        }\n        function rf(a) {\n            a = a | 0;\n            oc(a);\n            return;\n        }\n        function sf(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            e = Re(a) | 0;\n            vf(d, e, Re((a + 4) | 0) | 0);\n            a = c[d >> 2] | 0;\n            t(c[(d + 4) >> 2] | 0);\n            V = b;\n            return a | 0;\n        }\n        function tf(a) {\n            a = a | 0;\n            var b = 0;\n            b = (bd(a) | 0) & 65535;\n            return (((bd(a) | 0) & 65535) << 16) | b | 0;\n        }\n        function uf(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var c = 0;\n            c = a;\n            We(d[c >> 0] | (d[(c + 1) >> 0] << 8) | (d[(c + 2) >> 0] << 16) | (d[(c + 3) >> 0] << 24), b);\n            a = (a + 4) | 0;\n            We(d[a >> 0] | (d[(a + 1) >> 0] << 8) | (d[(a + 2) >> 0] << 16) | (d[(a + 3) >> 0] << 24), (b + 4) | 0);\n            return;\n        }\n        function vf(b, c, d) {\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            var e = 0;\n            e = b;\n            a[e >> 0] = c;\n            a[(e + 1) >> 0] = c >> 8;\n            a[(e + 2) >> 0] = c >> 16;\n            a[(e + 3) >> 0] = c >> 24;\n            c = (b + 4) | 0;\n            a[c >> 0] = d;\n            a[(c + 1) >> 0] = d >> 8;\n            a[(c + 2) >> 0] = d >> 16;\n            a[(c + 3) >> 0] = d >> 24;\n            return;\n        }\n        function wf(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function xf(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 4) >> 2] & 255](a);\n            return;\n        }\n        function yf(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 9890 ? (a + 12) | 0 : 0) | 0;\n        }\n        function zf(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Af(a, b) {\n            a = a | 0;\n            b = b | 0;\n            fe(a);\n            c[a >> 2] = 4820;\n            c[(a + 4) >> 2] = b;\n            Cf((a + 8) | 0);\n            return;\n        }\n        function Bf(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 4844;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xe(a, e);\n            V = d;\n            return;\n        }\n        function Cf(b) {\n            b = b | 0;\n            a[b >> 0] = 0;\n            Gf((b + 1) | 0);\n            Oc((b + 8) | 0, 128, 0, 0);\n            Oc((b + 52) | 0, 256, 0, 0);\n            Oc((b + 96) | 0, 256, 0, 0);\n            Oc((b + 140) | 0, 256, 0, 0);\n            Oc((b + 184) | 0, 256, 0, 0);\n            Oc((b + 228) | 0, 256, 0, 0);\n            Oc((b + 272) | 0, 256, 0, 0);\n            return;\n        }\n        function Df(a) {\n            a = a | 0;\n            c[a >> 2] = 4820;\n            Hf((a + 8) | 0);\n            le(a);\n            return;\n        }\n        function Ef(a) {\n            a = a | 0;\n            Df(a);\n            jp(a);\n            return;\n        }\n        function Ff(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return If((a + 8) | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function Gf(b) {\n            b = b | 0;\n            var c = 0;\n            a[b >> 0] = 0;\n            a[(b + 1) >> 0] = 0;\n            c = (b + 2) | 0;\n            a[c >> 0] = 0;\n            a[(c + 1) >> 0] = 0;\n            b = (b + 4) | 0;\n            a[b >> 0] = 0;\n            a[(b + 1) >> 0] = 0;\n            return;\n        }\n        function Hf(a) {\n            a = a | 0;\n            Ic((a + 272) | 0);\n            Ic((a + 228) | 0);\n            Ic((a + 184) | 0);\n            Ic((a + 140) | 0);\n            Ic((a + 96) | 0);\n            Ic((a + 52) | 0);\n            Ic((a + 8) | 0);\n            return;\n        }\n        function If(c, f, g) {\n            c = c | 0;\n            f = f | 0;\n            g = g | 0;\n            var h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0;\n            o = V;\n            V = (V + 16) | 0;\n            m = o;\n            if (!(a[c >> 0] | 0)) {\n                a[c >> 0] = 1;\n                Ee(De(f) | 0, g, 6);\n                Jf(m, g);\n                n = (c + 1) | 0;\n                a[n >> 0] = a[m >> 0] | 0;\n                a[(n + 1) >> 0] = a[(m + 1) >> 0] | 0;\n                a[(n + 2) >> 0] = a[(m + 2) >> 0] | 0;\n                a[(n + 3) >> 0] = a[(m + 3) >> 0] | 0;\n                a[(n + 4) >> 0] = a[(m + 4) >> 0] | 0;\n                a[(n + 5) >> 0] = a[(m + 5) >> 0] | 0;\n            }\n            else {\n                n = Zc(f, (c + 8) | 0) | 0;\n                Gf(m);\n                if (!(n & 1)) {\n                    h = (c + 1) | 0;\n                    h = (d[h >> 0] | (d[(h + 1) >> 0] << 8)) & 255;\n                }\n                else {\n                    l = (Zc(f, (c + 52) | 0) | 0) & 255;\n                    h = (c + 1) | 0;\n                    h = (Ie((l + ((d[h >> 0] | (d[(h + 1) >> 0] << 8)) & 255)) | 0) | 0) & 255;\n                }\n                b[m >> 1] = h;\n                if (!(n & 2)) {\n                    l = (c + 1) | 0;\n                    h = h | ((d[l >> 0] | (d[(l + 1) >> 0] << 8)) & -256);\n                }\n                else {\n                    h = (Zc(f, (c + 96) | 0) | 0) & 255;\n                    l = (c + 1) | 0;\n                    h =\n                        ((Ie(((((d[l >> 0] | (d[(l + 1) >> 0] << 8)) & 65535) >>> 8) + h) | 0) | 0) & 255) << 8;\n                    h = (h | e[m >> 1]) & 65535;\n                }\n                b[m >> 1] = h;\n                do\n                    if (n & 64) {\n                        k = (c + 1) | 0;\n                        i = ((h & 255) - ((d[k >> 0] | (d[(k + 1) >> 0] << 8)) & 255)) | 0;\n                        if (!(n & 4)) {\n                            h = (c + 3) | 0;\n                            h = (d[h >> 0] | (d[(h + 1) >> 0] << 8)) & 255;\n                        }\n                        else {\n                            h = (Zc(f, (c + 140) | 0) | 0) & 255;\n                            l = (c + 3) | 0;\n                            l = (i + ((d[l >> 0] | (d[(l + 1) >> 0] << 8)) & 255)) | 0;\n                            h = (Ie((((l | 0) < 1 ? 0 : (l | 0) > 254 ? 255 : l & 255) + h) | 0) | 0) & 255;\n                        }\n                        l = (m + 2) | 0;\n                        b[l >> 1] = h;\n                        if (!(n & 16)) {\n                            h = (c + 5) | 0;\n                            h = (d[h >> 0] | (d[(h + 1) >> 0] << 8)) & 255;\n                        }\n                        else {\n                            h = Zc(f, (c + 228) | 0) | 0;\n                            p = (c + 3) | 0;\n                            j = (c + 5) | 0;\n                            j =\n                                (((((i + (b[l >> 1] & 255) - ((d[p >> 0] | (d[(p + 1) >> 0] << 8)) & 255)) | 0) /\n                                    2) |\n                                    0) +\n                                    ((d[j >> 0] | (d[(j + 1) >> 0] << 8)) & 255)) |\n                                    0;\n                            h =\n                                (Ie((((j | 0) < 1 ? 0 : (j | 0) > 254 ? 255 : j & 255) + (h & 255)) | 0) | 0) & 255;\n                        }\n                        j = (m + 4) | 0;\n                        b[j >> 1] = h;\n                        h =\n                            (((e[m >> 1] | 0) >>> 8) - (((d[k >> 0] | (d[(k + 1) >> 0] << 8)) & 65535) >>> 8)) |\n                                0;\n                        if (!(n & 8)) {\n                            i = (c + 3) | 0;\n                            i = b[l >> 1] | ((d[i >> 0] | (d[(i + 1) >> 0] << 8)) & -256);\n                        }\n                        else {\n                            i = (Zc(f, (c + 184) | 0) | 0) & 255;\n                            p = (c + 3) | 0;\n                            p = ((((d[p >> 0] | (d[(p + 1) >> 0] << 8)) & 65535) >>> 8) + h) | 0;\n                            i =\n                                ((Ie((((p | 0) < 1 ? 0 : (p | 0) > 254 ? 255 : p & 255) + i) | 0) | 0) & 255) << 8;\n                            i = (i | e[l >> 1]) & 65535;\n                        }\n                        b[l >> 1] = i;\n                        if (!(n & 32)) {\n                            p = (c + 5) | 0;\n                            b[j >> 1] = b[j >> 1] | ((d[p >> 0] | (d[(p + 1) >> 0] << 8)) & -256);\n                            break;\n                        }\n                        else {\n                            p = Zc(f, (c + 272) | 0) | 0;\n                            f = (c + 3) | 0;\n                            n = (c + 5) | 0;\n                            n =\n                                (((((((e[l >> 1] | 0) >>> 8) +\n                                    h -\n                                    (((d[f >> 0] | (d[(f + 1) >> 0] << 8)) & 65535) >>> 8)) |\n                                    0) /\n                                    2) |\n                                    0) +\n                                    (((d[n >> 0] | (d[(n + 1) >> 0] << 8)) & 65535) >>> 8)) |\n                                    0;\n                            p =\n                                ((Ie((((n | 0) < 1 ? 0 : (n | 0) > 254 ? 255 : n & 255) + (p & 255)) | 0) | 0) &\n                                    255) <<\n                                    8;\n                            b[j >> 1] = p | e[j >> 1];\n                            break;\n                        }\n                    }\n                    else {\n                        b[(m + 2) >> 1] = h;\n                        b[(m + 4) >> 1] = h;\n                    }\n                while (0);\n                p = (c + 1) | 0;\n                a[p >> 0] = a[m >> 0] | 0;\n                a[(p + 1) >> 0] = a[(m + 1) >> 0] | 0;\n                a[(p + 2) >> 0] = a[(m + 2) >> 0] | 0;\n                a[(p + 3) >> 0] = a[(m + 3) >> 0] | 0;\n                a[(p + 4) >> 0] = a[(m + 4) >> 0] | 0;\n                a[(p + 5) >> 0] = a[(m + 5) >> 0] | 0;\n                Kf(p, g);\n            }\n            V = o;\n            return (g + 6) | 0;\n        }\n        function Jf(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var c = 0, d = 0;\n            d = Oe(b) | 0;\n            c = Oe((b + 2) | 0) | 0;\n            Lf(a, d, c, Oe((b + 4) | 0) | 0);\n            return;\n        }\n        function Kf(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var c = 0;\n            Te(d[a >> 0] | (d[(a + 1) >> 0] << 8), b);\n            c = (a + 2) | 0;\n            Te(d[c >> 0] | (d[(c + 1) >> 0] << 8), (b + 2) | 0);\n            a = (a + 4) | 0;\n            Te(d[a >> 0] | (d[(a + 1) >> 0] << 8), (b + 4) | 0);\n            return;\n        }\n        function Lf(b, c, d, e) {\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            e = e | 0;\n            a[b >> 0] = c;\n            a[(b + 1) >> 0] = c >> 8;\n            c = (b + 2) | 0;\n            a[c >> 0] = d;\n            a[(c + 1) >> 0] = d >> 8;\n            d = (b + 4) | 0;\n            a[d >> 0] = e;\n            a[(d + 1) >> 0] = e >> 8;\n            return;\n        }\n        function Mf(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Nf(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 4) >> 2] & 255](a);\n            return;\n        }\n        function Of(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 10570 ? (a + 12) | 0 : 0) | 0;\n        }\n        function Pf(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Qf(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            fe(a);\n            c[a >> 2] = 4872;\n            c[(a + 4) >> 2] = b;\n            Sf((a + 8) | 0, d);\n            return;\n        }\n        function Rf(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 4896;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xe(a, e);\n            V = d;\n            return;\n        }\n        function Sf(b, d) {\n            b = b | 0;\n            d = d | 0;\n            c[b >> 2] = c[d >> 2];\n            a[(b + 4) >> 0] = a[(d + 4) >> 0] | 0;\n            Wf((b + 8) | 0, (d + 8) | 0);\n            Wf((b + 20) | 0, (d + 20) | 0);\n            Xf((b + 32) | 0, (d + 32) | 0);\n            return;\n        }\n        function Tf(a) {\n            a = a | 0;\n            c[a >> 2] = 4872;\n            ud((a + 8) | 0);\n            le(a);\n            return;\n        }\n        function Uf(a) {\n            a = a | 0;\n            Tf(a);\n            jp(a);\n            return;\n        }\n        function Vf(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return Dg((a + 8) | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function Wf(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0;\n            c[a >> 2] = 0;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = 0;\n            d = (b + 4) | 0;\n            e = ((c[d >> 2] | 0) - (c[b >> 2] | 0)) | 0;\n            if (e | 0) {\n                Yf(a, e);\n                Zf(a, c[b >> 2] | 0, c[d >> 2] | 0, e);\n            }\n            return;\n        }\n        function Xf(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0;\n            d = V;\n            V = (V + 32) | 0;\n            e = (d + 24) | 0;\n            f = (d + 16) | 0;\n            h = (d + 8) | 0;\n            g = d;\n            c[a >> 2] = 0;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = 0;\n            c[(a + 12) >> 2] = 0;\n            c[(a + 16) >> 2] = 0;\n            c[(a + 20) >> 2] = 0;\n            zg(h, b);\n            Ag(g, b);\n            c[f >> 2] = c[h >> 2];\n            c[(f + 4) >> 2] = c[(h + 4) >> 2];\n            c[e >> 2] = c[g >> 2];\n            c[(e + 4) >> 2] = c[(g + 4) >> 2];\n            cg(a, f, e, 0);\n            V = d;\n            return;\n        }\n        function Yf(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0;\n            if (($f(a) | 0) >>> 0 < b >>> 0)\n                cr(a);\n            else {\n                d = eq(b) | 0;\n                c[(a + 4) >> 2] = d;\n                c[a >> 2] = d;\n                c[(a + 8) >> 2] = d + b;\n                return;\n            }\n        }\n        function Zf(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0;\n            g = V;\n            V = (V + 16) | 0;\n            f = g;\n            ag(f, a, e);\n            e = (f + 4) | 0;\n            a = (d - b) | 0;\n            if ((a | 0) > 0) {\n                ur(c[e >> 2] | 0, b | 0, a | 0) | 0;\n                c[e >> 2] = (c[e >> 2] | 0) + a;\n            }\n            bg(f);\n            V = g;\n            return;\n        }\n        function _f(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = c[a >> 2] | 0;\n            d = b;\n            if (b | 0) {\n                c[(a + 4) >> 2] = d;\n                Da(b, ((c[(a + 8) >> 2] | 0) - d) | 0);\n            }\n            return;\n        }\n        function $f(a) {\n            a = a | 0;\n            return 2147483647;\n        }\n        function ag(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = b;\n            b = c[(b + 4) >> 2] | 0;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = b + d;\n            return;\n        }\n        function bg(a) {\n            a = a | 0;\n            c[((c[a >> 2] | 0) + 4) >> 2] = c[(a + 4) >> 2];\n            return;\n        }\n        function cg(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0;\n            q = V;\n            V = (V + 96) | 0;\n            p = (q + 80) | 0;\n            m = (q + 64) | 0;\n            j = (q + 48) | 0;\n            k = (q + 40) | 0;\n            l = (q + 8) | 0;\n            i = q;\n            n = (q + 32) | 0;\n            o = (q + 16) | 0;\n            h = b;\n            g = c[h >> 2] | 0;\n            h = c[(h + 4) >> 2] | 0;\n            f = d;\n            d = c[f >> 2] | 0;\n            f = c[(f + 4) >> 2] | 0;\n            e = g;\n            if ((f | 0) == (h | 0))\n                h = 0;\n            else\n                h =\n                    (((((f - (c[d >> 2] | 0)) | 0) / 44) | 0) +\n                        ((((d - g) >> 2) * 93) | 0) +\n                        ((((h - (c[g >> 2] | 0)) | 0) / -44) | 0)) |\n                        0;\n            d = ((c[(a + 8) >> 2] | 0) - (c[(a + 4) >> 2] | 0)) | 0;\n            d =\n                (((d | 0) == 0 ? 0 : ((((d >> 2) * 93) | 0) + -1) | 0) -\n                    ((c[(a + 20) >> 2] | 0) + (c[(a + 16) >> 2] | 0))) |\n                    0;\n            if (h >>> 0 > d >>> 0)\n                eg(a, (h - d) | 0);\n            fg(k, a);\n            fg(i, a);\n            f = i;\n            d = c[f >> 2] | 0;\n            f = c[(f + 4) >> 2] | 0;\n            g = l;\n            c[g >> 2] = d;\n            c[(g + 4) >> 2] = f;\n            g = d;\n            if (h | 0) {\n                d = (((((f - (c[d >> 2] | 0)) | 0) / 44) | 0) + h) | 0;\n                if ((d | 0) > 0) {\n                    i = ((d >>> 0) / 93) | 0;\n                    h = (g + (i << 2)) | 0;\n                    c[l >> 2] = h;\n                    d = ((c[h >> 2] | 0) + ((((d - ((i * 93) | 0)) | 0) * 44) | 0)) | 0;\n                }\n                else {\n                    d = (92 - d) | 0;\n                    i = (g + ((((d | 0) / -93) | 0) << 2)) | 0;\n                    c[l >> 2] = i;\n                    d = ((c[i >> 2] | 0) + ((((92 - ((d | 0) % 93 | 0)) | 0) * 44) | 0)) | 0;\n                }\n                c[(l + 4) >> 2] = d;\n            }\n            c[m >> 2] = c[k >> 2];\n            c[(m + 4) >> 2] = c[(k + 4) >> 2];\n            c[p >> 2] = c[l >> 2];\n            c[(p + 4) >> 2] = c[(l + 4) >> 2];\n            gg(j, m, p);\n            hg(p, j);\n            ig(m, j);\n            if (jg(p, m) | 0) {\n                g = (o + 4) | 0;\n                h = (b + 4) | 0;\n                do {\n                    kg(n, p);\n                    lg(o, a, n);\n                    d = c[o >> 2] | 0;\n                    if ((d | 0) != (c[g >> 2] | 0)) {\n                        f = c[h >> 2] | 0;\n                        do {\n                            Wc(d, f);\n                            d = ((c[o >> 2] | 0) + 44) | 0;\n                            c[o >> 2] = d;\n                            f = (f + 44) | 0;\n                            c[h >> 2] = f;\n                            if (((f - (c[e >> 2] | 0)) | 0) == 4092) {\n                                e = (e + 4) | 0;\n                                c[b >> 2] = e;\n                                f = c[e >> 2] | 0;\n                                c[h >> 2] = f;\n                            }\n                        } while ((d | 0) != (c[g >> 2] | 0));\n                    }\n                    mg(o);\n                    ng(p) | 0;\n                } while (jg(p, m) | 0);\n            }\n            V = q;\n            return;\n        }\n        function dg(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = c[(a + 4) >> 2] | 0;\n            d = (a + 8) | 0;\n            e = c[d >> 2] | 0;\n            if ((e | 0) != (b | 0))\n                c[d >> 2] = e + (~(((e + -4 - b) | 0) >>> 2) << 2);\n            b = c[a >> 2] | 0;\n            if (b | 0)\n                Da(b, ((c[(a + 12) >> 2] | 0) - b) | 0);\n            return;\n        }\n        function eg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0;\n            B = V;\n            V = (V + 64) | 0;\n            v = (B + 52) | 0;\n            u = (B + 48) | 0;\n            w = (B + 28) | 0;\n            x = (B + 24) | 0;\n            y = (B + 20) | 0;\n            p = B;\n            z = (a + 8) | 0;\n            d = c[z >> 2] | 0;\n            A = (a + 4) | 0;\n            j = c[A >> 2] | 0;\n            s = ((((d | 0) == (j | 0)) & 1) + b) | 0;\n            h = ((s >>> 0) / 93) | 0;\n            h = (h + ((((s - ((h * 93) | 0)) | 0) != 0) & 1)) | 0;\n            s = (a + 16) | 0;\n            e = c[s >> 2] | 0;\n            i = ((e >>> 0) / 93) | 0;\n            r = h >>> 0 < i >>> 0 ? h : i;\n            b = (h - r) | 0;\n            g = d;\n            a: do\n                if (!b) {\n                    c[s >> 2] = (q(r, -93) | 0) + e;\n                    if (r | 0) {\n                        i = (a + 12) | 0;\n                        k = (a + 12) | 0;\n                        l = (w + 4) | 0;\n                        m = (w + 8) | 0;\n                        n = (w + 12) | 0;\n                        b = r;\n                        e = j;\n                        while (1) {\n                            h = c[e >> 2] | 0;\n                            g = (e + 4) | 0;\n                            c[A >> 2] = g;\n                            t = c[i >> 2] | 0;\n                            e = t;\n                            do\n                                if ((d | 0) == (t | 0)) {\n                                    t = c[a >> 2] | 0;\n                                    d = t;\n                                    if (g >>> 0 <= t >>> 0) {\n                                        d = (e - d) | 0;\n                                        d = (d | 0) == 0 ? 1 : d >> 1;\n                                        qg(w, d, d >>> 2, k);\n                                        c[x >> 2] = c[A >> 2];\n                                        c[y >> 2] = c[z >> 2];\n                                        c[u >> 2] = c[x >> 2];\n                                        c[v >> 2] = c[y >> 2];\n                                        ug(w, u, v);\n                                        d = c[a >> 2] | 0;\n                                        c[a >> 2] = c[w >> 2];\n                                        c[w >> 2] = d;\n                                        d = c[A >> 2] | 0;\n                                        c[A >> 2] = c[l >> 2];\n                                        c[l >> 2] = d;\n                                        d = c[z >> 2] | 0;\n                                        c[z >> 2] = c[m >> 2];\n                                        c[m >> 2] = d;\n                                        d = c[i >> 2] | 0;\n                                        c[i >> 2] = c[n >> 2];\n                                        c[n >> 2] = d;\n                                        tg(w);\n                                        d = c[z >> 2] | 0;\n                                        break;\n                                    }\n                                    t = g;\n                                    d = (((((t - d) >> 2) + 1) | 0) / -2) | 0;\n                                    f = (g + (d << 2)) | 0;\n                                    e = (e - t) | 0;\n                                    if (!e)\n                                        d = f;\n                                    else {\n                                        vr(f | 0, g | 0, e | 0) | 0;\n                                        d = ((c[A >> 2] | 0) + (d << 2)) | 0;\n                                    }\n                                    t = (f + ((e >> 2) << 2)) | 0;\n                                    c[z >> 2] = t;\n                                    c[A >> 2] = d;\n                                    d = t;\n                                }\n                            while (0);\n                            c[d >> 2] = h;\n                            d = ((c[z >> 2] | 0) + 4) | 0;\n                            c[z >> 2] = d;\n                            b = (b + -1) | 0;\n                            if (!b)\n                                break a;\n                            e = c[A >> 2] | 0;\n                        }\n                    }\n                }\n                else {\n                    t = (a + 12) | 0;\n                    e = c[t >> 2] | 0;\n                    f = (e - (c[a >> 2] | 0)) | 0;\n                    d = (g - j) >> 2;\n                    if (b >>> 0 > (((f >> 2) - d) | 0) >>> 0) {\n                        o = f >> 1;\n                        n = (d + b) | 0;\n                        qg(p, o >>> 0 < n >>> 0 ? n : o, (d - r) | 0, (a + 12) | 0);\n                        do {\n                            c[v >> 2] = eq(4092) | 0;\n                            rg(p, v);\n                            b = (b + -1) | 0;\n                        } while ((b | 0) != 0);\n                        if (!r)\n                            d = c[A >> 2] | 0;\n                        else {\n                            i = (p + 8) | 0;\n                            j = (p + 12) | 0;\n                            k = (p + 4) | 0;\n                            l = (p + 16) | 0;\n                            m = (w + 4) | 0;\n                            n = (w + 8) | 0;\n                            o = (w + 12) | 0;\n                            h = r;\n                            b = c[i >> 2] | 0;\n                            d = c[A >> 2] | 0;\n                            do {\n                                g = c[j >> 2] | 0;\n                                e = g;\n                                do\n                                    if ((b | 0) == (g | 0)) {\n                                        f = c[k >> 2] | 0;\n                                        g = c[p >> 2] | 0;\n                                        b = g;\n                                        if (f >>> 0 <= g >>> 0) {\n                                            b = (e - b) | 0;\n                                            b = (b | 0) == 0 ? 1 : b >> 1;\n                                            qg(w, b, b >>> 2, c[l >> 2] | 0);\n                                            c[x >> 2] = c[k >> 2];\n                                            c[y >> 2] = c[i >> 2];\n                                            c[u >> 2] = c[x >> 2];\n                                            c[v >> 2] = c[y >> 2];\n                                            ug(w, u, v);\n                                            b = c[p >> 2] | 0;\n                                            c[p >> 2] = c[w >> 2];\n                                            c[w >> 2] = b;\n                                            b = c[k >> 2] | 0;\n                                            c[k >> 2] = c[m >> 2];\n                                            c[m >> 2] = b;\n                                            b = c[i >> 2] | 0;\n                                            c[i >> 2] = c[n >> 2];\n                                            c[n >> 2] = b;\n                                            b = c[j >> 2] | 0;\n                                            c[j >> 2] = c[o >> 2];\n                                            c[o >> 2] = b;\n                                            tg(w);\n                                            b = c[i >> 2] | 0;\n                                            break;\n                                        }\n                                        C = f;\n                                        b = (((((C - b) >> 2) + 1) | 0) / -2) | 0;\n                                        g = (f + (b << 2)) | 0;\n                                        e = (e - C) | 0;\n                                        if (!e)\n                                            b = g;\n                                        else {\n                                            vr(g | 0, f | 0, e | 0) | 0;\n                                            b = ((c[k >> 2] | 0) + (b << 2)) | 0;\n                                        }\n                                        C = (g + ((e >> 2) << 2)) | 0;\n                                        c[i >> 2] = C;\n                                        c[k >> 2] = b;\n                                        b = C;\n                                    }\n                                while (0);\n                                c[b >> 2] = c[d >> 2];\n                                b = ((c[i >> 2] | 0) + 4) | 0;\n                                c[i >> 2] = b;\n                                d = ((c[A >> 2] | 0) + 4) | 0;\n                                c[A >> 2] = d;\n                                h = (h + -1) | 0;\n                            } while ((h | 0) != 0);\n                        }\n                        b = c[z >> 2] | 0;\n                        if ((b | 0) != (d | 0)) {\n                            do {\n                                b = (b + -4) | 0;\n                                sg(p, b);\n                                d = c[A >> 2] | 0;\n                            } while ((b | 0) != (d | 0));\n                            b = c[z >> 2] | 0;\n                        }\n                        C = c[a >> 2] | 0;\n                        c[a >> 2] = c[p >> 2];\n                        c[p >> 2] = C;\n                        C = (p + 4) | 0;\n                        c[A >> 2] = c[C >> 2];\n                        c[C >> 2] = d;\n                        C = (p + 8) | 0;\n                        c[z >> 2] = c[C >> 2];\n                        c[C >> 2] = b;\n                        C = (p + 12) | 0;\n                        A = c[t >> 2] | 0;\n                        c[t >> 2] = c[C >> 2];\n                        c[C >> 2] = A;\n                        c[s >> 2] = (c[s >> 2] | 0) + (q(r, -93) | 0);\n                        tg(p);\n                        break;\n                    }\n                    else {\n                        b: do\n                            if ((e | 0) == (g | 0))\n                                k = 18;\n                            else {\n                                while (1) {\n                                    c[v >> 2] = eq(4092) | 0;\n                                    og(a, v);\n                                    b = (b + -1) | 0;\n                                    if (!b)\n                                        break;\n                                    if ((c[t >> 2] | 0) == (c[z >> 2] | 0)) {\n                                        k = 18;\n                                        break b;\n                                    }\n                                }\n                                d = r;\n                                b = c[s >> 2] | 0;\n                            }\n                        while (0);\n                        if ((k | 0) == 18) {\n                            e = ~(h >>> 0 > i >>> 0 ? i : h);\n                            d = b;\n                            do {\n                                c[v >> 2] = eq(4092) | 0;\n                                pg(a, v);\n                                d = (d + -1) | 0;\n                                f =\n                                    (((((c[z >> 2] | 0) - (c[A >> 2] | 0)) | 0) == 4 ? 92 : 93) + (c[s >> 2] | 0)) |\n                                        0;\n                                c[s >> 2] = f;\n                            } while ((d | 0) != 0);\n                            d = (b + -1 - e) | 0;\n                            b = f;\n                        }\n                        c[s >> 2] = b + (q(d, -93) | 0);\n                        if (!d)\n                            break;\n                        i = (a + 12) | 0;\n                        j = (w + 4) | 0;\n                        k = (w + 8) | 0;\n                        l = (w + 12) | 0;\n                        b = c[z >> 2] | 0;\n                        do {\n                            g = c[A >> 2] | 0;\n                            h = c[g >> 2] | 0;\n                            g = (g + 4) | 0;\n                            c[A >> 2] = g;\n                            C = c[t >> 2] | 0;\n                            e = C;\n                            do\n                                if ((b | 0) == (C | 0)) {\n                                    C = c[a >> 2] | 0;\n                                    b = C;\n                                    if (g >>> 0 <= C >>> 0) {\n                                        b = (e - b) | 0;\n                                        b = (b | 0) == 0 ? 1 : b >> 1;\n                                        qg(w, b, b >>> 2, i);\n                                        c[x >> 2] = c[A >> 2];\n                                        c[y >> 2] = c[z >> 2];\n                                        c[u >> 2] = c[x >> 2];\n                                        c[v >> 2] = c[y >> 2];\n                                        ug(w, u, v);\n                                        b = c[a >> 2] | 0;\n                                        c[a >> 2] = c[w >> 2];\n                                        c[w >> 2] = b;\n                                        b = c[A >> 2] | 0;\n                                        c[A >> 2] = c[j >> 2];\n                                        c[j >> 2] = b;\n                                        b = c[z >> 2] | 0;\n                                        c[z >> 2] = c[k >> 2];\n                                        c[k >> 2] = b;\n                                        b = c[t >> 2] | 0;\n                                        c[t >> 2] = c[l >> 2];\n                                        c[l >> 2] = b;\n                                        tg(w);\n                                        b = c[z >> 2] | 0;\n                                        break;\n                                    }\n                                    C = g;\n                                    b = (((((C - b) >> 2) + 1) | 0) / -2) | 0;\n                                    f = (g + (b << 2)) | 0;\n                                    e = (e - C) | 0;\n                                    if (!e)\n                                        b = f;\n                                    else {\n                                        vr(f | 0, g | 0, e | 0) | 0;\n                                        b = ((c[A >> 2] | 0) + (b << 2)) | 0;\n                                    }\n                                    C = (f + ((e >> 2) << 2)) | 0;\n                                    c[z >> 2] = C;\n                                    c[A >> 2] = b;\n                                    b = C;\n                                }\n                            while (0);\n                            c[b >> 2] = h;\n                            b = ((c[z >> 2] | 0) + 4) | 0;\n                            c[z >> 2] = b;\n                            d = (d + -1) | 0;\n                        } while ((d | 0) != 0);\n                    }\n                }\n            while (0);\n            V = B;\n            return;\n        }\n        function fg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0;\n            d = ((c[(b + 16) >> 2] | 0) + (c[(b + 20) >> 2] | 0)) | 0;\n            g = c[(b + 4) >> 2] | 0;\n            e = ((d >>> 0) / 93) | 0;\n            f = (g + (e << 2)) | 0;\n            if ((c[(b + 8) >> 2] | 0) == (g | 0))\n                b = 0;\n            else\n                b = ((c[f >> 2] | 0) + ((((d - ((e * 93) | 0)) | 0) * 44) | 0)) | 0;\n            c[a >> 2] = f;\n            c[(a + 4) >> 2] = b;\n            return;\n        }\n        function gg(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            f = b;\n            b = c[(f + 4) >> 2] | 0;\n            e = a;\n            c[e >> 2] = c[f >> 2];\n            c[(e + 4) >> 2] = b;\n            e = d;\n            b = c[(e + 4) >> 2] | 0;\n            d = (a + 8) | 0;\n            c[d >> 2] = c[e >> 2];\n            c[(d + 4) >> 2] = b;\n            return;\n        }\n        function hg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = c[b >> 2];\n            c[(a + 4) >> 2] = c[(b + 4) >> 2];\n            c[(a + 8) >> 2] = c[(b + 8) >> 2];\n            c[(a + 12) >> 2] = c[(b + 12) >> 2];\n            return;\n        }\n        function ig(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0;\n            d = V;\n            V = (V + 32) | 0;\n            e = (d + 24) | 0;\n            f = (d + 16) | 0;\n            h = (d + 8) | 0;\n            g = d;\n            i = (b + 8) | 0;\n            j = c[i >> 2] | 0;\n            i = c[(i + 4) >> 2] | 0;\n            b = h;\n            c[b >> 2] = j;\n            c[(b + 4) >> 2] = i;\n            b = g;\n            c[b >> 2] = j;\n            c[(b + 4) >> 2] = i;\n            c[f >> 2] = c[h >> 2];\n            c[(f + 4) >> 2] = c[(h + 4) >> 2];\n            c[e >> 2] = c[g >> 2];\n            c[(e + 4) >> 2] = c[(g + 4) >> 2];\n            gg(a, f, e);\n            V = d;\n            return;\n        }\n        function jg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((xg(a, b) | 0) ^ 1) | 0;\n        }\n        function kg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0;\n            d = c[b >> 2] | 0;\n            e = c[(b + 4) >> 2] | 0;\n            if ((d | 0) == (c[(b + 8) >> 2] | 0))\n                yg(a, e, c[(b + 12) >> 2] | 0);\n            else\n                yg(a, e, ((c[d >> 2] | 0) + 4092) | 0);\n            return;\n        }\n        function lg(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0;\n            e = c[d >> 2] | 0;\n            c[a >> 2] = e;\n            c[(a + 4) >> 2] = c[(d + 4) >> 2];\n            c[(a + 8) >> 2] = e;\n            c[(a + 12) >> 2] = b;\n            return;\n        }\n        function mg(a) {\n            a = a | 0;\n            var b = 0;\n            b = ((c[(a + 12) >> 2] | 0) + 20) | 0;\n            c[b >> 2] = (c[b >> 2] | 0) + (((((c[a >> 2] | 0) - (c[(a + 8) >> 2] | 0)) | 0) / 44) | 0);\n            return;\n        }\n        function ng(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = c[a >> 2] | 0;\n            d = (a + 8) | 0;\n            if ((b | 0) == (c[d >> 2] | 0)) {\n                e = d;\n                b = c[(e + 4) >> 2] | 0;\n                d = a;\n                c[d >> 2] = c[e >> 2];\n                c[(d + 4) >> 2] = b;\n            }\n            else {\n                e = (b + 4) | 0;\n                c[a >> 2] = e;\n                c[(a + 4) >> 2] = c[e >> 2];\n            }\n            return a | 0;\n        }\n        function og(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0;\n            p = V;\n            V = (V + 48) | 0;\n            f = (p + 32) | 0;\n            e = (p + 28) | 0;\n            i = (p + 8) | 0;\n            j = (p + 4) | 0;\n            k = p;\n            o = (a + 8) | 0;\n            d = c[o >> 2] | 0;\n            l = (a + 12) | 0;\n            n = c[l >> 2] | 0;\n            g = n;\n            do\n                if ((d | 0) == (n | 0)) {\n                    n = (a + 4) | 0;\n                    m = c[n >> 2] | 0;\n                    q = c[a >> 2] | 0;\n                    h = q;\n                    if (m >>> 0 <= q >>> 0) {\n                        d = (g - h) | 0;\n                        d = (d | 0) == 0 ? 1 : d >> 1;\n                        qg(i, d, d >>> 2, (a + 12) | 0);\n                        c[j >> 2] = c[n >> 2];\n                        c[k >> 2] = c[o >> 2];\n                        c[e >> 2] = c[j >> 2];\n                        c[f >> 2] = c[k >> 2];\n                        ug(i, e, f);\n                        d = c[a >> 2] | 0;\n                        c[a >> 2] = c[i >> 2];\n                        c[i >> 2] = d;\n                        d = (i + 4) | 0;\n                        q = c[n >> 2] | 0;\n                        c[n >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        d = (i + 8) | 0;\n                        q = c[o >> 2] | 0;\n                        c[o >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        d = (i + 12) | 0;\n                        q = c[l >> 2] | 0;\n                        c[l >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        tg(i);\n                        d = c[o >> 2] | 0;\n                        break;\n                    }\n                    f = m;\n                    e = (((((f - h) >> 2) + 1) | 0) / -2) | 0;\n                    a = (m + (e << 2)) | 0;\n                    f = (d - f) | 0;\n                    if (!f)\n                        d = a;\n                    else {\n                        vr(a | 0, m | 0, f | 0) | 0;\n                        d = ((c[n >> 2] | 0) + (e << 2)) | 0;\n                    }\n                    q = (a + ((f >> 2) << 2)) | 0;\n                    c[o >> 2] = q;\n                    c[n >> 2] = d;\n                    d = q;\n                }\n            while (0);\n            c[d >> 2] = c[b >> 2];\n            c[o >> 2] = (c[o >> 2] | 0) + 4;\n            V = p;\n            return;\n        }\n        function pg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0;\n            p = V;\n            V = (V + 48) | 0;\n            e = (p + 32) | 0;\n            d = (p + 28) | 0;\n            h = (p + 8) | 0;\n            i = (p + 4) | 0;\n            j = p;\n            o = (a + 4) | 0;\n            m = c[o >> 2] | 0;\n            n = c[a >> 2] | 0;\n            k = n;\n            do\n                if ((m | 0) == (n | 0)) {\n                    n = (a + 8) | 0;\n                    l = c[n >> 2] | 0;\n                    g = (a + 12) | 0;\n                    q = c[g >> 2] | 0;\n                    f = q;\n                    if (l >>> 0 >= q >>> 0) {\n                        q = (f - k) | 0;\n                        q = (q | 0) == 0 ? 1 : q >> 1;\n                        qg(h, q, ((q + 3) | 0) >>> 2, (a + 12) | 0);\n                        c[i >> 2] = c[o >> 2];\n                        c[j >> 2] = c[n >> 2];\n                        c[d >> 2] = c[i >> 2];\n                        c[e >> 2] = c[j >> 2];\n                        ug(h, d, e);\n                        d = c[a >> 2] | 0;\n                        c[a >> 2] = c[h >> 2];\n                        c[h >> 2] = d;\n                        d = (h + 4) | 0;\n                        q = c[o >> 2] | 0;\n                        c[o >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        d = (h + 8) | 0;\n                        q = c[n >> 2] | 0;\n                        c[n >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        d = (h + 12) | 0;\n                        q = c[g >> 2] | 0;\n                        c[g >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        tg(h);\n                        d = c[o >> 2] | 0;\n                        break;\n                    }\n                    e = l;\n                    a = (((((f - e) >> 2) + 1) | 0) / 2) | 0;\n                    f = (l + (a << 2)) | 0;\n                    e = (e - m) | 0;\n                    d = (f + ((0 - (e >> 2)) << 2)) | 0;\n                    if (!e) {\n                        d = f;\n                        e = f;\n                    }\n                    else {\n                        vr(d | 0, m | 0, e | 0) | 0;\n                        e = ((c[n >> 2] | 0) + (a << 2)) | 0;\n                    }\n                    c[o >> 2] = d;\n                    c[n >> 2] = e;\n                }\n                else\n                    d = m;\n            while (0);\n            c[(d + -4) >> 2] = c[b >> 2];\n            c[o >> 2] = (c[o >> 2] | 0) + -4;\n            V = p;\n            return;\n        }\n        function qg(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0;\n            f = (a + 12) | 0;\n            c[f >> 2] = 0;\n            c[(a + 16) >> 2] = e;\n            do\n                if (b)\n                    if (b >>> 0 > 1073741823) {\n                        f = v(8) | 0;\n                        vq(f, 6723);\n                        c[f >> 2] = 5956;\n                        x(f | 0, 3928, 123);\n                    }\n                    else {\n                        e = eq(b << 2) | 0;\n                        break;\n                    }\n                else\n                    e = 0;\n            while (0);\n            c[a >> 2] = e;\n            d = (e + (d << 2)) | 0;\n            c[(a + 8) >> 2] = d;\n            c[(a + 4) >> 2] = d;\n            c[f >> 2] = e + (b << 2);\n            return;\n        }\n        function rg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0;\n            p = V;\n            V = (V + 48) | 0;\n            f = (p + 32) | 0;\n            e = (p + 28) | 0;\n            i = (p + 8) | 0;\n            j = (p + 4) | 0;\n            k = p;\n            o = (a + 8) | 0;\n            d = c[o >> 2] | 0;\n            l = (a + 12) | 0;\n            n = c[l >> 2] | 0;\n            g = n;\n            do\n                if ((d | 0) == (n | 0)) {\n                    n = (a + 4) | 0;\n                    m = c[n >> 2] | 0;\n                    q = c[a >> 2] | 0;\n                    h = q;\n                    if (m >>> 0 <= q >>> 0) {\n                        d = (g - h) | 0;\n                        d = (d | 0) == 0 ? 1 : d >> 1;\n                        qg(i, d, d >>> 2, c[(a + 16) >> 2] | 0);\n                        c[j >> 2] = c[n >> 2];\n                        c[k >> 2] = c[o >> 2];\n                        c[e >> 2] = c[j >> 2];\n                        c[f >> 2] = c[k >> 2];\n                        ug(i, e, f);\n                        d = c[a >> 2] | 0;\n                        c[a >> 2] = c[i >> 2];\n                        c[i >> 2] = d;\n                        d = (i + 4) | 0;\n                        q = c[n >> 2] | 0;\n                        c[n >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        d = (i + 8) | 0;\n                        q = c[o >> 2] | 0;\n                        c[o >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        d = (i + 12) | 0;\n                        q = c[l >> 2] | 0;\n                        c[l >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        tg(i);\n                        d = c[o >> 2] | 0;\n                        break;\n                    }\n                    f = m;\n                    e = (((((f - h) >> 2) + 1) | 0) / -2) | 0;\n                    a = (m + (e << 2)) | 0;\n                    f = (d - f) | 0;\n                    if (!f)\n                        d = a;\n                    else {\n                        vr(a | 0, m | 0, f | 0) | 0;\n                        d = ((c[n >> 2] | 0) + (e << 2)) | 0;\n                    }\n                    q = (a + ((f >> 2) << 2)) | 0;\n                    c[o >> 2] = q;\n                    c[n >> 2] = d;\n                    d = q;\n                }\n            while (0);\n            c[d >> 2] = c[b >> 2];\n            c[o >> 2] = (c[o >> 2] | 0) + 4;\n            V = p;\n            return;\n        }\n        function sg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0;\n            p = V;\n            V = (V + 48) | 0;\n            e = (p + 32) | 0;\n            d = (p + 28) | 0;\n            h = (p + 8) | 0;\n            i = (p + 4) | 0;\n            j = p;\n            o = (a + 4) | 0;\n            m = c[o >> 2] | 0;\n            n = c[a >> 2] | 0;\n            k = n;\n            do\n                if ((m | 0) == (n | 0)) {\n                    n = (a + 8) | 0;\n                    l = c[n >> 2] | 0;\n                    g = (a + 12) | 0;\n                    q = c[g >> 2] | 0;\n                    f = q;\n                    if (l >>> 0 >= q >>> 0) {\n                        q = (f - k) | 0;\n                        q = (q | 0) == 0 ? 1 : q >> 1;\n                        qg(h, q, ((q + 3) | 0) >>> 2, c[(a + 16) >> 2] | 0);\n                        c[i >> 2] = c[o >> 2];\n                        c[j >> 2] = c[n >> 2];\n                        c[d >> 2] = c[i >> 2];\n                        c[e >> 2] = c[j >> 2];\n                        ug(h, d, e);\n                        d = c[a >> 2] | 0;\n                        c[a >> 2] = c[h >> 2];\n                        c[h >> 2] = d;\n                        d = (h + 4) | 0;\n                        q = c[o >> 2] | 0;\n                        c[o >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        d = (h + 8) | 0;\n                        q = c[n >> 2] | 0;\n                        c[n >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        d = (h + 12) | 0;\n                        q = c[g >> 2] | 0;\n                        c[g >> 2] = c[d >> 2];\n                        c[d >> 2] = q;\n                        tg(h);\n                        d = c[o >> 2] | 0;\n                        break;\n                    }\n                    e = l;\n                    a = (((((f - e) >> 2) + 1) | 0) / 2) | 0;\n                    f = (l + (a << 2)) | 0;\n                    e = (e - m) | 0;\n                    d = (f + ((0 - (e >> 2)) << 2)) | 0;\n                    if (!e) {\n                        d = f;\n                        e = f;\n                    }\n                    else {\n                        vr(d | 0, m | 0, e | 0) | 0;\n                        e = ((c[n >> 2] | 0) + (a << 2)) | 0;\n                    }\n                    c[o >> 2] = d;\n                    c[n >> 2] = e;\n                }\n                else\n                    d = m;\n            while (0);\n            c[(d + -4) >> 2] = c[b >> 2];\n            c[o >> 2] = (c[o >> 2] | 0) + -4;\n            V = p;\n            return;\n        }\n        function tg(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = c[(a + 4) >> 2] | 0;\n            d = (a + 8) | 0;\n            e = c[d >> 2] | 0;\n            if ((e | 0) != (b | 0))\n                c[d >> 2] = e + (~(((e + -4 - b) | 0) >>> 2) << 2);\n            b = c[a >> 2] | 0;\n            if (b | 0)\n                Da(b, ((c[(a + 12) >> 2] | 0) - b) | 0);\n            return;\n        }\n        function ug(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0;\n            h = V;\n            V = (V + 16) | 0;\n            g = h;\n            f = c[b >> 2] | 0;\n            vg(g, (a + 8) | 0, ((c[d >> 2] | 0) - f) >> 2);\n            a = c[g >> 2] | 0;\n            e = (g + 4) | 0;\n            if ((a | 0) != (c[e >> 2] | 0)) {\n                d = f;\n                do {\n                    c[a >> 2] = c[d >> 2];\n                    a = ((c[g >> 2] | 0) + 4) | 0;\n                    c[g >> 2] = a;\n                    d = (d + 4) | 0;\n                } while ((a | 0) != (c[e >> 2] | 0));\n                c[b >> 2] = d;\n            }\n            wg(g);\n            V = h;\n            return;\n        }\n        function vg(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = c[b >> 2];\n            c[(a + 4) >> 2] = (c[b >> 2] | 0) + (d << 2);\n            c[(a + 8) >> 2] = b;\n            return;\n        }\n        function wg(a) {\n            a = a | 0;\n            c[c[(a + 8) >> 2] >> 2] = c[a >> 2];\n            return;\n        }\n        function xg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(a + 4) >> 2] | 0) == (c[(b + 4) >> 2] | 0)) | 0;\n        }\n        function yg(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = b;\n            c[(a + 4) >> 2] = d;\n            return;\n        }\n        function zg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0;\n            g = c[(b + 4) >> 2] | 0;\n            d = c[(b + 16) >> 2] | 0;\n            e = ((d >>> 0) / 93) | 0;\n            f = (g + (e << 2)) | 0;\n            if ((c[(b + 8) >> 2] | 0) == (g | 0))\n                b = 0;\n            else\n                b = ((c[f >> 2] | 0) + ((((d - ((e * 93) | 0)) | 0) * 44) | 0)) | 0;\n            c[a >> 2] = f;\n            c[(a + 4) >> 2] = b;\n            return;\n        }\n        function Ag(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0;\n            d = ((c[(b + 16) >> 2] | 0) + (c[(b + 20) >> 2] | 0)) | 0;\n            g = c[(b + 4) >> 2] | 0;\n            e = ((d >>> 0) / 93) | 0;\n            f = (g + (e << 2)) | 0;\n            if ((c[(b + 8) >> 2] | 0) == (g | 0))\n                b = 0;\n            else\n                b = ((c[f >> 2] | 0) + ((((d - ((e * 93) | 0)) | 0) * 44) | 0)) | 0;\n            c[a >> 2] = f;\n            c[(a + 4) >> 2] = b;\n            return;\n        }\n        function Bg(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0;\n            i = V;\n            V = (V + 16) | 0;\n            e = (i + 8) | 0;\n            g = i;\n            Cg(e, a);\n            fg(g, a);\n            f = (e + 4) | 0;\n            b = c[f >> 2] | 0;\n            g = (g + 4) | 0;\n            if ((b | 0) != (c[g >> 2] | 0))\n                do {\n                    Ic(b);\n                    b = ((c[f >> 2] | 0) + 44) | 0;\n                    c[f >> 2] = b;\n                    d = c[e >> 2] | 0;\n                    if (((b - (c[d >> 2] | 0)) | 0) == 4092) {\n                        b = (d + 4) | 0;\n                        c[e >> 2] = b;\n                        b = c[b >> 2] | 0;\n                        c[f >> 2] = b;\n                    }\n                } while ((b | 0) != (c[g >> 2] | 0));\n            c[(a + 20) >> 2] = 0;\n            f = (a + 8) | 0;\n            e = (a + 4) | 0;\n            d = c[e >> 2] | 0;\n            b = ((c[f >> 2] | 0) - d) >> 2;\n            if (b >>> 0 > 2)\n                do {\n                    Da(c[d >> 2] | 0, 4092);\n                    d = ((c[e >> 2] | 0) + 4) | 0;\n                    c[e >> 2] = d;\n                    b = ((c[f >> 2] | 0) - d) >> 2;\n                } while (b >>> 0 > 2);\n            switch (b | 0) {\n                case 1: {\n                    b = 46;\n                    h = 11;\n                    break;\n                }\n                case 2: {\n                    b = 93;\n                    h = 11;\n                    break;\n                }\n                default: {\n                }\n            }\n            if ((h | 0) == 11)\n                c[(a + 16) >> 2] = b;\n            V = i;\n            return;\n        }\n        function Cg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0;\n            g = c[(b + 4) >> 2] | 0;\n            d = c[(b + 16) >> 2] | 0;\n            e = ((d >>> 0) / 93) | 0;\n            f = (g + (e << 2)) | 0;\n            if ((c[(b + 8) >> 2] | 0) == (g | 0))\n                b = 0;\n            else\n                b = ((c[f >> 2] | 0) + ((((d - ((e * 93) | 0)) | 0) * 44) | 0)) | 0;\n            c[a >> 2] = f;\n            c[(a + 4) >> 2] = b;\n            return;\n        }\n        function Dg(b, e, f) {\n            b = b | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0;\n            m = V;\n            V = (V + 16) | 0;\n            l = m;\n            j = (b + 4) | 0;\n            if (!(a[j >> 0] | 0)) {\n                l = De(e) | 0;\n                Ee(l, f, c[b >> 2] | 0);\n                l = c[b >> 2] | 0;\n                i = (f + l) | 0;\n                if (!l)\n                    g = 0;\n                else {\n                    g = f;\n                    h = c[(b + 8) >> 2] | 0;\n                    while (1) {\n                        a[h >> 0] = a[g >> 0] | 0;\n                        g = (g + 1) | 0;\n                        if ((g | 0) == (i | 0))\n                            break;\n                        else\n                            h = (h + 1) | 0;\n                    }\n                    g = c[b >> 2] | 0;\n                }\n                a[j >> 0] = 1;\n                f = (f + g) | 0;\n            }\n            else {\n                h = c[(b + 20) >> 2] | 0;\n                g = c[(b + 8) >> 2] | 0;\n                Cg(l, (b + 32) | 0);\n                b = (b + 12) | 0;\n                if ((g | 0) != (c[b >> 2] | 0)) {\n                    k = (l + 4) | 0;\n                    j = g;\n                    i = h;\n                    g = c[k >> 2] | 0;\n                    while (1) {\n                        h = d[j >> 0] | 0;\n                        h = Eg(((Zc(e, g) | 0) + h) | 0) | 0;\n                        a[i >> 0] = h;\n                        a[f >> 0] = h;\n                        a[j >> 0] = h;\n                        j = (j + 1) | 0;\n                        f = (f + 1) | 0;\n                        h = c[l >> 2] | 0;\n                        g = ((c[k >> 2] | 0) + 44) | 0;\n                        c[k >> 2] = g;\n                        if (((g - (c[h >> 2] | 0)) | 0) == 4092) {\n                            g = (h + 4) | 0;\n                            c[l >> 2] = g;\n                            g = c[g >> 2] | 0;\n                            c[k >> 2] = g;\n                        }\n                        if ((j | 0) == (c[b >> 2] | 0))\n                            break;\n                        else\n                            i = (i + 1) | 0;\n                    }\n                }\n            }\n            V = m;\n            return f | 0;\n        }\n        function Eg(a) {\n            a = a | 0;\n            return (a & 255) | 0;\n        }\n        function Fg(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Gg(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 4) >> 2] & 255](a);\n            return;\n        }\n        function Hg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 11262 ? (a + 12) | 0 : 0) | 0;\n        }\n        function Ig(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Jg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = 0;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = 0;\n            if (b | 0) {\n                Yf(a, b);\n                Lg(a, b);\n            }\n            return;\n        }\n        function Kg(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = 0;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = 0;\n            c[(a + 12) >> 2] = 0;\n            c[(a + 16) >> 2] = 0;\n            c[(a + 20) >> 2] = 0;\n            if (b | 0)\n                Mg(a, b, d);\n            return;\n        }\n        function Lg(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0;\n            g = V;\n            V = (V + 16) | 0;\n            f = g;\n            ag(f, b, d);\n            d = (f + 4) | 0;\n            b = c[d >> 2] | 0;\n            e = (f + 8) | 0;\n            if ((b | 0) != (c[e >> 2] | 0))\n                do {\n                    a[b >> 0] = 0;\n                    b = ((c[d >> 2] | 0) + 1) | 0;\n                    c[d >> 2] = b;\n                } while ((b | 0) != (c[e >> 2] | 0));\n            bg(f);\n            V = g;\n            return;\n        }\n        function Mg(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0;\n            o = V;\n            V = (V + 96) | 0;\n            n = (o + 80) | 0;\n            k = (o + 64) | 0;\n            h = (o + 48) | 0;\n            i = (o + 40) | 0;\n            j = (o + 8) | 0;\n            f = o;\n            l = (o + 32) | 0;\n            m = (o + 16) | 0;\n            e = ((c[(a + 8) >> 2] | 0) - (c[(a + 4) >> 2] | 0)) | 0;\n            e =\n                (((e | 0) == 0 ? 0 : ((((e >> 2) * 93) | 0) + -1) | 0) -\n                    ((c[(a + 20) >> 2] | 0) + (c[(a + 16) >> 2] | 0))) |\n                    0;\n            if (e >>> 0 < b >>> 0)\n                eg(a, (b - e) | 0);\n            fg(i, a);\n            fg(f, a);\n            e = c[f >> 2] | 0;\n            f = c[(f + 4) >> 2] | 0;\n            g = j;\n            c[g >> 2] = e;\n            c[(g + 4) >> 2] = f;\n            g = e;\n            if (b | 0) {\n                e = (((((f - (c[e >> 2] | 0)) | 0) / 44) | 0) + b) | 0;\n                if ((e | 0) > 0) {\n                    b = ((e >>> 0) / 93) | 0;\n                    g = (g + (b << 2)) | 0;\n                    c[j >> 2] = g;\n                    e = ((c[g >> 2] | 0) + ((((e - ((b * 93) | 0)) | 0) * 44) | 0)) | 0;\n                }\n                else {\n                    e = (92 - e) | 0;\n                    b = (g + ((((e | 0) / -93) | 0) << 2)) | 0;\n                    c[j >> 2] = b;\n                    e = ((c[b >> 2] | 0) + ((((92 - ((e | 0) % 93 | 0)) | 0) * 44) | 0)) | 0;\n                }\n                c[(j + 4) >> 2] = e;\n            }\n            c[k >> 2] = c[i >> 2];\n            c[(k + 4) >> 2] = c[(i + 4) >> 2];\n            c[n >> 2] = c[j >> 2];\n            c[(n + 4) >> 2] = c[(j + 4) >> 2];\n            gg(h, k, n);\n            hg(n, h);\n            ig(k, h);\n            if (jg(n, k) | 0) {\n                f = (m + 4) | 0;\n                do {\n                    kg(l, n);\n                    lg(m, a, l);\n                    e = c[m >> 2] | 0;\n                    if ((e | 0) != (c[f >> 2] | 0))\n                        do {\n                            Wc(e, d);\n                            e = ((c[m >> 2] | 0) + 44) | 0;\n                            c[m >> 2] = e;\n                        } while ((e | 0) != (c[f >> 2] | 0));\n                    mg(m);\n                    ng(n) | 0;\n                } while (jg(n, k) | 0);\n            }\n            V = o;\n            return;\n        }\n        function Ng(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            Bg(a);\n            b = c[(a + 4) >> 2] | 0;\n            d = c[(a + 8) >> 2] | 0;\n            if ((b | 0) != (d | 0))\n                do {\n                    Da(c[b >> 2] | 0, 4092);\n                    b = (b + 4) | 0;\n                } while ((b | 0) != (d | 0));\n            dg(a);\n            return;\n        }\n        function Og(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            Md(a);\n            c[a >> 2] = 4924;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = d;\n            return;\n        }\n        function Pg(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 4944;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Wg(a, e);\n            V = d;\n            return;\n        }\n        function Qg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return Tg(c[(a + 8) >> 2] | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function Rg(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            c[a >> 2] = 4924;\n            d = (a + 8) | 0;\n            b = c[d >> 2] | 0;\n            c[d >> 2] = 0;\n            if (b | 0) {\n                Vg(b);\n                jp(b);\n            }\n            Qd(a);\n            return;\n        }\n        function Sg(a) {\n            a = a | 0;\n            Rg(a);\n            jp(a);\n            return;\n        }\n        function Tg(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            return Ug((a + 4784) | 0, b, Be(a, b, c) | 0) | 0;\n        }\n        function Ug(b, c, d) {\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            if (a[b >> 0] | 0) {\n                nc(c);\n                a[b >> 0] = 0;\n            }\n            return d | 0;\n        }\n        function Vg(a) {\n            a = a | 0;\n            ze(a);\n            return;\n        }\n        function Wg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return;\n        }\n        function Xg(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Yg(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n            return;\n        }\n        function Zg(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 12004 ? (a + 12) | 0 : 0) | 0;\n        }\n        function _g(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function $g(b) {\n            b = b | 0;\n            a[b >> 0] = 1;\n            return;\n        }\n        function ah(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            Md(a);\n            c[a >> 2] = 4972;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = d;\n            return;\n        }\n        function bh(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 4992;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Wg(a, e);\n            V = d;\n            return;\n        }\n        function ch(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return fh(c[(a + 8) >> 2] | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function dh(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            c[a >> 2] = 4972;\n            d = (a + 8) | 0;\n            b = c[d >> 2] | 0;\n            c[d >> 2] = 0;\n            if (b | 0) {\n                hh(b);\n                jp(b);\n            }\n            Qd(a);\n            return;\n        }\n        function eh(a) {\n            a = a | 0;\n            dh(a);\n            jp(a);\n            return;\n        }\n        function fh(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            return gh((a + 4784) | 0, b, Be(a, b, c) | 0) | 0;\n        }\n        function gh(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            return Ug((a + 328) | 0, b, qf(a, b, c) | 0) | 0;\n        }\n        function hh(a) {\n            a = a | 0;\n            ih((a + 4784) | 0);\n            ze(a);\n            return;\n        }\n        function ih(a) {\n            a = a | 0;\n            of(a);\n            return;\n        }\n        function jh(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function kh(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n            return;\n        }\n        function lh(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 12827 ? (a + 12) | 0 : 0) | 0;\n        }\n        function mh(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function nh(a) {\n            a = a | 0;\n            cf(a);\n            $g((a + 328) | 0);\n            return;\n        }\n        function oh(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            Md(a);\n            c[a >> 2] = 5020;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = d;\n            return;\n        }\n        function ph(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5040;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Wg(a, e);\n            V = d;\n            return;\n        }\n        function qh(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return th(c[(a + 8) >> 2] | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function rh(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            c[a >> 2] = 5020;\n            d = (a + 8) | 0;\n            b = c[d >> 2] | 0;\n            c[d >> 2] = 0;\n            if (b | 0) {\n                vh(b);\n                jp(b);\n            }\n            Qd(a);\n            return;\n        }\n        function sh(a) {\n            a = a | 0;\n            rh(a);\n            jp(a);\n            return;\n        }\n        function th(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            return uh((a + 4784) | 0, b, Be(a, b, c) | 0) | 0;\n        }\n        function uh(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            return Ug((a + 316) | 0, b, If(a, b, c) | 0) | 0;\n        }\n        function vh(a) {\n            a = a | 0;\n            wh((a + 4784) | 0);\n            ze(a);\n            return;\n        }\n        function wh(a) {\n            a = a | 0;\n            Hf(a);\n            return;\n        }\n        function xh(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function yh(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n            return;\n        }\n        function zh(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 13672 ? (a + 12) | 0 : 0) | 0;\n        }\n        function Ah(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Bh(a) {\n            a = a | 0;\n            Cf(a);\n            $g((a + 316) | 0);\n            return;\n        }\n        function Ch(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            Md(a);\n            c[a >> 2] = 5068;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = d;\n            return;\n        }\n        function Dh(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5088;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Wg(a, e);\n            V = d;\n            return;\n        }\n        function Eh(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return Hh(c[(a + 8) >> 2] | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function Fh(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            c[a >> 2] = 5068;\n            d = (a + 8) | 0;\n            b = c[d >> 2] | 0;\n            c[d >> 2] = 0;\n            if (b | 0) {\n                Jh(b);\n                jp(b);\n            }\n            Qd(a);\n            return;\n        }\n        function Gh(a) {\n            a = a | 0;\n            Fh(a);\n            jp(a);\n            return;\n        }\n        function Hh(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            return Ih((a + 4784) | 0, b, Be(a, b, c) | 0) | 0;\n        }\n        function Ih(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            return uh((a + 328) | 0, b, qf(a, b, c) | 0) | 0;\n        }\n        function Jh(a) {\n            a = a | 0;\n            Kh((a + 4784) | 0);\n            ze(a);\n            return;\n        }\n        function Kh(a) {\n            a = a | 0;\n            wh((a + 328) | 0);\n            of(a);\n            return;\n        }\n        function Lh(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Mh(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n            return;\n        }\n        function Nh(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 14573 ? (a + 12) | 0 : 0) | 0;\n        }\n        function Oh(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Ph(a) {\n            a = a | 0;\n            cf(a);\n            Bh((a + 328) | 0);\n            return;\n        }\n        function Qh(a) {\n            a = a | 0;\n            return (a + 20) | 0;\n        }\n        function Rh(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = b;\n            c[(a + 4) >> 2] = d;\n            c[(a + 8) >> 2] = 0;\n            return;\n        }\n        function Sh(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = b;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = -1;\n            return;\n        }\n        function Th(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = (d + 4) | 0;\n            g = d;\n            f = eq(24) | 0;\n            ii(f, b);\n            c[g >> 2] = 0;\n            c[e >> 2] = c[g >> 2];\n            ji(a, f, e);\n            V = d;\n            return;\n        }\n        function Uh(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            a = c[(a + 4) >> 2] | 0;\n            if (a | 0 ? ((d = (a + 4) | 0), (b = c[d >> 2] | 0), (c[d >> 2] = b + -1), (b | 0) == 0) : 0) {\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n                qq(a);\n            }\n            return;\n        }\n        function Vh(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5116;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xh(a, e);\n            V = d;\n            return;\n        }\n        function Wh(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            a = c[(a + 4) >> 2] | 0;\n            if (a | 0 ? ((d = (a + 4) | 0), (b = c[d >> 2] | 0), (c[d >> 2] = b + -1), (b | 0) == 0) : 0) {\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n                qq(a);\n            }\n            return;\n        }\n        function Xh(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return;\n        }\n        function Yh(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Zh(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                jp(a);\n            return;\n        }\n        function _h(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 14966 ? (a + 12) | 0 : 0) | 0;\n        }\n        function $h(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function ai(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5144;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            ci(a, e);\n            V = d;\n            return;\n        }\n        function bi(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            a = c[(a + 4) >> 2] | 0;\n            if (a | 0 ? ((d = (a + 4) | 0), (b = c[d >> 2] | 0), (c[d >> 2] = b + -1), (b | 0) == 0) : 0) {\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n                qq(a);\n            }\n            return;\n        }\n        function ci(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return;\n        }\n        function di(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function ei(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0) {\n                hi(a);\n                jp(a);\n            }\n            return;\n        }\n        function fi(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 15127 ? (a + 12) | 0 : 0) | 0;\n        }\n        function gi(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function hi(a) {\n            a = a | 0;\n            return;\n        }\n        function ii(b, d) {\n            b = b | 0;\n            d = d | 0;\n            Md(b);\n            c[b >> 2] = 5172;\n            c[(b + 4) >> 2] = d;\n            c[(b + 8) >> 2] = 0;\n            c[(b + 12) >> 2] = 0;\n            c[(b + 16) >> 2] = 0;\n            a[(b + 20) >> 0] = 1;\n            return;\n        }\n        function ji(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5192;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            pi(a, e);\n            V = d;\n            return;\n        }\n        function ki(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            k = V;\n            V = (V + 16) | 0;\n            h = k;\n            e = c[(b + 8) >> 2] | 0;\n            i = c[(b + 12) >> 2] | 0;\n            if ((e | 0) != (i | 0)) {\n                j = (h + 4) | 0;\n                do {\n                    f = c[e >> 2] | 0;\n                    c[h >> 2] = f;\n                    g = c[(e + 4) >> 2] | 0;\n                    c[j >> 2] = g;\n                    if (g | 0) {\n                        g = (g + 4) | 0;\n                        c[g >> 2] = (c[g >> 2] | 0) + 1;\n                    }\n                    d = $[c[((c[f >> 2] | 0) + 12) >> 2] & 63](f, d) | 0;\n                    Sd(h);\n                    e = (e + 8) | 0;\n                } while ((e | 0) != (i | 0));\n            }\n            e = (b + 20) | 0;\n            if (a[e >> 0] | 0) {\n                a[e >> 0] = 0;\n                ni(c[(b + 4) >> 2] | 0);\n            }\n            V = k;\n            return d | 0;\n        }\n        function li(a) {\n            a = a | 0;\n            c[a >> 2] = 5172;\n            Td((a + 8) | 0);\n            Qd(a);\n            return;\n        }\n        function mi(a) {\n            a = a | 0;\n            li(a);\n            jp(a);\n            return;\n        }\n        function ni(a) {\n            a = a | 0;\n            var b = 0;\n            b = ((oi(c[a >> 2] | 0) | 0) & 255) << 24;\n            b = (((oi(c[a >> 2] | 0) | 0) & 255) << 16) | b;\n            b = b | (((oi(c[a >> 2] | 0) | 0) & 255) << 8);\n            c[(a + 4) >> 2] = b | ((oi(c[a >> 2] | 0) | 0) & 255);\n            return;\n        }\n        function oi(b) {\n            b = b | 0;\n            var d = 0, e = 0;\n            d = c[b >> 2] | 0;\n            e = (b + 8) | 0;\n            b = c[e >> 2] | 0;\n            c[e >> 2] = b + 1;\n            return a[(d + b) >> 0] | 0;\n        }\n        function pi(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return;\n        }\n        function qi(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function ri(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 8) >> 2] & 255](a);\n            return;\n        }\n        function si(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 15450 ? (a + 12) | 0 : 0) | 0;\n        }\n        function ti(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function ui(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            j = V;\n            V = (V + 32) | 0;\n            e = (j + 12) | 0;\n            f = j;\n            b = (j + 8) | 0;\n            h = eq(180) | 0;\n            wi(h, c[(a + 4) >> 2] | 0);\n            g = (a + 8) | 0;\n            c[b >> 2] = 0;\n            c[e >> 2] = c[b >> 2];\n            xi(f, h, e);\n            h = (a + 12) | 0;\n            b = c[h >> 2] | 0;\n            i = (a + 16) | 0;\n            do\n                if (b >>> 0 >= (c[i >> 2] | 0) >>> 0) {\n                    b = (((b - (c[g >> 2] | 0)) >> 3) + 1) | 0;\n                    d = ee(g) | 0;\n                    if (d >>> 0 < b >>> 0)\n                        cr(g);\n                    else {\n                        k = c[g >> 2] | 0;\n                        l = ((c[i >> 2] | 0) - k) | 0;\n                        i = l >> 2;\n                        be(e, (l >> 3) >>> 0 < (d >>> 1) >>> 0 ? (i >>> 0 < b >>> 0 ? b : i) : d, ((c[h >> 2] | 0) - k) >> 3, (a + 16) | 0);\n                        i = (e + 8) | 0;\n                        h = c[i >> 2] | 0;\n                        c[h >> 2] = c[f >> 2];\n                        a = (f + 4) | 0;\n                        c[(h + 4) >> 2] = c[a >> 2];\n                        c[f >> 2] = 0;\n                        c[a >> 2] = 0;\n                        c[i >> 2] = h + 8;\n                        ce(g, e);\n                        de(e);\n                        break;\n                    }\n                }\n                else {\n                    $d(e, g, 1);\n                    l = (e + 4) | 0;\n                    k = c[l >> 2] | 0;\n                    c[k >> 2] = c[f >> 2];\n                    i = (f + 4) | 0;\n                    c[(k + 4) >> 2] = c[i >> 2];\n                    c[f >> 2] = 0;\n                    c[i >> 2] = 0;\n                    c[l >> 2] = k + 8;\n                    ae(e);\n                }\n            while (0);\n            Sd(f);\n            V = j;\n            return;\n        }\n        function vi(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            j = V;\n            V = (V + 32) | 0;\n            e = (j + 12) | 0;\n            f = j;\n            b = (j + 8) | 0;\n            h = eq(180) | 0;\n            Ui(h, c[(a + 4) >> 2] | 0);\n            g = (a + 8) | 0;\n            c[b >> 2] = 0;\n            c[e >> 2] = c[b >> 2];\n            Vi(f, h, e);\n            h = (a + 12) | 0;\n            b = c[h >> 2] | 0;\n            i = (a + 16) | 0;\n            do\n                if (b >>> 0 >= (c[i >> 2] | 0) >>> 0) {\n                    b = (((b - (c[g >> 2] | 0)) >> 3) + 1) | 0;\n                    d = ee(g) | 0;\n                    if (d >>> 0 < b >>> 0)\n                        cr(g);\n                    else {\n                        k = c[g >> 2] | 0;\n                        l = ((c[i >> 2] | 0) - k) | 0;\n                        i = l >> 2;\n                        be(e, (l >> 3) >>> 0 < (d >>> 1) >>> 0 ? (i >>> 0 < b >>> 0 ? b : i) : d, ((c[h >> 2] | 0) - k) >> 3, (a + 16) | 0);\n                        i = (e + 8) | 0;\n                        h = c[i >> 2] | 0;\n                        c[h >> 2] = c[f >> 2];\n                        a = (f + 4) | 0;\n                        c[(h + 4) >> 2] = c[a >> 2];\n                        c[f >> 2] = 0;\n                        c[a >> 2] = 0;\n                        c[i >> 2] = h + 8;\n                        ce(g, e);\n                        de(e);\n                        break;\n                    }\n                }\n                else {\n                    $d(e, g, 1);\n                    l = (e + 4) | 0;\n                    k = c[l >> 2] | 0;\n                    c[k >> 2] = c[f >> 2];\n                    i = (f + 4) | 0;\n                    c[(k + 4) >> 2] = c[i >> 2];\n                    c[f >> 2] = 0;\n                    c[i >> 2] = 0;\n                    c[l >> 2] = k + 8;\n                    ae(e);\n                }\n            while (0);\n            Sd(f);\n            V = j;\n            return;\n        }\n        function wi(a, b) {\n            a = a | 0;\n            b = b | 0;\n            fe(a);\n            c[a >> 2] = 5220;\n            c[(a + 4) >> 2] = b;\n            yi((a + 8) | 0);\n            return;\n        }\n        function xi(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5244;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xe(a, e);\n            V = d;\n            return;\n        }\n        function yi(b) {\n            b = b | 0;\n            xe(b, 32, 1, 8, 0);\n            mc((b + 80) | 0, 32, 1, 8, 0);\n            a[(b + 160) >> 0] = 0;\n            a[(b + 161) >> 0] = 0;\n            Ci((b + 164) | 0);\n            return;\n        }\n        function zi(a) {\n            a = a | 0;\n            c[a >> 2] = 5220;\n            Di((a + 8) | 0);\n            le(a);\n            return;\n        }\n        function Ai(a) {\n            a = a | 0;\n            zi(a);\n            jp(a);\n            return;\n        }\n        function Bi(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return Ei((a + 8) | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function Ci(b) {\n            b = b | 0;\n            a[(b + 4) >> 0] = 0;\n            return;\n        }\n        function Di(a) {\n            a = a | 0;\n            qc((a + 80) | 0);\n            ye(a);\n            return;\n        }\n        function Ei(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0;\n            h = V;\n            V = (V + 16) | 0;\n            f = h;\n            if (!(a[(b + 161) >> 0] | 0))\n                oc((b + 80) | 0);\n            g = (b + 164) | 0;\n            if (Fi(g) | 0) {\n                d = Gi((b + 80) | 0, d, c[g >> 2] | 0, 0) | 0;\n                c[f >> 2] = d;\n                Se(d, e);\n            }\n            else {\n                Ii(Hi(d) | 0, e, 4);\n                c[f >> 2] = Ne(e) | 0;\n            }\n            Ji(g, f);\n            V = h;\n            return (e + 4) | 0;\n        }\n        function Fi(b) {\n            b = b | 0;\n            return ((a[(b + 4) >> 0] | 0) != 0) | 0;\n        }\n        function Gi(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            d = ((Ki(a, b, ((c[(a + 36) >> 2] | 0) + ((e * 44) | 0)) | 0) | 0) + d) | 0;\n            b = c[(a + 24) >> 2] | 0;\n            if ((d | 0) < 0)\n                return (d + b) | 0;\n            else\n                return (d - (d >>> 0 < b >>> 0 ? 0 : b)) | 0;\n            return 0;\n        }\n        function Hi(a) {\n            a = a | 0;\n            return c[a >> 2] | 0;\n        }\n        function Ii(b, c, d) {\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            var e = 0;\n            if ((d | 0) > 0) {\n                e = 0;\n                do {\n                    a[(c + e) >> 0] = oi(b) | 0;\n                    e = (e + 1) | 0;\n                } while ((e | 0) != (d | 0));\n            }\n            return;\n        }\n        function Ji(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0;\n            e = (b + 4) | 0;\n            if (!(a[e >> 0] | 0))\n                a[e >> 0] = 1;\n            c[b >> 2] = c[d >> 2];\n            return;\n        }\n        function Ki(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0;\n            d = Li(b, d) | 0;\n            c[a >> 2] = d;\n            do\n                if (d) {\n                    if (d >>> 0 >= 32) {\n                        d = c[(a + 28) >> 2] | 0;\n                        break;\n                    }\n                    e = c[(a + 12) >> 2] | 0;\n                    if (d >>> 0 > e >>> 0) {\n                        e = (d - e) | 0;\n                        d = Li(b, ((c[(a + 68) >> 2] | 0) + ((((d + -1) | 0) * 44) | 0)) | 0) | 0;\n                        e = (d << e) | (Mi(b, e) | 0);\n                    }\n                    else\n                        e = Li(b, ((c[(a + 68) >> 2] | 0) + ((((d + -1) | 0) * 44) | 0)) | 0) | 0;\n                    d = c[a >> 2] | 0;\n                    if ((e | 0) < ((1 << (d + -1)) | 0)) {\n                        d = (e + 1 + (-1 << d)) | 0;\n                        break;\n                    }\n                    else {\n                        d = (e + 1) | 0;\n                        break;\n                    }\n                }\n                else\n                    d = Ni(b, (a + 48) | 0) | 0;\n            while (0);\n            return d | 0;\n        }\n        function Li(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0;\n            n = (a + 8) | 0;\n            m = c[n >> 2] | 0;\n            f = c[(b + 16) >> 2] | 0;\n            if (f) {\n                e = (a + 4) | 0;\n                d = c[e >> 2] | 0;\n                l = m >>> 15;\n                c[n >> 2] = l;\n                j = ((d >>> 0) / (l >>> 0)) | 0;\n                i = j >>> (c[(b + 40) >> 2] | 0);\n                g = c[(f + (i << 2)) >> 2] | 0;\n                i = ((c[(f + ((i + 1) << 2)) >> 2] | 0) + 1) | 0;\n                h = (g + 1) | 0;\n                k = c[(b + 8) >> 2] | 0;\n                if (i >>> 0 > h >>> 0) {\n                    f = g;\n                    g = i;\n                    do {\n                        h = ((g + f) | 0) >>> 1;\n                        i = (c[(k + (h << 2)) >> 2] | 0) >>> 0 > j >>> 0;\n                        f = i ? f : h;\n                        g = i ? h : g;\n                        h = (f + 1) | 0;\n                    } while (g >>> 0 > h >>> 0);\n                    g = f;\n                }\n                f = q(c[(k + (g << 2)) >> 2] | 0, l) | 0;\n                if ((g | 0) == (c[(b + 32) >> 2] | 0))\n                    h = m;\n                else\n                    h = q(c[(k + (h << 2)) >> 2] | 0, l) | 0;\n            }\n            else {\n                k = m >>> 15;\n                c[n >> 2] = k;\n                i = c[b >> 2] | 0;\n                l = c[(b + 8) >> 2] | 0;\n                e = (a + 4) | 0;\n                d = c[e >> 2] | 0;\n                j = i >>> 1;\n                f = 0;\n                h = m;\n                g = 0;\n                do {\n                    o = q(c[(l + (j << 2)) >> 2] | 0, k) | 0;\n                    m = o >>> 0 > d >>> 0;\n                    h = m ? o : h;\n                    f = m ? f : o;\n                    g = m ? g : j;\n                    i = m ? j : i;\n                    j = ((g + i) | 0) >>> 1;\n                } while ((j | 0) != (g | 0));\n            }\n            c[e >> 2] = d - f;\n            o = (h - f) | 0;\n            c[n >> 2] = o;\n            if (o >>> 0 < 16777216)\n                Oi(a);\n            n = ((c[(b + 12) >> 2] | 0) + (g << 2)) | 0;\n            c[n >> 2] = (c[n >> 2] | 0) + 1;\n            n = (b + 28) | 0;\n            o = ((c[n >> 2] | 0) + -1) | 0;\n            c[n >> 2] = o;\n            if (!o)\n                Xc(b);\n            return g | 0;\n        }\n        function Mi(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0;\n            if (b >>> 0 > 19) {\n                d = (Pi(a) | 0) & 65535;\n                return ((Mi(a, (b + -16) | 0) | 0) << 16) | d | 0;\n            }\n            e = (a + 4) | 0;\n            f = c[e >> 2] | 0;\n            g = (a + 8) | 0;\n            d = (c[g >> 2] | 0) >>> b;\n            c[g >> 2] = d;\n            b = ((f >>> 0) / (d >>> 0)) | 0;\n            c[e >> 2] = f - (q(b, d) | 0);\n            if (d >>> 0 < 16777216)\n                Oi(a);\n            return b | 0;\n        }\n        function Ni(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0;\n            e = (a + 8) | 0;\n            f = c[e >> 2] | 0;\n            d = q(f >>> 13, c[(b + 8) >> 2] | 0) | 0;\n            g = (a + 4) | 0;\n            h = c[g >> 2] | 0;\n            i = h >>> 0 >= d >>> 0;\n            if (i) {\n                c[g >> 2] = h - d;\n                d = (f - d) | 0;\n                c[e >> 2] = d;\n            }\n            else {\n                c[e >> 2] = d;\n                h = (b + 12) | 0;\n                c[h >> 2] = (c[h >> 2] | 0) + 1;\n            }\n            if (d >>> 0 < 16777216)\n                Oi(a);\n            h = (b + 4) | 0;\n            a = ((c[h >> 2] | 0) + -1) | 0;\n            c[h >> 2] = a;\n            if (!a)\n                cd(b);\n            return (i & 1) | 0;\n        }\n        function Oi(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            b = (a + 4) | 0;\n            d = (a + 8) | 0;\n            e = c[b >> 2] | 0;\n            do {\n                e = (e << 8) | ((oi(c[a >> 2] | 0) | 0) & 255);\n                c[b >> 2] = e;\n                f = c[d >> 2] << 8;\n                c[d >> 2] = f;\n            } while (f >>> 0 < 16777216);\n            return;\n        }\n        function Pi(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            d = (a + 4) | 0;\n            f = c[d >> 2] | 0;\n            b = (a + 8) | 0;\n            e = (c[b >> 2] | 0) >>> 16;\n            c[b >> 2] = e;\n            b = ((f >>> 0) / (e >>> 0)) | 0;\n            c[d >> 2] = f - (q(b, e) | 0);\n            Oi(a);\n            return (b & 65535) | 0;\n        }\n        function Qi(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Ri(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 4) >> 2] & 255](a);\n            return;\n        }\n        function Si(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 15904 ? (a + 12) | 0 : 0) | 0;\n        }\n        function Ti(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Ui(a, b) {\n            a = a | 0;\n            b = b | 0;\n            fe(a);\n            c[a >> 2] = 5272;\n            c[(a + 4) >> 2] = b;\n            Wi((a + 8) | 0);\n            return;\n        }\n        function Vi(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5296;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xe(a, e);\n            V = d;\n            return;\n        }\n        function Wi(b) {\n            b = b | 0;\n            xe(b, 32, 1, 8, 0);\n            mc((b + 80) | 0, 32, 1, 8, 0);\n            a[(b + 160) >> 0] = 0;\n            a[(b + 161) >> 0] = 0;\n            _i((b + 164) | 0);\n            return;\n        }\n        function Xi(a) {\n            a = a | 0;\n            c[a >> 2] = 5272;\n            $i((a + 8) | 0);\n            le(a);\n            return;\n        }\n        function Yi(a) {\n            a = a | 0;\n            Xi(a);\n            jp(a);\n            return;\n        }\n        function Zi(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return aj((a + 8) | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function _i(b) {\n            b = b | 0;\n            a[(b + 4) >> 0] = 0;\n            return;\n        }\n        function $i(a) {\n            a = a | 0;\n            qc((a + 80) | 0);\n            ye(a);\n            return;\n        }\n        function aj(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0;\n            h = V;\n            V = (V + 16) | 0;\n            f = h;\n            if (!(a[(b + 161) >> 0] | 0))\n                oc((b + 80) | 0);\n            g = (b + 164) | 0;\n            if (bj(g) | 0) {\n                d = Gi((b + 80) | 0, d, c[g >> 2] | 0, 0) | 0;\n                c[f >> 2] = d;\n                We(d, e);\n            }\n            else {\n                Ii(Hi(d) | 0, e, 4);\n                c[f >> 2] = Re(e) | 0;\n            }\n            cj(g, f);\n            V = h;\n            return (e + 4) | 0;\n        }\n        function bj(b) {\n            b = b | 0;\n            return ((a[(b + 4) >> 0] | 0) != 0) | 0;\n        }\n        function cj(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0;\n            e = (b + 4) | 0;\n            if (!(a[e >> 0] | 0))\n                a[e >> 0] = 1;\n            c[b >> 2] = c[d >> 2];\n            return;\n        }\n        function dj(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function ej(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 4) >> 2] & 255](a);\n            return;\n        }\n        function fj(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 16402 ? (a + 12) | 0 : 0) | 0;\n        }\n        function gj(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function hj(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            j = V;\n            V = (V + 32) | 0;\n            e = (j + 12) | 0;\n            f = j;\n            b = (j + 8) | 0;\n            h = eq(172) | 0;\n            jj(h, c[(a + 4) >> 2] | 0);\n            g = (a + 8) | 0;\n            c[b >> 2] = 0;\n            c[e >> 2] = c[b >> 2];\n            kj(f, h, e);\n            h = (a + 12) | 0;\n            b = c[h >> 2] | 0;\n            i = (a + 16) | 0;\n            do\n                if (b >>> 0 >= (c[i >> 2] | 0) >>> 0) {\n                    b = (((b - (c[g >> 2] | 0)) >> 3) + 1) | 0;\n                    d = ee(g) | 0;\n                    if (d >>> 0 < b >>> 0)\n                        cr(g);\n                    else {\n                        k = c[g >> 2] | 0;\n                        l = ((c[i >> 2] | 0) - k) | 0;\n                        i = l >> 2;\n                        be(e, (l >> 3) >>> 0 < (d >>> 1) >>> 0 ? (i >>> 0 < b >>> 0 ? b : i) : d, ((c[h >> 2] | 0) - k) >> 3, (a + 16) | 0);\n                        i = (e + 8) | 0;\n                        h = c[i >> 2] | 0;\n                        c[h >> 2] = c[f >> 2];\n                        a = (f + 4) | 0;\n                        c[(h + 4) >> 2] = c[a >> 2];\n                        c[f >> 2] = 0;\n                        c[a >> 2] = 0;\n                        c[i >> 2] = h + 8;\n                        ce(g, e);\n                        de(e);\n                        break;\n                    }\n                }\n                else {\n                    $d(e, g, 1);\n                    l = (e + 4) | 0;\n                    k = c[l >> 2] | 0;\n                    c[k >> 2] = c[f >> 2];\n                    i = (f + 4) | 0;\n                    c[(k + 4) >> 2] = c[i >> 2];\n                    c[f >> 2] = 0;\n                    c[i >> 2] = 0;\n                    c[l >> 2] = k + 8;\n                    ae(e);\n                }\n            while (0);\n            Sd(f);\n            V = j;\n            return;\n        }\n        function ij(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            j = V;\n            V = (V + 32) | 0;\n            e = (j + 12) | 0;\n            f = j;\n            b = (j + 8) | 0;\n            h = eq(176) | 0;\n            Aj(h, c[(a + 4) >> 2] | 0);\n            g = (a + 8) | 0;\n            c[b >> 2] = 0;\n            c[e >> 2] = c[b >> 2];\n            Bj(f, h, e);\n            h = (a + 12) | 0;\n            b = c[h >> 2] | 0;\n            i = (a + 16) | 0;\n            do\n                if (b >>> 0 >= (c[i >> 2] | 0) >>> 0) {\n                    b = (((b - (c[g >> 2] | 0)) >> 3) + 1) | 0;\n                    d = ee(g) | 0;\n                    if (d >>> 0 < b >>> 0)\n                        cr(g);\n                    else {\n                        k = c[g >> 2] | 0;\n                        l = ((c[i >> 2] | 0) - k) | 0;\n                        i = l >> 2;\n                        be(e, (l >> 3) >>> 0 < (d >>> 1) >>> 0 ? (i >>> 0 < b >>> 0 ? b : i) : d, ((c[h >> 2] | 0) - k) >> 3, (a + 16) | 0);\n                        i = (e + 8) | 0;\n                        h = c[i >> 2] | 0;\n                        c[h >> 2] = c[f >> 2];\n                        a = (f + 4) | 0;\n                        c[(h + 4) >> 2] = c[a >> 2];\n                        c[f >> 2] = 0;\n                        c[a >> 2] = 0;\n                        c[i >> 2] = h + 8;\n                        ce(g, e);\n                        de(e);\n                        break;\n                    }\n                }\n                else {\n                    $d(e, g, 1);\n                    l = (e + 4) | 0;\n                    k = c[l >> 2] | 0;\n                    c[k >> 2] = c[f >> 2];\n                    i = (f + 4) | 0;\n                    c[(k + 4) >> 2] = c[i >> 2];\n                    c[f >> 2] = 0;\n                    c[i >> 2] = 0;\n                    c[l >> 2] = k + 8;\n                    ae(e);\n                }\n            while (0);\n            Sd(f);\n            V = j;\n            return;\n        }\n        function jj(a, b) {\n            a = a | 0;\n            b = b | 0;\n            fe(a);\n            c[a >> 2] = 5324;\n            c[(a + 4) >> 2] = b;\n            lj((a + 8) | 0);\n            return;\n        }\n        function kj(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5348;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xe(a, e);\n            V = d;\n            return;\n        }\n        function lj(b) {\n            b = b | 0;\n            xe(b, 8, 1, 8, 0);\n            mc((b + 80) | 0, 8, 1, 8, 0);\n            a[(b + 160) >> 0] = 0;\n            a[(b + 161) >> 0] = 0;\n            pj((b + 162) | 0);\n            return;\n        }\n        function mj(a) {\n            a = a | 0;\n            c[a >> 2] = 5324;\n            qj((a + 8) | 0);\n            le(a);\n            return;\n        }\n        function nj(a) {\n            a = a | 0;\n            mj(a);\n            jp(a);\n            return;\n        }\n        function oj(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return rj((a + 8) | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function pj(b) {\n            b = b | 0;\n            a[(b + 1) >> 0] = 0;\n            return;\n        }\n        function qj(a) {\n            a = a | 0;\n            qc((a + 80) | 0);\n            ye(a);\n            return;\n        }\n        function rj(b, c, d) {\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0;\n            g = V;\n            V = (V + 16) | 0;\n            e = g;\n            if (!(a[(b + 161) >> 0] | 0))\n                oc((b + 80) | 0);\n            f = (b + 162) | 0;\n            if (sj(f) | 0) {\n                c = (Gi((b + 80) | 0, c, a[f >> 0] | 0, 0) | 0) & 255;\n                a[e >> 0] = c;\n                tj(c, d);\n            }\n            else {\n                Ii(Hi(c) | 0, d, 1);\n                a[e >> 0] = uj(d) | 0;\n            }\n            vj(f, e);\n            V = g;\n            return (d + 1) | 0;\n        }\n        function sj(b) {\n            b = b | 0;\n            return ((a[(b + 1) >> 0] | 0) != 0) | 0;\n        }\n        function tj(b, c) {\n            b = b | 0;\n            c = c | 0;\n            a[c >> 0] = b;\n            return;\n        }\n        function uj(b) {\n            b = b | 0;\n            return a[b >> 0] | 0;\n        }\n        function vj(b, c) {\n            b = b | 0;\n            c = c | 0;\n            var d = 0;\n            d = (b + 1) | 0;\n            if (!(a[d >> 0] | 0))\n                a[d >> 0] = 1;\n            a[b >> 0] = a[c >> 0] | 0;\n            return;\n        }\n        function wj(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function xj(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 4) >> 2] & 255](a);\n            return;\n        }\n        function yj(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 16900 ? (a + 12) | 0 : 0) | 0;\n        }\n        function zj(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Aj(a, b) {\n            a = a | 0;\n            b = b | 0;\n            fe(a);\n            c[a >> 2] = 5376;\n            c[(a + 4) >> 2] = b;\n            Cj((a + 8) | 0);\n            return;\n        }\n        function Bj(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5400;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xe(a, e);\n            V = d;\n            return;\n        }\n        function Cj(b) {\n            b = b | 0;\n            xe(b, 16, 1, 8, 0);\n            mc((b + 80) | 0, 16, 1, 8, 0);\n            a[(b + 160) >> 0] = 0;\n            a[(b + 161) >> 0] = 0;\n            Gj((b + 162) | 0);\n            return;\n        }\n        function Dj(a) {\n            a = a | 0;\n            c[a >> 2] = 5376;\n            Hj((a + 8) | 0);\n            le(a);\n            return;\n        }\n        function Ej(a) {\n            a = a | 0;\n            Dj(a);\n            jp(a);\n            return;\n        }\n        function Fj(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return Ij((a + 8) | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function Gj(b) {\n            b = b | 0;\n            a[(b + 2) >> 0] = 0;\n            return;\n        }\n        function Hj(a) {\n            a = a | 0;\n            qc((a + 80) | 0);\n            ye(a);\n            return;\n        }\n        function Ij(c, d, e) {\n            c = c | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0;\n            h = V;\n            V = (V + 16) | 0;\n            f = h;\n            if (!(a[(c + 161) >> 0] | 0))\n                oc((c + 80) | 0);\n            g = (c + 162) | 0;\n            if (Jj(g) | 0) {\n                d = (Gi((c + 80) | 0, d, b[g >> 1] | 0, 0) | 0) & 65535;\n                b[f >> 1] = d;\n                Kj(d, e);\n            }\n            else {\n                Ii(Hi(d) | 0, e, 2);\n                b[f >> 1] = Lj(e) | 0;\n            }\n            Mj(g, f);\n            V = h;\n            return (e + 2) | 0;\n        }\n        function Jj(b) {\n            b = b | 0;\n            return ((a[(b + 2) >> 0] | 0) != 0) | 0;\n        }\n        function Kj(a, b) {\n            a = a | 0;\n            b = b | 0;\n            Te(a, b);\n            return;\n        }\n        function Lj(a) {\n            a = a | 0;\n            return Oe(a) | 0;\n        }\n        function Mj(c, d) {\n            c = c | 0;\n            d = d | 0;\n            var e = 0;\n            e = (c + 2) | 0;\n            if (!(a[e >> 0] | 0))\n                a[e >> 0] = 1;\n            b[c >> 1] = b[d >> 1] | 0;\n            return;\n        }\n        function Nj(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function Oj(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 4) >> 2] & 255](a);\n            return;\n        }\n        function Pj(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 17398 ? (a + 12) | 0 : 0) | 0;\n        }\n        function Qj(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function Rj(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            j = V;\n            V = (V + 32) | 0;\n            e = (j + 12) | 0;\n            f = j;\n            b = (j + 8) | 0;\n            h = eq(172) | 0;\n            Tj(h, c[(a + 4) >> 2] | 0);\n            g = (a + 8) | 0;\n            c[b >> 2] = 0;\n            c[e >> 2] = c[b >> 2];\n            Uj(f, h, e);\n            h = (a + 12) | 0;\n            b = c[h >> 2] | 0;\n            i = (a + 16) | 0;\n            do\n                if (b >>> 0 >= (c[i >> 2] | 0) >>> 0) {\n                    b = (((b - (c[g >> 2] | 0)) >> 3) + 1) | 0;\n                    d = ee(g) | 0;\n                    if (d >>> 0 < b >>> 0)\n                        cr(g);\n                    else {\n                        k = c[g >> 2] | 0;\n                        l = ((c[i >> 2] | 0) - k) | 0;\n                        i = l >> 2;\n                        be(e, (l >> 3) >>> 0 < (d >>> 1) >>> 0 ? (i >>> 0 < b >>> 0 ? b : i) : d, ((c[h >> 2] | 0) - k) >> 3, (a + 16) | 0);\n                        i = (e + 8) | 0;\n                        h = c[i >> 2] | 0;\n                        c[h >> 2] = c[f >> 2];\n                        a = (f + 4) | 0;\n                        c[(h + 4) >> 2] = c[a >> 2];\n                        c[f >> 2] = 0;\n                        c[a >> 2] = 0;\n                        c[i >> 2] = h + 8;\n                        ce(g, e);\n                        de(e);\n                        break;\n                    }\n                }\n                else {\n                    $d(e, g, 1);\n                    l = (e + 4) | 0;\n                    k = c[l >> 2] | 0;\n                    c[k >> 2] = c[f >> 2];\n                    i = (f + 4) | 0;\n                    c[(k + 4) >> 2] = c[i >> 2];\n                    c[f >> 2] = 0;\n                    c[i >> 2] = 0;\n                    c[l >> 2] = k + 8;\n                    ae(e);\n                }\n            while (0);\n            Sd(f);\n            V = j;\n            return;\n        }\n        function Sj(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            j = V;\n            V = (V + 32) | 0;\n            e = (j + 12) | 0;\n            f = j;\n            b = (j + 8) | 0;\n            h = eq(176) | 0;\n            gk(h, c[(a + 4) >> 2] | 0);\n            g = (a + 8) | 0;\n            c[b >> 2] = 0;\n            c[e >> 2] = c[b >> 2];\n            hk(f, h, e);\n            h = (a + 12) | 0;\n            b = c[h >> 2] | 0;\n            i = (a + 16) | 0;\n            do\n                if (b >>> 0 >= (c[i >> 2] | 0) >>> 0) {\n                    b = (((b - (c[g >> 2] | 0)) >> 3) + 1) | 0;\n                    d = ee(g) | 0;\n                    if (d >>> 0 < b >>> 0)\n                        cr(g);\n                    else {\n                        k = c[g >> 2] | 0;\n                        l = ((c[i >> 2] | 0) - k) | 0;\n                        i = l >> 2;\n                        be(e, (l >> 3) >>> 0 < (d >>> 1) >>> 0 ? (i >>> 0 < b >>> 0 ? b : i) : d, ((c[h >> 2] | 0) - k) >> 3, (a + 16) | 0);\n                        i = (e + 8) | 0;\n                        h = c[i >> 2] | 0;\n                        c[h >> 2] = c[f >> 2];\n                        a = (f + 4) | 0;\n                        c[(h + 4) >> 2] = c[a >> 2];\n                        c[f >> 2] = 0;\n                        c[a >> 2] = 0;\n                        c[i >> 2] = h + 8;\n                        ce(g, e);\n                        de(e);\n                        break;\n                    }\n                }\n                else {\n                    $d(e, g, 1);\n                    l = (e + 4) | 0;\n                    k = c[l >> 2] | 0;\n                    c[k >> 2] = c[f >> 2];\n                    i = (f + 4) | 0;\n                    c[(k + 4) >> 2] = c[i >> 2];\n                    c[f >> 2] = 0;\n                    c[i >> 2] = 0;\n                    c[l >> 2] = k + 8;\n                    ae(e);\n                }\n            while (0);\n            Sd(f);\n            V = j;\n            return;\n        }\n        function Tj(a, b) {\n            a = a | 0;\n            b = b | 0;\n            fe(a);\n            c[a >> 2] = 5428;\n            c[(a + 4) >> 2] = b;\n            Vj((a + 8) | 0);\n            return;\n        }\n        function Uj(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5452;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xe(a, e);\n            V = d;\n            return;\n        }\n        function Vj(b) {\n            b = b | 0;\n            xe(b, 8, 1, 8, 0);\n            mc((b + 80) | 0, 8, 1, 8, 0);\n            a[(b + 160) >> 0] = 0;\n            a[(b + 161) >> 0] = 0;\n            Zj((b + 162) | 0);\n            return;\n        }\n        function Wj(a) {\n            a = a | 0;\n            c[a >> 2] = 5428;\n            _j((a + 8) | 0);\n            le(a);\n            return;\n        }\n        function Xj(a) {\n            a = a | 0;\n            Wj(a);\n            jp(a);\n            return;\n        }\n        function Yj(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return $j((a + 8) | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function Zj(b) {\n            b = b | 0;\n            a[(b + 1) >> 0] = 0;\n            return;\n        }\n        function _j(a) {\n            a = a | 0;\n            qc((a + 80) | 0);\n            ye(a);\n            return;\n        }\n        function $j(b, c, e) {\n            b = b | 0;\n            c = c | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0;\n            h = V;\n            V = (V + 16) | 0;\n            f = h;\n            if (!(a[(b + 161) >> 0] | 0))\n                oc((b + 80) | 0);\n            g = (b + 162) | 0;\n            if (ak(g) | 0) {\n                c = (Gi((b + 80) | 0, c, d[g >> 0] | 0, 0) | 0) & 255;\n                a[f >> 0] = c;\n                Ue(c, e);\n            }\n            else {\n                Ii(Hi(c) | 0, e, 1);\n                a[f >> 0] = Pe(e) | 0;\n            }\n            bk(g, f);\n            V = h;\n            return (e + 1) | 0;\n        }\n        function ak(b) {\n            b = b | 0;\n            return ((a[(b + 1) >> 0] | 0) != 0) | 0;\n        }\n        function bk(b, c) {\n            b = b | 0;\n            c = c | 0;\n            var d = 0;\n            d = (b + 1) | 0;\n            if (!(a[d >> 0] | 0))\n                a[d >> 0] = 1;\n            a[b >> 0] = a[c >> 0] | 0;\n            return;\n        }\n        function ck(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function dk(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 4) >> 2] & 255](a);\n            return;\n        }\n        function ek(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 17896 ? (a + 12) | 0 : 0) | 0;\n        }\n        function fk(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function gk(a, b) {\n            a = a | 0;\n            b = b | 0;\n            fe(a);\n            c[a >> 2] = 5480;\n            c[(a + 4) >> 2] = b;\n            ik((a + 8) | 0);\n            return;\n        }\n        function hk(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            c[a >> 2] = b;\n            f = eq(16) | 0;\n            c[(f + 4) >> 2] = 0;\n            c[(f + 8) >> 2] = 0;\n            c[f >> 2] = 5504;\n            c[(f + 12) >> 2] = b;\n            c[(a + 4) >> 2] = f;\n            c[e >> 2] = b;\n            c[(e + 4) >> 2] = b;\n            Xe(a, e);\n            V = d;\n            return;\n        }\n        function ik(b) {\n            b = b | 0;\n            xe(b, 16, 1, 8, 0);\n            mc((b + 80) | 0, 16, 1, 8, 0);\n            a[(b + 160) >> 0] = 0;\n            a[(b + 161) >> 0] = 0;\n            mk((b + 162) | 0);\n            return;\n        }\n        function jk(a) {\n            a = a | 0;\n            c[a >> 2] = 5480;\n            nk((a + 8) | 0);\n            le(a);\n            return;\n        }\n        function kk(a) {\n            a = a | 0;\n            jk(a);\n            jp(a);\n            return;\n        }\n        function lk(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ok((a + 8) | 0, c[(a + 4) >> 2] | 0, b) | 0;\n        }\n        function mk(b) {\n            b = b | 0;\n            a[(b + 2) >> 0] = 0;\n            return;\n        }\n        function nk(a) {\n            a = a | 0;\n            qc((a + 80) | 0);\n            ye(a);\n            return;\n        }\n        function ok(c, d, f) {\n            c = c | 0;\n            d = d | 0;\n            f = f | 0;\n            var g = 0, h = 0, i = 0;\n            i = V;\n            V = (V + 16) | 0;\n            g = i;\n            if (!(a[(c + 161) >> 0] | 0))\n                oc((c + 80) | 0);\n            h = (c + 162) | 0;\n            if (pk(h) | 0) {\n                d = (Gi((c + 80) | 0, d, e[h >> 1] | 0, 0) | 0) & 65535;\n                b[g >> 1] = d;\n                Te(d, f);\n            }\n            else {\n                Ii(Hi(d) | 0, f, 2);\n                b[g >> 1] = Oe(f) | 0;\n            }\n            qk(h, g);\n            V = i;\n            return (f + 2) | 0;\n        }\n        function pk(b) {\n            b = b | 0;\n            return ((a[(b + 2) >> 0] | 0) != 0) | 0;\n        }\n        function qk(c, d) {\n            c = c | 0;\n            d = d | 0;\n            var e = 0;\n            e = (c + 2) | 0;\n            if (!(a[e >> 0] | 0))\n                a[e >> 0] = 1;\n            b[c >> 1] = b[d >> 1] | 0;\n            return;\n        }\n        function rk(a) {\n            a = a | 0;\n            pq(a);\n            jp(a);\n            return;\n        }\n        function sk(a) {\n            a = a | 0;\n            a = c[(a + 12) >> 2] | 0;\n            if (a | 0)\n                ca[c[((c[a >> 2] | 0) + 4) >> 2] & 255](a);\n            return;\n        }\n        function tk(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ((c[(b + 4) >> 2] | 0) == 18394 ? (a + 12) | 0 : 0) | 0;\n        }\n        function uk(a) {\n            a = a | 0;\n            Da(a, 16);\n            return;\n        }\n        function vk() {\n            return;\n        }\n        function wk(a) {\n            a = a | 0;\n            return Ek(a) | 0;\n        }\n        function xk() {\n            return 0;\n        }\n        function yk() {\n            return 0;\n        }\n        function zk(a) {\n            a = a | 0;\n            if (a | 0) {\n                Fk(a);\n                jp(a);\n            }\n            return;\n        }\n        function Ak() {\n            return Gk() | 0;\n        }\n        function Bk() {\n            return Hk() | 0;\n        }\n        function Ck() {\n            return Ik() | 0;\n        }\n        function Dk() {\n            return 0;\n        }\n        function Ek(a) {\n            a = a | 0;\n            return 3360;\n        }\n        function Fk(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            b = V;\n            V = (V + 16) | 0;\n            e = b;\n            c[e >> 2] = c[a >> 2];\n            c[a >> 2] = 0;\n            d = (a + 4) | 0;\n            c[(e + 4) >> 2] = c[d >> 2];\n            c[d >> 2] = 0;\n            wa(e);\n            d = (a + 8) | 0;\n            c[e >> 2] = c[d >> 2];\n            c[d >> 2] = 0;\n            f = (a + 12) | 0;\n            c[(e + 4) >> 2] = c[f >> 2];\n            c[f >> 2] = 0;\n            Ga(e);\n            Ga(d);\n            wa(a);\n            V = b;\n            return;\n        }\n        function Gk() {\n            return 3360;\n        }\n        function Hk() {\n            return 3368;\n        }\n        function Ik() {\n            return 3384;\n        }\n        function Jk() {\n            return 18579;\n        }\n        function Kk() {\n            return 18582;\n        }\n        function Lk() {\n            return 18584;\n        }\n        function Mk() {\n            var a = 0;\n            a = eq(16) | 0;\n            Tk(a);\n            return a | 0;\n        }\n        function Nk(a) {\n            a = a | 0;\n            var b = 0, c = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            c = b;\n            e = Ak() | 0;\n            d = Pk(c) | 0;\n            c = Qk(c) | 0;\n            E(e | 0, d | 0, c | 0, Jk() | 0, 12, a | 0);\n            V = b;\n            return;\n        }\n        function Ok(a) {\n            a = a | 0;\n            return Rk(Y[a & 3]() | 0) | 0;\n        }\n        function Pk(a) {\n            a = a | 0;\n            return 1;\n        }\n        function Qk(a) {\n            a = a | 0;\n            return Sk() | 0;\n        }\n        function Rk(a) {\n            a = a | 0;\n            return a | 0;\n        }\n        function Sk() {\n            return 5524;\n        }\n        function Tk(a) {\n            a = a | 0;\n            c[a >> 2] = 0;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = 0;\n            c[(a + 12) >> 2] = 0;\n            return;\n        }\n        function Uk(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            f = (d + 8) | 0;\n            h = c[(b + 4) >> 2] | 0;\n            c[e >> 2] = c[b >> 2];\n            c[(e + 4) >> 2] = h;\n            h = Ak() | 0;\n            g = Wk(f) | 0;\n            f = Xk(f) | 0;\n            b = bl() | 0;\n            F(h | 0, a | 0, g | 0, f | 0, b | 0, 4, Yk(e) | 0, 0);\n            V = d;\n            return;\n        }\n        function Vk(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0;\n            g = Zk(b) | 0;\n            b = c[a >> 2] | 0;\n            f = c[(a + 4) >> 2] | 0;\n            a = (g + (f >> 1)) | 0;\n            if (f & 1)\n                b = c[((c[a >> 2] | 0) + b) >> 2] | 0;\n            f = _k(d) | 0;\n            g = $k(e) | 0;\n            ea[b & 15](a, f, g);\n            return;\n        }\n        function Wk(a) {\n            a = a | 0;\n            return 4;\n        }\n        function Xk(a) {\n            a = a | 0;\n            return al() | 0;\n        }\n        function Yk(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = eq(8) | 0;\n            d = c[(a + 4) >> 2] | 0;\n            c[b >> 2] = c[a >> 2];\n            c[(b + 4) >> 2] = d;\n            return b | 0;\n        }\n        function Zk(a) {\n            a = a | 0;\n            return a | 0;\n        }\n        function _k(a) {\n            a = a | 0;\n            return a | 0;\n        }\n        function $k(a) {\n            a = a | 0;\n            return a | 0;\n        }\n        function al() {\n            return 144;\n        }\n        function bl() {\n            return 18587;\n        }\n        function cl(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            f = (d + 8) | 0;\n            h = c[(b + 4) >> 2] | 0;\n            c[e >> 2] = c[b >> 2];\n            c[(e + 4) >> 2] = h;\n            h = Ak() | 0;\n            g = el(f) | 0;\n            f = fl(f) | 0;\n            b = jl() | 0;\n            F(h | 0, a | 0, g | 0, f | 0, b | 0, 7, gl(e) | 0, 0);\n            V = d;\n            return;\n        }\n        function dl(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            f = Zk(b) | 0;\n            b = c[a >> 2] | 0;\n            e = c[(a + 4) >> 2] | 0;\n            a = (f + (e >> 1)) | 0;\n            if (e & 1)\n                b = c[((c[a >> 2] | 0) + b) >> 2] | 0;\n            f = hl(d) | 0;\n            da[b & 15](a, f);\n            return;\n        }\n        function el(a) {\n            a = a | 0;\n            return 3;\n        }\n        function fl(a) {\n            a = a | 0;\n            return il() | 0;\n        }\n        function gl(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = eq(8) | 0;\n            d = c[(a + 4) >> 2] | 0;\n            c[b >> 2] = c[a >> 2];\n            c[(b + 4) >> 2] = d;\n            return b | 0;\n        }\n        function hl(a) {\n            a = a | 0;\n            return a | 0;\n        }\n        function il() {\n            return 5528;\n        }\n        function jl() {\n            return 18593;\n        }\n        function kl(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            f = (d + 8) | 0;\n            h = c[(b + 4) >> 2] | 0;\n            c[e >> 2] = c[b >> 2];\n            c[(e + 4) >> 2] = h;\n            h = Ak() | 0;\n            g = ml(f) | 0;\n            f = nl(f) | 0;\n            b = rl() | 0;\n            F(h | 0, a | 0, g | 0, f | 0, b | 0, 41, ol(e) | 0, 0);\n            V = d;\n            return;\n        }\n        function ll(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0;\n            e = V;\n            V = (V + 16) | 0;\n            d = e;\n            g = Zk(b) | 0;\n            b = c[a >> 2] | 0;\n            f = c[(a + 4) >> 2] | 0;\n            a = (g + (f >> 1)) | 0;\n            if (f & 1)\n                b = c[((c[a >> 2] | 0) + b) >> 2] | 0;\n            c[d >> 2] = Z[b & 15](a) | 0;\n            g = pl(d) | 0;\n            V = e;\n            return g | 0;\n        }\n        function ml(a) {\n            a = a | 0;\n            return 2;\n        }\n        function nl(a) {\n            a = a | 0;\n            return ql() | 0;\n        }\n        function ol(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = eq(8) | 0;\n            d = c[(a + 4) >> 2] | 0;\n            c[b >> 2] = c[a >> 2];\n            c[(b + 4) >> 2] = d;\n            return b | 0;\n        }\n        function pl(a) {\n            a = a | 0;\n            return c[a >> 2] | 0;\n        }\n        function ql() {\n            return 5540;\n        }\n        function rl() {\n            return 18598;\n        }\n        function sl() {\n            return;\n        }\n        function tl(a) {\n            a = a | 0;\n            return Al(a) | 0;\n        }\n        function ul() {\n            return 0;\n        }\n        function vl() {\n            return 0;\n        }\n        function wl(a) {\n            a = a | 0;\n            if (a | 0) {\n                Bl(a);\n                jp(a);\n            }\n            return;\n        }\n        function xl() {\n            return Cl() | 0;\n        }\n        function yl() {\n            return Dl() | 0;\n        }\n        function zl() {\n            return El() | 0;\n        }\n        function Al(a) {\n            a = a | 0;\n            return 3400;\n        }\n        function Bl(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            b = V;\n            V = (V + 16) | 0;\n            e = b;\n            c[e >> 2] = c[a >> 2];\n            c[a >> 2] = 0;\n            d = (a + 4) | 0;\n            c[(e + 4) >> 2] = c[d >> 2];\n            c[d >> 2] = 0;\n            Wh(e);\n            d = (a + 16) | 0;\n            c[e >> 2] = c[d >> 2];\n            c[d >> 2] = 0;\n            f = (a + 20) | 0;\n            c[(e + 4) >> 2] = c[f >> 2];\n            c[f >> 2] = 0;\n            Uh(e);\n            c[e >> 2] = c[d >> 2];\n            c[d >> 2] = 0;\n            c[(e + 4) >> 2] = c[f >> 2];\n            c[f >> 2] = 0;\n            Uh(e);\n            Uh(d);\n            bi((a + 8) | 0);\n            Wh(a);\n            V = b;\n            return;\n        }\n        function Cl() {\n            return 3400;\n        }\n        function Dl() {\n            return 3408;\n        }\n        function El() {\n            return 3424;\n        }\n        function Fl() {\n            var a = 0;\n            a = eq(24) | 0;\n            Ml(a);\n            return a | 0;\n        }\n        function Gl(a) {\n            a = a | 0;\n            var b = 0, c = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            c = b;\n            e = xl() | 0;\n            d = Il(c) | 0;\n            c = Jl(c) | 0;\n            E(e | 0, d | 0, c | 0, Jk() | 0, 13, a | 0);\n            V = b;\n            return;\n        }\n        function Hl(a) {\n            a = a | 0;\n            return Kl(Y[a & 3]() | 0) | 0;\n        }\n        function Il(a) {\n            a = a | 0;\n            return 1;\n        }\n        function Jl(a) {\n            a = a | 0;\n            return Ll() | 0;\n        }\n        function Kl(a) {\n            a = a | 0;\n            return a | 0;\n        }\n        function Ll() {\n            return 5548;\n        }\n        function Ml(a) {\n            a = a | 0;\n            c[a >> 2] = 0;\n            c[(a + 4) >> 2] = 0;\n            c[(a + 8) >> 2] = 0;\n            c[(a + 12) >> 2] = 0;\n            c[(a + 16) >> 2] = 0;\n            c[(a + 20) >> 2] = 0;\n            return;\n        }\n        function Nl(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            f = (d + 8) | 0;\n            h = c[(b + 4) >> 2] | 0;\n            c[e >> 2] = c[b >> 2];\n            c[(e + 4) >> 2] = h;\n            h = xl() | 0;\n            g = Pl(f) | 0;\n            f = Ql(f) | 0;\n            b = bl() | 0;\n            F(h | 0, a | 0, g | 0, f | 0, b | 0, 5, Rl(e) | 0, 0);\n            V = d;\n            return;\n        }\n        function Ol(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0;\n            g = Sl(b) | 0;\n            b = c[a >> 2] | 0;\n            f = c[(a + 4) >> 2] | 0;\n            a = (g + (f >> 1)) | 0;\n            if (f & 1)\n                b = c[((c[a >> 2] | 0) + b) >> 2] | 0;\n            f = _k(d) | 0;\n            g = $k(e) | 0;\n            ea[b & 15](a, f, g);\n            return;\n        }\n        function Pl(a) {\n            a = a | 0;\n            return 4;\n        }\n        function Ql(a) {\n            a = a | 0;\n            return Tl() | 0;\n        }\n        function Rl(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = eq(8) | 0;\n            d = c[(a + 4) >> 2] | 0;\n            c[b >> 2] = c[a >> 2];\n            c[(b + 4) >> 2] = d;\n            return b | 0;\n        }\n        function Sl(a) {\n            a = a | 0;\n            return a | 0;\n        }\n        function Tl() {\n            return 160;\n        }\n        function Ul(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            f = (d + 8) | 0;\n            h = c[(b + 4) >> 2] | 0;\n            c[e >> 2] = c[b >> 2];\n            c[(e + 4) >> 2] = h;\n            h = xl() | 0;\n            g = Wl(f) | 0;\n            f = Xl(f) | 0;\n            b = jl() | 0;\n            F(h | 0, a | 0, g | 0, f | 0, b | 0, 8, Yl(e) | 0, 0);\n            V = d;\n            return;\n        }\n        function Vl(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            f = Sl(b) | 0;\n            b = c[a >> 2] | 0;\n            e = c[(a + 4) >> 2] | 0;\n            a = (f + (e >> 1)) | 0;\n            if (e & 1)\n                b = c[((c[a >> 2] | 0) + b) >> 2] | 0;\n            f = $k(d) | 0;\n            da[b & 15](a, f);\n            return;\n        }\n        function Wl(a) {\n            a = a | 0;\n            return 3;\n        }\n        function Xl(a) {\n            a = a | 0;\n            return Zl() | 0;\n        }\n        function Yl(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = eq(8) | 0;\n            d = c[(a + 4) >> 2] | 0;\n            c[b >> 2] = c[a >> 2];\n            c[(b + 4) >> 2] = d;\n            return b | 0;\n        }\n        function Zl() {\n            return 5552;\n        }\n        function _l(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0;\n            d = V;\n            V = (V + 16) | 0;\n            e = d;\n            f = (d + 8) | 0;\n            h = c[(b + 4) >> 2] | 0;\n            c[e >> 2] = c[b >> 2];\n            c[(e + 4) >> 2] = h;\n            h = xl() | 0;\n            g = am(f) | 0;\n            f = bm(f) | 0;\n            b = jl() | 0;\n            F(h | 0, a | 0, g | 0, f | 0, b | 0, 9, cm(e) | 0, 0);\n            V = d;\n            return;\n        }\n        function $l(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            f = Sl(b) | 0;\n            b = c[a >> 2] | 0;\n            e = c[(a + 4) >> 2] | 0;\n            a = (f + (e >> 1)) | 0;\n            if (e & 1)\n                b = c[((c[a >> 2] | 0) + b) >> 2] | 0;\n            f = hl(d) | 0;\n            da[b & 15](a, f);\n            return;\n        }\n        function am(a) {\n            a = a | 0;\n            return 3;\n        }\n        function bm(a) {\n            a = a | 0;\n            return dm() | 0;\n        }\n        function cm(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = eq(8) | 0;\n            d = c[(a + 4) >> 2] | 0;\n            c[b >> 2] = c[a >> 2];\n            c[(b + 4) >> 2] = d;\n            return b | 0;\n        }\n        function dm() {\n            return 5564;\n        }\n        function em() {\n            ja();\n            return;\n        }\n        function fm() {\n            gm();\n            return;\n        }\n        function gm() {\n            hm(22144);\n            return;\n        }\n        function hm(a) {\n            a = a | 0;\n            var b = 0;\n            b = V;\n            V = (V + 16) | 0;\n            c[b >> 2] = a;\n            im();\n            V = b;\n            return;\n        }\n        function im() {\n            M(jm() | 0, 18653);\n            C(km() | 0, 18658, 1, 1, 0);\n            lm(18663);\n            mm(18668);\n            nm(18680);\n            om(18694);\n            pm(18700);\n            qm(18715);\n            rm(18719);\n            sm(18732);\n            tm(18737);\n            um(18751);\n            vm(18757);\n            K(wm() | 0, 18764);\n            K(xm() | 0, 18776);\n            L(ym() | 0, 4, 18809);\n            L(zm() | 0, 2, 18822);\n            L(Am() | 0, 4, 18837);\n            G(Bm() | 0, 18852);\n            Cm(18868);\n            Dm(18898);\n            Em(18935);\n            Fm(18974);\n            Gm(19005);\n            Hm(19045);\n            Im(19074);\n            Jm(19112);\n            Km(19142);\n            Dm(19181);\n            Em(19213);\n            Fm(19246);\n            Gm(19279);\n            Hm(19313);\n            Im(19346);\n            Lm(19380);\n            Mm(19411);\n            Nm(19443);\n            return;\n        }\n        function jm() {\n            return _n() | 0;\n        }\n        function km() {\n            return Zn() | 0;\n        }\n        function lm(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Xn() | 0;\n            I(a | 0, c[d >> 2] | 0, 1, ((-128 << 24) >> 24) | 0, ((127 << 24) >> 24) | 0);\n            V = b;\n            return;\n        }\n        function mm(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Vn() | 0;\n            I(a | 0, c[d >> 2] | 0, 1, ((-128 << 24) >> 24) | 0, ((127 << 24) >> 24) | 0);\n            V = b;\n            return;\n        }\n        function nm(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Tn() | 0;\n            I(a | 0, c[d >> 2] | 0, 1, 0, 255);\n            V = b;\n            return;\n        }\n        function om(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Rn() | 0;\n            I(a | 0, c[d >> 2] | 0, 2, ((-32768 << 16) >> 16) | 0, ((32767 << 16) >> 16) | 0);\n            V = b;\n            return;\n        }\n        function pm(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Pn() | 0;\n            I(a | 0, c[d >> 2] | 0, 2, 0, 65535);\n            V = b;\n            return;\n        }\n        function qm(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Nn() | 0;\n            I(a | 0, c[d >> 2] | 0, 4, -2147483648, 2147483647);\n            V = b;\n            return;\n        }\n        function rm(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Ln() | 0;\n            I(a | 0, c[d >> 2] | 0, 4, 0, -1);\n            V = b;\n            return;\n        }\n        function sm(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Jn() | 0;\n            I(a | 0, c[d >> 2] | 0, 4, -2147483648, 2147483647);\n            V = b;\n            return;\n        }\n        function tm(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Hn() | 0;\n            I(a | 0, c[d >> 2] | 0, 4, 0, -1);\n            V = b;\n            return;\n        }\n        function um(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Fn() | 0;\n            H(a | 0, c[d >> 2] | 0, 4);\n            V = b;\n            return;\n        }\n        function vm(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            a = Dn() | 0;\n            H(a | 0, c[d >> 2] | 0, 8);\n            V = b;\n            return;\n        }\n        function wm() {\n            return Cn() | 0;\n        }\n        function xm() {\n            return Bn() | 0;\n        }\n        function ym() {\n            return An() | 0;\n        }\n        function zm() {\n            return zn() | 0;\n        }\n        function Am() {\n            return yn() | 0;\n        }\n        function Bm() {\n            return xn() | 0;\n        }\n        function Cm(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = un() | 0;\n            a = vn() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Dm(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = rn() | 0;\n            a = sn() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Em(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = on() | 0;\n            a = pn() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Fm(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = ln() | 0;\n            a = mn() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Gm(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = hn() | 0;\n            a = jn() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Hm(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = en() | 0;\n            a = fn() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Im(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = bn() | 0;\n            a = cn() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Jm(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = _m() | 0;\n            a = $m() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Km(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = Xm() | 0;\n            a = Ym() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Lm(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = Um() | 0;\n            a = Vm() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Mm(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = Rm() | 0;\n            a = Sm() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Nm(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            c[d >> 2] = a;\n            e = Om() | 0;\n            a = Pm() | 0;\n            J(e | 0, a | 0, c[d >> 2] | 0);\n            V = b;\n            return;\n        }\n        function Om() {\n            return Qm() | 0;\n        }\n        function Pm() {\n            return 7;\n        }\n        function Qm() {\n            return 3440;\n        }\n        function Rm() {\n            return Tm() | 0;\n        }\n        function Sm() {\n            return 7;\n        }\n        function Tm() {\n            return 3448;\n        }\n        function Um() {\n            return Wm() | 0;\n        }\n        function Vm() {\n            return 6;\n        }\n        function Wm() {\n            return 3456;\n        }\n        function Xm() {\n            return Zm() | 0;\n        }\n        function Ym() {\n            return 5;\n        }\n        function Zm() {\n            return 3464;\n        }\n        function _m() {\n            return an() | 0;\n        }\n        function $m() {\n            return 4;\n        }\n        function an() {\n            return 3472;\n        }\n        function bn() {\n            return dn() | 0;\n        }\n        function cn() {\n            return 5;\n        }\n        function dn() {\n            return 3480;\n        }\n        function en() {\n            return gn() | 0;\n        }\n        function fn() {\n            return 4;\n        }\n        function gn() {\n            return 3488;\n        }\n        function hn() {\n            return kn() | 0;\n        }\n        function jn() {\n            return 3;\n        }\n        function kn() {\n            return 3496;\n        }\n        function ln() {\n            return nn() | 0;\n        }\n        function mn() {\n            return 2;\n        }\n        function nn() {\n            return 3504;\n        }\n        function on() {\n            return qn() | 0;\n        }\n        function pn() {\n            return 1;\n        }\n        function qn() {\n            return 3512;\n        }\n        function rn() {\n            return tn() | 0;\n        }\n        function sn() {\n            return 0;\n        }\n        function tn() {\n            return 3520;\n        }\n        function un() {\n            return wn() | 0;\n        }\n        function vn() {\n            return 0;\n        }\n        function wn() {\n            return 3528;\n        }\n        function xn() {\n            return 3536;\n        }\n        function yn() {\n            return 3544;\n        }\n        function zn() {\n            return 3576;\n        }\n        function An() {\n            return 3600;\n        }\n        function Bn() {\n            return 3624;\n        }\n        function Cn() {\n            return 3648;\n        }\n        function Dn() {\n            return En() | 0;\n        }\n        function En() {\n            return 4144;\n        }\n        function Fn() {\n            return Gn() | 0;\n        }\n        function Gn() {\n            return 4136;\n        }\n        function Hn() {\n            return In() | 0;\n        }\n        function In() {\n            return 4128;\n        }\n        function Jn() {\n            return Kn() | 0;\n        }\n        function Kn() {\n            return 4120;\n        }\n        function Ln() {\n            return Mn() | 0;\n        }\n        function Mn() {\n            return 4112;\n        }\n        function Nn() {\n            return On() | 0;\n        }\n        function On() {\n            return 4104;\n        }\n        function Pn() {\n            return Qn() | 0;\n        }\n        function Qn() {\n            return 4096;\n        }\n        function Rn() {\n            return Sn() | 0;\n        }\n        function Sn() {\n            return 4088;\n        }\n        function Tn() {\n            return Un() | 0;\n        }\n        function Un() {\n            return 4072;\n        }\n        function Vn() {\n            return Wn() | 0;\n        }\n        function Wn() {\n            return 4080;\n        }\n        function Xn() {\n            return Yn() | 0;\n        }\n        function Yn() {\n            return 4064;\n        }\n        function Zn() {\n            return 4056;\n        }\n        function _n() {\n            return 4040;\n        }\n        function $n(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = (b + 8) | 0;\n            e = (b + 4) | 0;\n            f = b;\n            c[f >> 2] = a;\n            c[e >> 2] = c[f >> 2];\n            c[d >> 2] = c[((c[e >> 2] | 0) + 4) >> 2];\n            a = Jo(c[d >> 2] | 0) | 0;\n            V = b;\n            return a | 0;\n        }\n        function ao() {\n            return 21636;\n        }\n        function bo(a) {\n            a = a | 0;\n            return (((a + -48) | 0) >>> 0 < 10) | 0;\n        }\n        function co() {\n            return 5576;\n        }\n        function eo(b, c) {\n            b = b | 0;\n            c = c | 0;\n            var d = 0, e = 0;\n            d = a[b >> 0] | 0;\n            e = a[c >> 0] | 0;\n            if ((d << 24) >> 24 == 0 ? 1 : (d << 24) >> 24 != (e << 24) >> 24)\n                b = e;\n            else {\n                do {\n                    b = (b + 1) | 0;\n                    c = (c + 1) | 0;\n                    d = a[b >> 0] | 0;\n                    e = a[c >> 0] | 0;\n                } while (!((d << 24) >> 24 == 0 ? 1 : (d << 24) >> 24 != (e << 24) >> 24));\n                b = e;\n            }\n            return ((d & 255) - (b & 255)) | 0;\n        }\n        function fo(b) {\n            b = b | 0;\n            var d = 0, e = 0, f = 0;\n            f = b;\n            a: do\n                if (!(f & 3))\n                    e = 5;\n                else {\n                    d = f;\n                    while (1) {\n                        if (!(a[b >> 0] | 0)) {\n                            b = d;\n                            break a;\n                        }\n                        b = (b + 1) | 0;\n                        d = b;\n                        if (!(d & 3)) {\n                            e = 5;\n                            break;\n                        }\n                    }\n                }\n            while (0);\n            if ((e | 0) == 5) {\n                while (1) {\n                    d = c[b >> 2] | 0;\n                    if (!(((d & -2139062144) ^ -2139062144) & (d + -16843009)))\n                        b = (b + 4) | 0;\n                    else\n                        break;\n                }\n                if (((d & 255) << 24) >> 24)\n                    do\n                        b = (b + 1) | 0;\n                    while ((a[b >> 0] | 0) != 0);\n            }\n            return (b - f) | 0;\n        }\n        function go(a) {\n            a = a | 0;\n            return;\n        }\n        function ho(a) {\n            a = a | 0;\n            return 1;\n        }\n        function io(b) {\n            b = b | 0;\n            var d = 0, e = 0;\n            d = (b + 74) | 0;\n            e = a[d >> 0] | 0;\n            a[d >> 0] = (e + 255) | e;\n            d = c[b >> 2] | 0;\n            if (!(d & 8)) {\n                c[(b + 8) >> 2] = 0;\n                c[(b + 4) >> 2] = 0;\n                e = c[(b + 44) >> 2] | 0;\n                c[(b + 28) >> 2] = e;\n                c[(b + 20) >> 2] = e;\n                c[(b + 16) >> 2] = e + (c[(b + 48) >> 2] | 0);\n                b = 0;\n            }\n            else {\n                c[b >> 2] = d | 32;\n                b = -1;\n            }\n            return b | 0;\n        }\n        function jo(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0, i = 0, j = 0;\n            f = (e + 16) | 0;\n            g = c[f >> 2] | 0;\n            if (!g)\n                if (!(io(e) | 0)) {\n                    g = c[f >> 2] | 0;\n                    h = 5;\n                }\n                else\n                    f = 0;\n            else\n                h = 5;\n            a: do\n                if ((h | 0) == 5) {\n                    j = (e + 20) | 0;\n                    i = c[j >> 2] | 0;\n                    f = i;\n                    if (((g - i) | 0) >>> 0 < d >>> 0) {\n                        f = aa[c[(e + 36) >> 2] & 7](e, b, d) | 0;\n                        break;\n                    }\n                    b: do\n                        if (((a[(e + 75) >> 0] | 0) < 0) | ((d | 0) == 0)) {\n                            h = 0;\n                            g = b;\n                        }\n                        else {\n                            i = d;\n                            while (1) {\n                                g = (i + -1) | 0;\n                                if ((a[(b + g) >> 0] | 0) == 10)\n                                    break;\n                                if (!g) {\n                                    h = 0;\n                                    g = b;\n                                    break b;\n                                }\n                                else\n                                    i = g;\n                            }\n                            f = aa[c[(e + 36) >> 2] & 7](e, b, i) | 0;\n                            if (f >>> 0 < i >>> 0)\n                                break a;\n                            h = i;\n                            g = (b + i) | 0;\n                            d = (d - i) | 0;\n                            f = c[j >> 2] | 0;\n                        }\n                    while (0);\n                    ur(f | 0, g | 0, d | 0) | 0;\n                    c[j >> 2] = (c[j >> 2] | 0) + d;\n                    f = (h + d) | 0;\n                }\n            while (0);\n            return f | 0;\n        }\n        function ko(a, b) {\n            a = a | 0;\n            b = b | 0;\n            if (!b)\n                b = 0;\n            else\n                b = lo(c[b >> 2] | 0, c[(b + 4) >> 2] | 0, a) | 0;\n            return ((b | 0) == 0 ? a : b) | 0;\n        }\n        function lo(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0;\n            o = ((c[b >> 2] | 0) + 1794895138) | 0;\n            h = mo(c[(b + 8) >> 2] | 0, o) | 0;\n            f = mo(c[(b + 12) >> 2] | 0, o) | 0;\n            g = mo(c[(b + 16) >> 2] | 0, o) | 0;\n            a: do\n                if ((h >>> 0 < (d >>> 2) >>> 0\n                    ? ((n = (d - (h << 2)) | 0), (f >>> 0 < n >>> 0) & (g >>> 0 < n >>> 0))\n                    : 0)\n                    ? (((g | f) & 3) | 0) == 0\n                    : 0) {\n                    n = f >>> 2;\n                    m = g >>> 2;\n                    l = 0;\n                    while (1) {\n                        j = h >>> 1;\n                        k = (l + j) | 0;\n                        i = k << 1;\n                        g = (i + n) | 0;\n                        f = mo(c[(b + (g << 2)) >> 2] | 0, o) | 0;\n                        g = mo(c[(b + ((g + 1) << 2)) >> 2] | 0, o) | 0;\n                        if (!((g >>> 0 < d >>> 0) & (f >>> 0 < ((d - g) | 0) >>> 0))) {\n                            f = 0;\n                            break a;\n                        }\n                        if (a[(b + (g + f)) >> 0] | 0) {\n                            f = 0;\n                            break a;\n                        }\n                        f = eo(e, (b + g) | 0) | 0;\n                        if (!f)\n                            break;\n                        f = (f | 0) < 0;\n                        if ((h | 0) == 1) {\n                            f = 0;\n                            break a;\n                        }\n                        l = f ? l : k;\n                        h = f ? j : (h - j) | 0;\n                    }\n                    f = (i + m) | 0;\n                    g = mo(c[(b + (f << 2)) >> 2] | 0, o) | 0;\n                    f = mo(c[(b + ((f + 1) << 2)) >> 2] | 0, o) | 0;\n                    if ((f >>> 0 < d >>> 0) & (g >>> 0 < ((d - f) | 0) >>> 0))\n                        f = (a[(b + (f + g)) >> 0] | 0) == 0 ? (b + f) | 0 : 0;\n                    else\n                        f = 0;\n                }\n                else\n                    f = 0;\n            while (0);\n            return f | 0;\n        }\n        function mo(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var c = 0;\n            c = tr(a | 0) | 0;\n            return ((b | 0) == 0 ? a : c) | 0;\n        }\n        function no(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0;\n            h = d & 255;\n            f = (e | 0) != 0;\n            a: do\n                if (f & (((b & 3) | 0) != 0)) {\n                    g = d & 255;\n                    while (1) {\n                        if ((a[b >> 0] | 0) == (g << 24) >> 24) {\n                            g = 6;\n                            break a;\n                        }\n                        b = (b + 1) | 0;\n                        e = (e + -1) | 0;\n                        f = (e | 0) != 0;\n                        if (!(f & (((b & 3) | 0) != 0))) {\n                            g = 5;\n                            break;\n                        }\n                    }\n                }\n                else\n                    g = 5;\n            while (0);\n            if ((g | 0) == 5)\n                if (f)\n                    g = 6;\n                else\n                    b = 0;\n            b: do\n                if ((g | 0) == 6) {\n                    if ((a[b >> 0] | 0) != ((d & 255) << 24) >> 24) {\n                        f = q(h, 16843009) | 0;\n                        c: do\n                            if (e >>> 0 > 3)\n                                do {\n                                    h = c[b >> 2] ^ f;\n                                    if ((((h & -2139062144) ^ -2139062144) & (h + -16843009)) | 0)\n                                        break c;\n                                    b = (b + 4) | 0;\n                                    e = (e + -4) | 0;\n                                } while (e >>> 0 > 3);\n                        while (0);\n                    }\n                    if (!e)\n                        b = 0;\n                    else {\n                        f = d & 255;\n                        while (1) {\n                            if ((a[b >> 0] | 0) == (f << 24) >> 24)\n                                break b;\n                            e = (e + -1) | 0;\n                            if (!e) {\n                                b = 0;\n                                break;\n                            }\n                            else\n                                b = (b + 1) | 0;\n                        }\n                    }\n                }\n            while (0);\n            return b | 0;\n        }\n        function oo(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            return ro(a, b, c, 1, 8) | 0;\n        }\n        function po(b, e, f, g, h, i) {\n            b = b | 0;\n            e = +e;\n            f = f | 0;\n            g = g | 0;\n            h = h | 0;\n            i = i | 0;\n            var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, r = 0.0, s = 0, t = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0;\n            H = V;\n            V = (V + 560) | 0;\n            l = (H + 32) | 0;\n            w = (H + 536) | 0;\n            G = H;\n            F = G;\n            m = (H + 540) | 0;\n            c[w >> 2] = 0;\n            E = (m + 12) | 0;\n            Do(e) | 0;\n            j = u() | 0;\n            if ((j | 0) < 0) {\n                e = -e;\n                Do(e) | 0;\n                D = 1;\n                C = 20247;\n                j = u() | 0;\n            }\n            else {\n                D = (((h & 2049) | 0) != 0) & 1;\n                C = ((h & 2048) | 0) == 0 ? (((h & 1) | 0) == 0 ? 20248 : 20253) : 20250;\n            }\n            do\n                if ((0 == 0) & (((j & 2146435072) | 0) == 2146435072)) {\n                    G = ((i & 32) | 0) != 0;\n                    j = (D + 3) | 0;\n                    zo(b, 32, f, j, h & -65537);\n                    to(b, C, D);\n                    to(b, (e != e) | (0.0 != 0.0) ? (G ? 20274 : 20278) : G ? 20266 : 20270, 3);\n                    zo(b, 32, f, j, h ^ 8192);\n                }\n                else {\n                    r = +Eo(e, w) * 2.0;\n                    j = r != 0.0;\n                    if (j)\n                        c[w >> 2] = (c[w >> 2] | 0) + -1;\n                    v = i | 32;\n                    if ((v | 0) == 97) {\n                        o = i & 32;\n                        s = (o | 0) == 0 ? C : (C + 9) | 0;\n                        p = D | 2;\n                        j = (12 - g) | 0;\n                        do\n                            if (!((g >>> 0 > 11) | ((j | 0) == 0))) {\n                                e = 8.0;\n                                do {\n                                    j = (j + -1) | 0;\n                                    e = e * 16.0;\n                                } while ((j | 0) != 0);\n                                if ((a[s >> 0] | 0) == 45) {\n                                    e = -(e + (-r - e));\n                                    break;\n                                }\n                                else {\n                                    e = r + e - e;\n                                    break;\n                                }\n                            }\n                            else\n                                e = r;\n                        while (0);\n                        k = c[w >> 2] | 0;\n                        j = (k | 0) < 0 ? (0 - k) | 0 : k;\n                        j = yo(j, (((j | 0) < 0) << 31) >> 31, E) | 0;\n                        if ((j | 0) == (E | 0)) {\n                            j = (m + 11) | 0;\n                            a[j >> 0] = 48;\n                        }\n                        a[(j + -1) >> 0] = ((k >> 31) & 2) + 43;\n                        n = (j + -2) | 0;\n                        a[n >> 0] = i + 15;\n                        k = (g | 0) < 1;\n                        l = ((h & 8) | 0) == 0;\n                        m = G;\n                        do {\n                            D = ~~e;\n                            j = (m + 1) | 0;\n                            a[m >> 0] = o | d[(640 + D) >> 0];\n                            e = (e - +(D | 0)) * 16.0;\n                            if (((j - F) | 0) == 1 ? !(l & (k & (e == 0.0))) : 0) {\n                                a[j >> 0] = 46;\n                                m = (m + 2) | 0;\n                            }\n                            else\n                                m = j;\n                        } while (e != 0.0);\n                        if ((g | 0) != 0 ? ((-2 - F + m) | 0) < (g | 0) : 0) {\n                            k = E;\n                            l = n;\n                            j = (g + 2 + k - l) | 0;\n                        }\n                        else {\n                            k = E;\n                            l = n;\n                            j = (k - F - l + m) | 0;\n                        }\n                        E = (j + p) | 0;\n                        zo(b, 32, f, E, h);\n                        to(b, s, p);\n                        zo(b, 48, f, E, h ^ 65536);\n                        F = (m - F) | 0;\n                        to(b, G, F);\n                        G = (k - l) | 0;\n                        zo(b, 48, (j - (F + G)) | 0, 0, 0);\n                        to(b, n, G);\n                        zo(b, 32, f, E, h ^ 8192);\n                        j = E;\n                        break;\n                    }\n                    k = (g | 0) < 0 ? 6 : g;\n                    if (j) {\n                        j = ((c[w >> 2] | 0) + -28) | 0;\n                        c[w >> 2] = j;\n                        e = r * 268435456.0;\n                    }\n                    else {\n                        e = r;\n                        j = c[w >> 2] | 0;\n                    }\n                    B = (j | 0) < 0 ? l : (l + 288) | 0;\n                    l = B;\n                    do {\n                        z = ~~e >>> 0;\n                        c[l >> 2] = z;\n                        l = (l + 4) | 0;\n                        e = (e - +(z >>> 0)) * 1.0e9;\n                    } while (e != 0.0);\n                    z = B;\n                    if ((j | 0) > 0) {\n                        o = B;\n                        while (1) {\n                            n = (j | 0) < 29 ? j : 29;\n                            j = (l + -4) | 0;\n                            if (j >>> 0 >= o >>> 0) {\n                                m = 0;\n                                do {\n                                    t = rr(c[j >> 2] | 0, 0, n | 0) | 0;\n                                    t = lr(t | 0, u() | 0, m | 0, 0) | 0;\n                                    x = u() | 0;\n                                    m = pr(t | 0, x | 0, 1e9, 0) | 0;\n                                    y = kr(m | 0, u() | 0, 1e9, 0) | 0;\n                                    y = mr(t | 0, x | 0, y | 0, u() | 0) | 0;\n                                    u() | 0;\n                                    c[j >> 2] = y;\n                                    j = (j + -4) | 0;\n                                } while (j >>> 0 >= o >>> 0);\n                                if (m) {\n                                    y = (o + -4) | 0;\n                                    c[y >> 2] = m;\n                                    m = y;\n                                }\n                                else\n                                    m = o;\n                            }\n                            else\n                                m = o;\n                            a: do\n                                if (l >>> 0 > m >>> 0) {\n                                    j = l;\n                                    while (1) {\n                                        l = (j + -4) | 0;\n                                        if (c[l >> 2] | 0) {\n                                            l = j;\n                                            break a;\n                                        }\n                                        if (l >>> 0 > m >>> 0)\n                                            j = l;\n                                        else\n                                            break;\n                                    }\n                                }\n                            while (0);\n                            j = ((c[w >> 2] | 0) - n) | 0;\n                            c[w >> 2] = j;\n                            if ((j | 0) > 0)\n                                o = m;\n                            else\n                                break;\n                        }\n                    }\n                    else\n                        m = B;\n                    if ((j | 0) < 0) {\n                        g = (((((k + 25) | 0) / 9) | 0) + 1) | 0;\n                        t = (v | 0) == 102;\n                        do {\n                            s = (0 - j) | 0;\n                            s = (s | 0) < 9 ? s : 9;\n                            if (m >>> 0 < l >>> 0) {\n                                n = ((1 << s) + -1) | 0;\n                                o = 1e9 >>> s;\n                                p = 0;\n                                j = m;\n                                do {\n                                    y = c[j >> 2] | 0;\n                                    c[j >> 2] = (y >>> s) + p;\n                                    p = q(y & n, o) | 0;\n                                    j = (j + 4) | 0;\n                                } while (j >>> 0 < l >>> 0);\n                                m = (c[m >> 2] | 0) == 0 ? (m + 4) | 0 : m;\n                                if (p) {\n                                    c[l >> 2] = p;\n                                    l = (l + 4) | 0;\n                                }\n                            }\n                            else\n                                m = (c[m >> 2] | 0) == 0 ? (m + 4) | 0 : m;\n                            j = t ? B : m;\n                            l = (((l - j) >> 2) | 0) > (g | 0) ? (j + (g << 2)) | 0 : l;\n                            j = ((c[w >> 2] | 0) + s) | 0;\n                            c[w >> 2] = j;\n                        } while ((j | 0) < 0);\n                        t = m;\n                    }\n                    else\n                        t = m;\n                    if (t >>> 0 < l >>> 0) {\n                        j = (((z - t) >> 2) * 9) | 0;\n                        n = c[t >> 2] | 0;\n                        if (n >>> 0 >= 10) {\n                            m = 10;\n                            do {\n                                m = (m * 10) | 0;\n                                j = (j + 1) | 0;\n                            } while (n >>> 0 >= m >>> 0);\n                        }\n                    }\n                    else\n                        j = 0;\n                    x = (v | 0) == 103;\n                    y = (k | 0) != 0;\n                    m = (k - ((v | 0) == 102 ? 0 : j) + (((y & x) << 31) >> 31)) | 0;\n                    if ((m | 0) < ((((((l - z) >> 2) * 9) | 0) + -9) | 0)) {\n                        w = (m + 9216) | 0;\n                        m = ((w | 0) / 9) | 0;\n                        g = (B + 4 + ((m + -1024) << 2)) | 0;\n                        m = (w - ((m * 9) | 0)) | 0;\n                        if ((m | 0) < 8) {\n                            n = 10;\n                            while (1) {\n                                n = (n * 10) | 0;\n                                if ((m | 0) < 7)\n                                    m = (m + 1) | 0;\n                                else\n                                    break;\n                            }\n                        }\n                        else\n                            n = 10;\n                        p = c[g >> 2] | 0;\n                        m = ((p >>> 0) / (n >>> 0)) | 0;\n                        s = (p - (q(m, n) | 0)) | 0;\n                        o = ((g + 4) | 0) == (l | 0);\n                        if (!(o & ((s | 0) == 0))) {\n                            r = ((m & 1) | 0) == 0 ? 9007199254740992.0 : 9007199254740994.0;\n                            w = n >>> 1;\n                            e = s >>> 0 < w >>> 0 ? 0.5 : o & ((s | 0) == (w | 0)) ? 1.0 : 1.5;\n                            if (D) {\n                                w = (a[C >> 0] | 0) == 45;\n                                e = w ? -e : e;\n                                r = w ? -r : r;\n                            }\n                            m = (p - s) | 0;\n                            c[g >> 2] = m;\n                            if (r + e != r) {\n                                w = (m + n) | 0;\n                                c[g >> 2] = w;\n                                if (w >>> 0 > 999999999) {\n                                    n = g;\n                                    j = t;\n                                    while (1) {\n                                        m = (n + -4) | 0;\n                                        c[n >> 2] = 0;\n                                        if (m >>> 0 < j >>> 0) {\n                                            j = (j + -4) | 0;\n                                            c[j >> 2] = 0;\n                                        }\n                                        w = ((c[m >> 2] | 0) + 1) | 0;\n                                        c[m >> 2] = w;\n                                        if (w >>> 0 > 999999999)\n                                            n = m;\n                                        else {\n                                            n = j;\n                                            break;\n                                        }\n                                    }\n                                }\n                                else {\n                                    m = g;\n                                    n = t;\n                                }\n                                j = (((z - n) >> 2) * 9) | 0;\n                                p = c[n >> 2] | 0;\n                                if (p >>> 0 >= 10) {\n                                    o = 10;\n                                    do {\n                                        o = (o * 10) | 0;\n                                        j = (j + 1) | 0;\n                                    } while (p >>> 0 >= o >>> 0);\n                                }\n                            }\n                            else {\n                                m = g;\n                                n = t;\n                            }\n                        }\n                        else {\n                            m = g;\n                            n = t;\n                        }\n                        w = (m + 4) | 0;\n                        l = l >>> 0 > w >>> 0 ? w : l;\n                    }\n                    else\n                        n = t;\n                    g = (0 - j) | 0;\n                    b: do\n                        if (l >>> 0 > n >>> 0)\n                            while (1) {\n                                m = (l + -4) | 0;\n                                if (c[m >> 2] | 0) {\n                                    w = l;\n                                    v = 1;\n                                    break b;\n                                }\n                                if (m >>> 0 > n >>> 0)\n                                    l = m;\n                                else {\n                                    w = m;\n                                    v = 0;\n                                    break;\n                                }\n                            }\n                        else {\n                            w = l;\n                            v = 0;\n                        }\n                    while (0);\n                    do\n                        if (x) {\n                            k = (k + ((y ^ 1) & 1)) | 0;\n                            if (((k | 0) > (j | 0)) & ((j | 0) > -5)) {\n                                o = (i + -1) | 0;\n                                k = (k + -1 - j) | 0;\n                            }\n                            else {\n                                o = (i + -2) | 0;\n                                k = (k + -1) | 0;\n                            }\n                            if (!(h & 8)) {\n                                if (v ? ((A = c[(w + -4) >> 2] | 0), (A | 0) != 0) : 0)\n                                    if (!((A >>> 0) % 10 | 0)) {\n                                        m = 0;\n                                        l = 10;\n                                        do {\n                                            l = (l * 10) | 0;\n                                            m = (m + 1) | 0;\n                                        } while (!((A >>> 0) % (l >>> 0) | 0 | 0));\n                                    }\n                                    else\n                                        m = 0;\n                                else\n                                    m = 9;\n                                l = (((((w - z) >> 2) * 9) | 0) + -9) | 0;\n                                if ((o | 32 | 0) == 102) {\n                                    i = (l - m) | 0;\n                                    i = (i | 0) > 0 ? i : 0;\n                                    k = (k | 0) < (i | 0) ? k : i;\n                                    break;\n                                }\n                                else {\n                                    i = (l + j - m) | 0;\n                                    i = (i | 0) > 0 ? i : 0;\n                                    k = (k | 0) < (i | 0) ? k : i;\n                                    break;\n                                }\n                            }\n                        }\n                        else\n                            o = i;\n                    while (0);\n                    t = (k | 0) != 0;\n                    p = t ? 1 : (h >>> 3) & 1;\n                    s = (o | 32 | 0) == 102;\n                    if (s) {\n                        x = 0;\n                        j = (j | 0) > 0 ? j : 0;\n                    }\n                    else {\n                        l = (j | 0) < 0 ? g : j;\n                        l = yo(l, (((l | 0) < 0) << 31) >> 31, E) | 0;\n                        m = E;\n                        if (((m - l) | 0) < 2)\n                            do {\n                                l = (l + -1) | 0;\n                                a[l >> 0] = 48;\n                            } while (((m - l) | 0) < 2);\n                        a[(l + -1) >> 0] = ((j >> 31) & 2) + 43;\n                        j = (l + -2) | 0;\n                        a[j >> 0] = o;\n                        x = j;\n                        j = (m - j) | 0;\n                    }\n                    j = (D + 1 + k + p + j) | 0;\n                    zo(b, 32, f, j, h);\n                    to(b, C, D);\n                    zo(b, 48, f, j, h ^ 65536);\n                    if (s) {\n                        p = n >>> 0 > B >>> 0 ? B : n;\n                        s = (G + 9) | 0;\n                        n = s;\n                        o = (G + 8) | 0;\n                        m = p;\n                        do {\n                            l = yo(c[m >> 2] | 0, 0, s) | 0;\n                            if ((m | 0) == (p | 0)) {\n                                if ((l | 0) == (s | 0)) {\n                                    a[o >> 0] = 48;\n                                    l = o;\n                                }\n                            }\n                            else if (l >>> 0 > G >>> 0) {\n                                wr(G | 0, 48, (l - F) | 0) | 0;\n                                do\n                                    l = (l + -1) | 0;\n                                while (l >>> 0 > G >>> 0);\n                            }\n                            to(b, l, (n - l) | 0);\n                            m = (m + 4) | 0;\n                        } while (m >>> 0 <= B >>> 0);\n                        if (!((((h & 8) | 0) == 0) & (t ^ 1)))\n                            to(b, 20282, 1);\n                        if ((m >>> 0 < w >>> 0) & ((k | 0) > 0))\n                            while (1) {\n                                l = yo(c[m >> 2] | 0, 0, s) | 0;\n                                if (l >>> 0 > G >>> 0) {\n                                    wr(G | 0, 48, (l - F) | 0) | 0;\n                                    do\n                                        l = (l + -1) | 0;\n                                    while (l >>> 0 > G >>> 0);\n                                }\n                                to(b, l, (k | 0) < 9 ? k : 9);\n                                m = (m + 4) | 0;\n                                l = (k + -9) | 0;\n                                if (!((m >>> 0 < w >>> 0) & ((k | 0) > 9))) {\n                                    k = l;\n                                    break;\n                                }\n                                else\n                                    k = l;\n                            }\n                        zo(b, 48, (k + 9) | 0, 9, 0);\n                    }\n                    else {\n                        w = v ? w : (n + 4) | 0;\n                        if ((n >>> 0 < w >>> 0) & ((k | 0) > -1)) {\n                            g = (G + 9) | 0;\n                            t = ((h & 8) | 0) == 0;\n                            v = g;\n                            p = (0 - F) | 0;\n                            s = (G + 8) | 0;\n                            o = n;\n                            do {\n                                l = yo(c[o >> 2] | 0, 0, g) | 0;\n                                if ((l | 0) == (g | 0)) {\n                                    a[s >> 0] = 48;\n                                    l = s;\n                                }\n                                do\n                                    if ((o | 0) == (n | 0)) {\n                                        m = (l + 1) | 0;\n                                        to(b, l, 1);\n                                        if (t & ((k | 0) < 1)) {\n                                            l = m;\n                                            break;\n                                        }\n                                        to(b, 20282, 1);\n                                        l = m;\n                                    }\n                                    else {\n                                        if (l >>> 0 <= G >>> 0)\n                                            break;\n                                        wr(G | 0, 48, (l + p) | 0) | 0;\n                                        do\n                                            l = (l + -1) | 0;\n                                        while (l >>> 0 > G >>> 0);\n                                    }\n                                while (0);\n                                F = (v - l) | 0;\n                                to(b, l, (k | 0) > (F | 0) ? F : k);\n                                k = (k - F) | 0;\n                                o = (o + 4) | 0;\n                            } while ((o >>> 0 < w >>> 0) & ((k | 0) > -1));\n                        }\n                        zo(b, 48, (k + 18) | 0, 18, 0);\n                        to(b, x, (E - x) | 0);\n                    }\n                    zo(b, 32, f, j, h ^ 8192);\n                }\n            while (0);\n            V = H;\n            return ((j | 0) < (f | 0) ? f : j) | 0;\n        }\n        function qo(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0.0, e = 0;\n            e = ((c[b >> 2] | 0) + (8 - 1)) & ~(8 - 1);\n            d = +g[e >> 3];\n            c[b >> 2] = e + 8;\n            g[a >> 3] = d;\n            return;\n        }\n        function ro(b, d, e, f, g) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            var h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0;\n            t = V;\n            V = (V + 224) | 0;\n            p = (t + 208) | 0;\n            q = (t + 160) | 0;\n            r = (t + 80) | 0;\n            s = t;\n            h = q;\n            i = (h + 40) | 0;\n            do {\n                c[h >> 2] = 0;\n                h = (h + 4) | 0;\n            } while ((h | 0) < (i | 0));\n            c[p >> 2] = c[e >> 2];\n            if ((so(0, d, p, r, q, f, g) | 0) < 0)\n                e = -1;\n            else {\n                if ((c[(b + 76) >> 2] | 0) > -1)\n                    o = ho(b) | 0;\n                else\n                    o = 0;\n                e = c[b >> 2] | 0;\n                n = e & 32;\n                if ((a[(b + 74) >> 0] | 0) < 1)\n                    c[b >> 2] = e & -33;\n                h = (b + 48) | 0;\n                if (!(c[h >> 2] | 0)) {\n                    i = (b + 44) | 0;\n                    j = c[i >> 2] | 0;\n                    c[i >> 2] = s;\n                    k = (b + 28) | 0;\n                    c[k >> 2] = s;\n                    l = (b + 20) | 0;\n                    c[l >> 2] = s;\n                    c[h >> 2] = 80;\n                    m = (b + 16) | 0;\n                    c[m >> 2] = s + 80;\n                    e = so(b, d, p, r, q, f, g) | 0;\n                    if (j) {\n                        aa[c[(b + 36) >> 2] & 7](b, 0, 0) | 0;\n                        e = (c[l >> 2] | 0) == 0 ? -1 : e;\n                        c[i >> 2] = j;\n                        c[h >> 2] = 0;\n                        c[m >> 2] = 0;\n                        c[k >> 2] = 0;\n                        c[l >> 2] = 0;\n                    }\n                }\n                else\n                    e = so(b, d, p, r, q, f, g) | 0;\n                h = c[b >> 2] | 0;\n                c[b >> 2] = h | n;\n                if (o | 0)\n                    go(b);\n                e = ((h & 32) | 0) == 0 ? e : -1;\n            }\n            V = t;\n            return e | 0;\n        }\n        function so(d, e, f, h, i, j, k) {\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            h = h | 0;\n            i = i | 0;\n            j = j | 0;\n            k = k | 0;\n            var l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0;\n            J = V;\n            V = (V + 64) | 0;\n            G = (J + 56) | 0;\n            I = (J + 40) | 0;\n            B = J;\n            D = (J + 48) | 0;\n            E = (J + 60) | 0;\n            c[G >> 2] = e;\n            y = (d | 0) != 0;\n            z = (B + 40) | 0;\n            A = z;\n            B = (B + 39) | 0;\n            C = (D + 4) | 0;\n            l = 0;\n            e = 0;\n            n = 0;\n            a: while (1) {\n                do {\n                    do\n                        if ((e | 0) > -1)\n                            if ((l | 0) > ((2147483647 - e) | 0)) {\n                                c[(ao() | 0) >> 2] = 61;\n                                e = -1;\n                                break;\n                            }\n                            else {\n                                e = (l + e) | 0;\n                                break;\n                            }\n                    while (0);\n                    r = c[G >> 2] | 0;\n                    l = a[r >> 0] | 0;\n                    if (!((l << 24) >> 24)) {\n                        x = 92;\n                        break a;\n                    }\n                    m = r;\n                    b: while (1) {\n                        switch ((l << 24) >> 24) {\n                            case 37: {\n                                x = 10;\n                                break b;\n                            }\n                            case 0: {\n                                l = m;\n                                break b;\n                            }\n                            default: {\n                            }\n                        }\n                        w = (m + 1) | 0;\n                        c[G >> 2] = w;\n                        l = a[w >> 0] | 0;\n                        m = w;\n                    }\n                    c: do\n                        if ((x | 0) == 10) {\n                            x = 0;\n                            l = m;\n                            do {\n                                if ((a[(m + 1) >> 0] | 0) != 37)\n                                    break c;\n                                l = (l + 1) | 0;\n                                m = (m + 2) | 0;\n                                c[G >> 2] = m;\n                            } while ((a[m >> 0] | 0) == 37);\n                        }\n                    while (0);\n                    l = (l - r) | 0;\n                    if (y)\n                        to(d, r, l);\n                } while ((l | 0) != 0);\n                w = (bo(a[((c[G >> 2] | 0) + 1) >> 0] | 0) | 0) == 0;\n                m = c[G >> 2] | 0;\n                if (!w ? (a[(m + 2) >> 0] | 0) == 36 : 0) {\n                    t = ((a[(m + 1) >> 0] | 0) + -48) | 0;\n                    p = 1;\n                    l = 3;\n                }\n                else {\n                    t = -1;\n                    p = n;\n                    l = 1;\n                }\n                l = (m + l) | 0;\n                c[G >> 2] = l;\n                m = a[l >> 0] | 0;\n                n = (((m << 24) >> 24) + -32) | 0;\n                if ((n >>> 0 > 31) | ((((1 << n) & 75913) | 0) == 0))\n                    o = 0;\n                else {\n                    o = 0;\n                    do {\n                        o = (1 << n) | o;\n                        l = (l + 1) | 0;\n                        c[G >> 2] = l;\n                        m = a[l >> 0] | 0;\n                        n = (((m << 24) >> 24) + -32) | 0;\n                    } while (!((n >>> 0 > 31) | ((((1 << n) & 75913) | 0) == 0)));\n                }\n                if ((m << 24) >> 24 == 42) {\n                    if ((bo(a[(l + 1) >> 0] | 0) | 0) != 0\n                        ? ((H = c[G >> 2] | 0), (a[(H + 2) >> 0] | 0) == 36)\n                        : 0) {\n                        l = (H + 1) | 0;\n                        c[(i + (((a[l >> 0] | 0) + -48) << 2)) >> 2] = 10;\n                        l = c[(h + (((a[l >> 0] | 0) + -48) << 3)) >> 2] | 0;\n                        n = 1;\n                        m = (H + 3) | 0;\n                    }\n                    else {\n                        if (p | 0) {\n                            e = -1;\n                            break;\n                        }\n                        if (y) {\n                            w = ((c[f >> 2] | 0) + (4 - 1)) & ~(4 - 1);\n                            l = c[w >> 2] | 0;\n                            c[f >> 2] = w + 4;\n                        }\n                        else\n                            l = 0;\n                        n = 0;\n                        m = ((c[G >> 2] | 0) + 1) | 0;\n                    }\n                    c[G >> 2] = m;\n                    w = (l | 0) < 0;\n                    v = w ? (0 - l) | 0 : l;\n                    o = w ? o | 8192 : o;\n                    w = n;\n                }\n                else {\n                    l = uo(G) | 0;\n                    if ((l | 0) < 0) {\n                        e = -1;\n                        break;\n                    }\n                    v = l;\n                    w = p;\n                    m = c[G >> 2] | 0;\n                }\n                do\n                    if ((a[m >> 0] | 0) == 46) {\n                        l = (m + 1) | 0;\n                        if ((a[l >> 0] | 0) != 42) {\n                            c[G >> 2] = l;\n                            l = uo(G) | 0;\n                            m = c[G >> 2] | 0;\n                            break;\n                        }\n                        if (bo(a[(m + 2) >> 0] | 0) | 0 ? ((F = c[G >> 2] | 0), (a[(F + 3) >> 0] | 0) == 36) : 0) {\n                            l = (F + 2) | 0;\n                            c[(i + (((a[l >> 0] | 0) + -48) << 2)) >> 2] = 10;\n                            l = c[(h + (((a[l >> 0] | 0) + -48) << 3)) >> 2] | 0;\n                            m = (F + 4) | 0;\n                            c[G >> 2] = m;\n                            break;\n                        }\n                        if (w | 0) {\n                            e = -1;\n                            break a;\n                        }\n                        if (y) {\n                            s = ((c[f >> 2] | 0) + (4 - 1)) & ~(4 - 1);\n                            l = c[s >> 2] | 0;\n                            c[f >> 2] = s + 4;\n                        }\n                        else\n                            l = 0;\n                        m = ((c[G >> 2] | 0) + 2) | 0;\n                        c[G >> 2] = m;\n                    }\n                    else\n                        l = -1;\n                while (0);\n                s = 0;\n                while (1) {\n                    if ((((a[m >> 0] | 0) + -65) | 0) >>> 0 > 57) {\n                        e = -1;\n                        break a;\n                    }\n                    n = m;\n                    m = (m + 1) | 0;\n                    c[G >> 2] = m;\n                    n = a[((a[n >> 0] | 0) + -65 + (176 + ((s * 58) | 0))) >> 0] | 0;\n                    p = n & 255;\n                    if (((p + -1) | 0) >>> 0 >= 8)\n                        break;\n                    else\n                        s = p;\n                }\n                if (!((n << 24) >> 24)) {\n                    e = -1;\n                    break;\n                }\n                q = (t | 0) > -1;\n                do\n                    if ((n << 24) >> 24 == 19)\n                        if (q) {\n                            e = -1;\n                            break a;\n                        }\n                        else\n                            x = 54;\n                    else {\n                        if (q) {\n                            c[(i + (t << 2)) >> 2] = p;\n                            q = (h + (t << 3)) | 0;\n                            t = c[(q + 4) >> 2] | 0;\n                            x = I;\n                            c[x >> 2] = c[q >> 2];\n                            c[(x + 4) >> 2] = t;\n                            x = 54;\n                            break;\n                        }\n                        if (!y) {\n                            e = 0;\n                            break a;\n                        }\n                        vo(I, p, f, k);\n                        m = c[G >> 2] | 0;\n                        x = 55;\n                    }\n                while (0);\n                if ((x | 0) == 54) {\n                    x = 0;\n                    if (y)\n                        x = 55;\n                    else\n                        l = 0;\n                }\n                d: do\n                    if ((x | 0) == 55) {\n                        x = 0;\n                        m = a[(m + -1) >> 0] | 0;\n                        m = ((s | 0) != 0) & (((m & 15) | 0) == 3) ? m & -33 : m;\n                        n = o & -65537;\n                        t = ((o & 8192) | 0) == 0 ? o : n;\n                        e: do\n                            switch (m | 0) {\n                                case 110:\n                                    switch (((s & 255) << 24) >> 24) {\n                                        case 0: {\n                                            c[c[I >> 2] >> 2] = e;\n                                            l = 0;\n                                            break d;\n                                        }\n                                        case 1: {\n                                            c[c[I >> 2] >> 2] = e;\n                                            l = 0;\n                                            break d;\n                                        }\n                                        case 2: {\n                                            l = c[I >> 2] | 0;\n                                            c[l >> 2] = e;\n                                            c[(l + 4) >> 2] = (((e | 0) < 0) << 31) >> 31;\n                                            l = 0;\n                                            break d;\n                                        }\n                                        case 3: {\n                                            b[c[I >> 2] >> 1] = e;\n                                            l = 0;\n                                            break d;\n                                        }\n                                        case 4: {\n                                            a[c[I >> 2] >> 0] = e;\n                                            l = 0;\n                                            break d;\n                                        }\n                                        case 6: {\n                                            c[c[I >> 2] >> 2] = e;\n                                            l = 0;\n                                            break d;\n                                        }\n                                        case 7: {\n                                            l = c[I >> 2] | 0;\n                                            c[l >> 2] = e;\n                                            c[(l + 4) >> 2] = (((e | 0) < 0) << 31) >> 31;\n                                            l = 0;\n                                            break d;\n                                        }\n                                        default: {\n                                            l = 0;\n                                            break d;\n                                        }\n                                    }\n                                case 112: {\n                                    m = 120;\n                                    l = l >>> 0 > 8 ? l : 8;\n                                    n = t | 8;\n                                    x = 67;\n                                    break;\n                                }\n                                case 88:\n                                case 120: {\n                                    n = t;\n                                    x = 67;\n                                    break;\n                                }\n                                case 111: {\n                                    q = I;\n                                    q = xo(c[q >> 2] | 0, c[(q + 4) >> 2] | 0, z) | 0;\n                                    n = (A - q) | 0;\n                                    o = 0;\n                                    p = 20230;\n                                    l = (((t & 8) | 0) == 0) | ((l | 0) > (n | 0)) ? l : (n + 1) | 0;\n                                    n = t;\n                                    x = 73;\n                                    break;\n                                }\n                                case 105:\n                                case 100: {\n                                    n = I;\n                                    m = c[n >> 2] | 0;\n                                    n = c[(n + 4) >> 2] | 0;\n                                    if ((n | 0) < 0) {\n                                        m = mr(0, 0, m | 0, n | 0) | 0;\n                                        n = u() | 0;\n                                        o = I;\n                                        c[o >> 2] = m;\n                                        c[(o + 4) >> 2] = n;\n                                        o = 1;\n                                        p = 20230;\n                                        x = 72;\n                                        break e;\n                                    }\n                                    else {\n                                        o = (((t & 2049) | 0) != 0) & 1;\n                                        p = ((t & 2048) | 0) == 0 ? (((t & 1) | 0) == 0 ? 20230 : 20232) : 20231;\n                                        x = 72;\n                                        break e;\n                                    }\n                                }\n                                case 117: {\n                                    n = I;\n                                    o = 0;\n                                    p = 20230;\n                                    m = c[n >> 2] | 0;\n                                    n = c[(n + 4) >> 2] | 0;\n                                    x = 72;\n                                    break;\n                                }\n                                case 99: {\n                                    a[B >> 0] = c[I >> 2];\n                                    r = B;\n                                    o = 0;\n                                    p = 20230;\n                                    q = 1;\n                                    m = n;\n                                    l = A;\n                                    break;\n                                }\n                                case 115: {\n                                    s = c[I >> 2] | 0;\n                                    s = (s | 0) == 0 ? 20240 : s;\n                                    t = no(s, 0, l) | 0;\n                                    K = (t | 0) == 0;\n                                    r = s;\n                                    o = 0;\n                                    p = 20230;\n                                    q = K ? l : (t - s) | 0;\n                                    m = n;\n                                    l = K ? (s + l) | 0 : t;\n                                    break;\n                                }\n                                case 67: {\n                                    c[D >> 2] = c[I >> 2];\n                                    c[C >> 2] = 0;\n                                    c[I >> 2] = D;\n                                    p = -1;\n                                    x = 79;\n                                    break;\n                                }\n                                case 83: {\n                                    if (!l) {\n                                        zo(d, 32, v, 0, t);\n                                        l = 0;\n                                        x = 89;\n                                    }\n                                    else {\n                                        p = l;\n                                        x = 79;\n                                    }\n                                    break;\n                                }\n                                case 65:\n                                case 71:\n                                case 70:\n                                case 69:\n                                case 97:\n                                case 103:\n                                case 102:\n                                case 101: {\n                                    l = _[j & 1](d, +g[I >> 3], v, l, t, m) | 0;\n                                    break d;\n                                }\n                                default: {\n                                    o = 0;\n                                    p = 20230;\n                                    q = l;\n                                    m = t;\n                                    l = A;\n                                }\n                            }\n                        while (0);\n                        f: do\n                            if ((x | 0) == 67) {\n                                q = I;\n                                q = wo(c[q >> 2] | 0, c[(q + 4) >> 2] | 0, z, m & 32) | 0;\n                                p = I;\n                                p = (((n & 8) | 0) == 0) | (((c[p >> 2] | 0) == 0) & ((c[(p + 4) >> 2] | 0) == 0));\n                                o = p ? 0 : 2;\n                                p = p ? 20230 : (20230 + (m >>> 4)) | 0;\n                                x = 73;\n                            }\n                            else if ((x | 0) == 72) {\n                                q = yo(m, n, z) | 0;\n                                n = t;\n                                x = 73;\n                            }\n                            else if ((x | 0) == 79) {\n                                x = 0;\n                                o = c[I >> 2] | 0;\n                                l = 0;\n                                while (1) {\n                                    m = c[o >> 2] | 0;\n                                    if (!m)\n                                        break;\n                                    m = Ao(E, m) | 0;\n                                    n = (m | 0) < 0;\n                                    if (n | (m >>> 0 > ((p - l) | 0) >>> 0)) {\n                                        x = 83;\n                                        break;\n                                    }\n                                    l = (m + l) | 0;\n                                    if (p >>> 0 > l >>> 0)\n                                        o = (o + 4) | 0;\n                                    else\n                                        break;\n                                }\n                                if ((x | 0) == 83) {\n                                    x = 0;\n                                    if (n) {\n                                        e = -1;\n                                        break a;\n                                    }\n                                }\n                                zo(d, 32, v, l, t);\n                                if (!l) {\n                                    l = 0;\n                                    x = 89;\n                                }\n                                else {\n                                    n = c[I >> 2] | 0;\n                                    o = 0;\n                                    while (1) {\n                                        m = c[n >> 2] | 0;\n                                        if (!m) {\n                                            x = 89;\n                                            break f;\n                                        }\n                                        m = Ao(E, m) | 0;\n                                        o = (m + o) | 0;\n                                        if ((o | 0) > (l | 0)) {\n                                            x = 89;\n                                            break f;\n                                        }\n                                        to(d, E, m);\n                                        if (o >>> 0 >= l >>> 0) {\n                                            x = 89;\n                                            break;\n                                        }\n                                        else\n                                            n = (n + 4) | 0;\n                                    }\n                                }\n                            }\n                        while (0);\n                        if ((x | 0) == 73) {\n                            x = 0;\n                            m = I;\n                            m = ((c[m >> 2] | 0) != 0) | ((c[(m + 4) >> 2] | 0) != 0);\n                            K = ((l | 0) != 0) | m;\n                            m = (A - q + ((m ^ 1) & 1)) | 0;\n                            r = K ? q : z;\n                            q = K ? ((l | 0) > (m | 0) ? l : m) : 0;\n                            m = (l | 0) > -1 ? n & -65537 : n;\n                            l = A;\n                        }\n                        else if ((x | 0) == 89) {\n                            x = 0;\n                            zo(d, 32, v, l, t ^ 8192);\n                            l = (v | 0) > (l | 0) ? v : l;\n                            break;\n                        }\n                        t = (l - r) | 0;\n                        s = (q | 0) < (t | 0) ? t : q;\n                        K = (s + o) | 0;\n                        l = (v | 0) < (K | 0) ? K : v;\n                        zo(d, 32, l, K, m);\n                        to(d, p, o);\n                        zo(d, 48, l, K, m ^ 65536);\n                        zo(d, 48, s, t, 0);\n                        to(d, r, t);\n                        zo(d, 32, l, K, m ^ 8192);\n                    }\n                while (0);\n                n = w;\n            }\n            g: do\n                if ((x | 0) == 92)\n                    if (!d)\n                        if (!n)\n                            e = 0;\n                        else {\n                            e = 1;\n                            while (1) {\n                                l = c[(i + (e << 2)) >> 2] | 0;\n                                if (!l)\n                                    break;\n                                vo((h + (e << 3)) | 0, l, f, k);\n                                e = (e + 1) | 0;\n                                if (e >>> 0 >= 10) {\n                                    e = 1;\n                                    break g;\n                                }\n                            }\n                            while (1) {\n                                if (c[(i + (e << 2)) >> 2] | 0) {\n                                    e = -1;\n                                    break g;\n                                }\n                                e = (e + 1) | 0;\n                                if (e >>> 0 >= 10) {\n                                    e = 1;\n                                    break;\n                                }\n                            }\n                        }\n            while (0);\n            V = J;\n            return e | 0;\n        }\n        function to(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            if (!(c[a >> 2] & 32))\n                jo(b, d, a) | 0;\n            return;\n        }\n        function uo(b) {\n            b = b | 0;\n            var d = 0, e = 0;\n            if (!(bo(a[c[b >> 2] >> 0] | 0) | 0))\n                d = 0;\n            else {\n                d = 0;\n                do {\n                    e = c[b >> 2] | 0;\n                    d = (((d * 10) | 0) + -48 + (a[e >> 0] | 0)) | 0;\n                    e = (e + 1) | 0;\n                    c[b >> 2] = e;\n                } while ((bo(a[e >> 0] | 0) | 0) != 0);\n            }\n            return d | 0;\n        }\n        function vo(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, h = 0.0;\n            a: do\n                if (b >>> 0 <= 20)\n                    do\n                        switch (b | 0) {\n                            case 9: {\n                                b = ((c[d >> 2] | 0) + (4 - 1)) & ~(4 - 1);\n                                e = c[b >> 2] | 0;\n                                c[d >> 2] = b + 4;\n                                c[a >> 2] = e;\n                                break a;\n                            }\n                            case 10: {\n                                e = ((c[d >> 2] | 0) + (4 - 1)) & ~(4 - 1);\n                                b = c[e >> 2] | 0;\n                                c[d >> 2] = e + 4;\n                                e = a;\n                                c[e >> 2] = b;\n                                c[(e + 4) >> 2] = (((b | 0) < 0) << 31) >> 31;\n                                break a;\n                            }\n                            case 11: {\n                                e = ((c[d >> 2] | 0) + (4 - 1)) & ~(4 - 1);\n                                b = c[e >> 2] | 0;\n                                c[d >> 2] = e + 4;\n                                e = a;\n                                c[e >> 2] = b;\n                                c[(e + 4) >> 2] = 0;\n                                break a;\n                            }\n                            case 12: {\n                                e = ((c[d >> 2] | 0) + (8 - 1)) & ~(8 - 1);\n                                b = e;\n                                f = c[b >> 2] | 0;\n                                b = c[(b + 4) >> 2] | 0;\n                                c[d >> 2] = e + 8;\n                                e = a;\n                                c[e >> 2] = f;\n                                c[(e + 4) >> 2] = b;\n                                break a;\n                            }\n                            case 13: {\n                                f = ((c[d >> 2] | 0) + (4 - 1)) & ~(4 - 1);\n                                e = c[f >> 2] | 0;\n                                c[d >> 2] = f + 4;\n                                e = ((e & 65535) << 16) >> 16;\n                                f = a;\n                                c[f >> 2] = e;\n                                c[(f + 4) >> 2] = (((e | 0) < 0) << 31) >> 31;\n                                break a;\n                            }\n                            case 14: {\n                                f = ((c[d >> 2] | 0) + (4 - 1)) & ~(4 - 1);\n                                e = c[f >> 2] | 0;\n                                c[d >> 2] = f + 4;\n                                f = a;\n                                c[f >> 2] = e & 65535;\n                                c[(f + 4) >> 2] = 0;\n                                break a;\n                            }\n                            case 15: {\n                                f = ((c[d >> 2] | 0) + (4 - 1)) & ~(4 - 1);\n                                e = c[f >> 2] | 0;\n                                c[d >> 2] = f + 4;\n                                e = ((e & 255) << 24) >> 24;\n                                f = a;\n                                c[f >> 2] = e;\n                                c[(f + 4) >> 2] = (((e | 0) < 0) << 31) >> 31;\n                                break a;\n                            }\n                            case 16: {\n                                f = ((c[d >> 2] | 0) + (4 - 1)) & ~(4 - 1);\n                                e = c[f >> 2] | 0;\n                                c[d >> 2] = f + 4;\n                                f = a;\n                                c[f >> 2] = e & 255;\n                                c[(f + 4) >> 2] = 0;\n                                break a;\n                            }\n                            case 17: {\n                                f = ((c[d >> 2] | 0) + (8 - 1)) & ~(8 - 1);\n                                h = +g[f >> 3];\n                                c[d >> 2] = f + 8;\n                                g[a >> 3] = h;\n                                break a;\n                            }\n                            case 18: {\n                                da[e & 15](a, d);\n                                break a;\n                            }\n                            default:\n                                break a;\n                        }\n                    while (0);\n            while (0);\n            return;\n        }\n        function wo(b, c, e, f) {\n            b = b | 0;\n            c = c | 0;\n            e = e | 0;\n            f = f | 0;\n            if (!(((b | 0) == 0) & ((c | 0) == 0)))\n                do {\n                    e = (e + -1) | 0;\n                    a[e >> 0] = d[(640 + (b & 15)) >> 0] | 0 | f;\n                    b = qr(b | 0, c | 0, 4) | 0;\n                    c = u() | 0;\n                } while (!(((b | 0) == 0) & ((c | 0) == 0)));\n            return e | 0;\n        }\n        function xo(b, c, d) {\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            if (!(((b | 0) == 0) & ((c | 0) == 0)))\n                do {\n                    d = (d + -1) | 0;\n                    a[d >> 0] = (b & 7) | 48;\n                    b = qr(b | 0, c | 0, 3) | 0;\n                    c = u() | 0;\n                } while (!(((b | 0) == 0) & ((c | 0) == 0)));\n            return d | 0;\n        }\n        function yo(b, c, d) {\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0;\n            if ((c >>> 0 > 0) | (((c | 0) == 0) & (b >>> 0 > 4294967295))) {\n                do {\n                    e = b;\n                    b = pr(b | 0, c | 0, 10, 0) | 0;\n                    f = c;\n                    c = u() | 0;\n                    g = kr(b | 0, c | 0, 10, 0) | 0;\n                    g = mr(e | 0, f | 0, g | 0, u() | 0) | 0;\n                    u() | 0;\n                    d = (d + -1) | 0;\n                    a[d >> 0] = (g & 255) | 48;\n                } while ((f >>> 0 > 9) | (((f | 0) == 9) & (e >>> 0 > 4294967295)));\n                c = b;\n            }\n            else\n                c = b;\n            if (c)\n                do {\n                    g = c;\n                    c = ((c >>> 0) / 10) | 0;\n                    d = (d + -1) | 0;\n                    a[d >> 0] = (g - ((c * 10) | 0)) | 48;\n                } while (g >>> 0 >= 10);\n            return d | 0;\n        }\n        function zo(a, b, c, d, e) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0;\n            g = V;\n            V = (V + 256) | 0;\n            f = g;\n            if (((c | 0) > (d | 0)) & (((e & 73728) | 0) == 0)) {\n                e = (c - d) | 0;\n                wr(f | 0, ((b << 24) >> 24) | 0, (e >>> 0 < 256 ? e : 256) | 0) | 0;\n                if (e >>> 0 > 255) {\n                    b = (c - d) | 0;\n                    do {\n                        to(a, f, 256);\n                        e = (e + -256) | 0;\n                    } while (e >>> 0 > 255);\n                    e = b & 255;\n                }\n                to(a, f, e);\n            }\n            V = g;\n            return;\n        }\n        function Ao(a, b) {\n            a = a | 0;\n            b = b | 0;\n            if (!a)\n                a = 0;\n            else\n                a = Bo(a, b, 0) | 0;\n            return a | 0;\n        }\n        function Bo(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            do\n                if (b) {\n                    if (d >>> 0 < 128) {\n                        a[b >> 0] = d;\n                        b = 1;\n                        break;\n                    }\n                    if (!(c[c[((Co() | 0) + 176) >> 2] >> 2] | 0))\n                        if (((d & -128) | 0) == 57216) {\n                            a[b >> 0] = d;\n                            b = 1;\n                            break;\n                        }\n                        else {\n                            c[(ao() | 0) >> 2] = 25;\n                            b = -1;\n                            break;\n                        }\n                    if (d >>> 0 < 2048) {\n                        a[b >> 0] = (d >>> 6) | 192;\n                        a[(b + 1) >> 0] = (d & 63) | 128;\n                        b = 2;\n                        break;\n                    }\n                    if ((d >>> 0 < 55296) | (((d & -8192) | 0) == 57344)) {\n                        a[b >> 0] = (d >>> 12) | 224;\n                        a[(b + 1) >> 0] = ((d >>> 6) & 63) | 128;\n                        a[(b + 2) >> 0] = (d & 63) | 128;\n                        b = 3;\n                        break;\n                    }\n                    if (((d + -65536) | 0) >>> 0 < 1048576) {\n                        a[b >> 0] = (d >>> 18) | 240;\n                        a[(b + 1) >> 0] = ((d >>> 12) & 63) | 128;\n                        a[(b + 2) >> 0] = ((d >>> 6) & 63) | 128;\n                        a[(b + 3) >> 0] = (d & 63) | 128;\n                        b = 4;\n                        break;\n                    }\n                    else {\n                        c[(ao() | 0) >> 2] = 25;\n                        b = -1;\n                        break;\n                    }\n                }\n                else\n                    b = 1;\n            while (0);\n            return b | 0;\n        }\n        function Co() {\n            return co() | 0;\n        }\n        function Do(a) {\n            a = +a;\n            var b = 0;\n            g[h >> 3] = a;\n            b = c[h >> 2] | 0;\n            t(c[(h + 4) >> 2] | 0);\n            return b | 0;\n        }\n        function Eo(a, b) {\n            a = +a;\n            b = b | 0;\n            var d = 0, e = 0, f = 0;\n            g[h >> 3] = a;\n            d = c[h >> 2] | 0;\n            e = c[(h + 4) >> 2] | 0;\n            f = qr(d | 0, e | 0, 52) | 0;\n            u() | 0;\n            switch (f & 2047) {\n                case 0: {\n                    if (a != 0.0) {\n                        a = +Eo(a * 18446744073709551616.0, b);\n                        d = ((c[b >> 2] | 0) + -64) | 0;\n                    }\n                    else\n                        d = 0;\n                    c[b >> 2] = d;\n                    break;\n                }\n                case 2047:\n                    break;\n                default: {\n                    c[b >> 2] = (f & 2047) + -1022;\n                    c[h >> 2] = d;\n                    c[(h + 4) >> 2] = (e & -2146435073) | 1071644672;\n                    a = +g[h >> 3];\n                }\n            }\n            return +a;\n        }\n        function Fo(b, c, d) {\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            a: do\n                if (!d)\n                    b = 0;\n                else {\n                    while (1) {\n                        e = a[b >> 0] | 0;\n                        f = a[c >> 0] | 0;\n                        if ((e << 24) >> 24 != (f << 24) >> 24)\n                            break;\n                        d = (d + -1) | 0;\n                        if (!d) {\n                            b = 0;\n                            break a;\n                        }\n                        else {\n                            b = (b + 1) | 0;\n                            c = (c + 1) | 0;\n                        }\n                    }\n                    b = ((e & 255) - (f & 255)) | 0;\n                }\n            while (0);\n            return b | 0;\n        }\n        function Go(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0;\n            f = V;\n            V = (V + 16) | 0;\n            g = f;\n            c[g >> 2] = e;\n            e = Ho(a, b, d, g) | 0;\n            V = f;\n            return e | 0;\n        }\n        function Ho(b, d, e, f) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0, h = 0, i = 0, j = 0;\n            j = V;\n            V = (V + 160) | 0;\n            g = (j + 144) | 0;\n            i = j;\n            ur(i | 0, 3672, 144) | 0;\n            if (((d + -1) | 0) >>> 0 > 2147483646)\n                if (!d) {\n                    b = g;\n                    d = 1;\n                    h = 4;\n                }\n                else {\n                    c[(ao() | 0) >> 2] = 61;\n                    d = -1;\n                }\n            else\n                h = 4;\n            if ((h | 0) == 4) {\n                h = (-2 - b) | 0;\n                h = d >>> 0 > h >>> 0 ? h : d;\n                c[(i + 48) >> 2] = h;\n                g = (i + 20) | 0;\n                c[g >> 2] = b;\n                c[(i + 44) >> 2] = b;\n                d = (b + h) | 0;\n                b = (i + 16) | 0;\n                c[b >> 2] = d;\n                c[(i + 28) >> 2] = d;\n                d = oo(i, e, f) | 0;\n                if (h) {\n                    i = c[g >> 2] | 0;\n                    a[(i + ((((i | 0) == (c[b >> 2] | 0)) << 31) >> 31)) >> 0] = 0;\n                }\n            }\n            V = j;\n            return d | 0;\n        }\n        function Io(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            e = (a + 20) | 0;\n            f = c[e >> 2] | 0;\n            a = ((c[(a + 16) >> 2] | 0) - f) | 0;\n            a = a >>> 0 > d >>> 0 ? d : a;\n            ur(f | 0, b | 0, a | 0) | 0;\n            c[e >> 2] = (c[e >> 2] | 0) + a;\n            return d | 0;\n        }\n        function Jo(a) {\n            a = a | 0;\n            var b = 0, c = 0;\n            b = ((fo(a) | 0) + 1) | 0;\n            c = dr(b) | 0;\n            if (!c)\n                a = 0;\n            else\n                a = ur(c | 0, a | 0, b | 0) | 0;\n            return a | 0;\n        }\n        function Ko(b, e) {\n            b = b | 0;\n            e = e | 0;\n            var f = 0, g = 0;\n            f = 0;\n            while (1) {\n                if ((d[(656 + f) >> 0] | 0) == (b | 0)) {\n                    g = 4;\n                    break;\n                }\n                f = (f + 1) | 0;\n                if ((f | 0) == 87) {\n                    b = 87;\n                    g = 5;\n                    break;\n                }\n            }\n            if ((g | 0) == 4)\n                if (!f)\n                    f = 752;\n                else {\n                    b = f;\n                    g = 5;\n                }\n            if ((g | 0) == 5) {\n                f = 752;\n                do {\n                    do {\n                        g = f;\n                        f = (f + 1) | 0;\n                    } while ((a[g >> 0] | 0) != 0);\n                    b = (b + -1) | 0;\n                } while ((b | 0) != 0);\n            }\n            return Lo(f, c[(e + 20) >> 2] | 0) | 0;\n        }\n        function Lo(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return ko(a, b) | 0;\n        }\n        function Mo(a) {\n            a = a | 0;\n            return Ko(a, c[((No() | 0) + 176) >> 2] | 0) | 0;\n        }\n        function No() {\n            return co() | 0;\n        }\n        function Oo(b, c, d) {\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            var e = 0;\n            e = Mo(b) | 0;\n            b = fo(e) | 0;\n            if (b >>> 0 >= d >>> 0) {\n                b = (d + -1) | 0;\n                if (!d)\n                    b = 68;\n                else {\n                    ur(c | 0, e | 0, b | 0) | 0;\n                    a[(c + b) >> 0] = 0;\n                    b = 68;\n                }\n            }\n            else {\n                ur(c | 0, e | 0, (b + 1) | 0) | 0;\n                b = 0;\n            }\n            return b | 0;\n        }\n        function Po() {\n            var a = 0, b = 0, d = 0, e = 0, f = 0, g = 0, h = 0;\n            e = V;\n            V = (V + 48) | 0;\n            g = (e + 32) | 0;\n            b = (e + 24) | 0;\n            h = (e + 16) | 0;\n            f = e;\n            e = (e + 36) | 0;\n            a = Qo() | 0;\n            if (a | 0 ? ((d = c[a >> 2] | 0), d | 0) : 0) {\n                a = (d + 48) | 0;\n                if (!(Ro(a) | 0)) {\n                    c[b >> 2] = 20420;\n                    To(20370, b);\n                }\n                b = So(a) | 0;\n                if (((b | 0) == 1126902529) & ((u() | 0) == 1129074247))\n                    a = c[(d + 44) >> 2] | 0;\n                else\n                    a = (d + 80) | 0;\n                c[e >> 2] = a;\n                d = c[d >> 2] | 0;\n                a = c[(d + 4) >> 2] | 0;\n                if (aa[c[((c[954] | 0) + 16) >> 2] & 7](3816, d, e) | 0) {\n                    h = c[e >> 2] | 0;\n                    h = Z[c[((c[h >> 2] | 0) + 8) >> 2] & 15](h) | 0;\n                    c[f >> 2] = 20420;\n                    c[(f + 4) >> 2] = a;\n                    c[(f + 8) >> 2] = h;\n                    To(20284, f);\n                }\n                else {\n                    c[h >> 2] = 20420;\n                    c[(h + 4) >> 2] = a;\n                    To(20329, h);\n                }\n            }\n            To(20408, g);\n        }\n        function Qo() {\n            return 21640;\n        }\n        function Ro(a) {\n            a = a | 0;\n            a = So(a) | 0;\n            return ((((a & -256) | 0) == 1126902528) & ((u() | 0) == 1129074247)) | 0;\n        }\n        function So(a) {\n            a = a | 0;\n            var b = 0;\n            b = a;\n            a = c[b >> 2] | 0;\n            t(c[(b + 4) >> 2] | 0);\n            return a | 0;\n        }\n        function To(a, b) {\n            a = a | 0;\n            b = b | 0;\n            U();\n        }\n        function Uo(a) {\n            a = a | 0;\n            return;\n        }\n        function Vo(a) {\n            a = a | 0;\n            Uo(a);\n            jp(a);\n            return;\n        }\n        function Wo(a) {\n            a = a | 0;\n            return;\n        }\n        function Xo(a) {\n            a = a | 0;\n            return;\n        }\n        function Yo(d, e, f) {\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0, h = 0, i = 0, j = 0, k = 0, l = 0;\n            l = V;\n            V = (V + 64) | 0;\n            j = l;\n            if (!(ap(d, e, 0) | 0))\n                if ((e | 0) != 0 ? ((k = ep(e, 3840, 3824, 0) | 0), (k | 0) != 0) : 0) {\n                    c[j >> 2] = k;\n                    c[(j + 4) >> 2] = 0;\n                    c[(j + 8) >> 2] = d;\n                    c[(j + 12) >> 2] = -1;\n                    d = (j + 16) | 0;\n                    e = (j + 24) | 0;\n                    g = (j + 48) | 0;\n                    h = d;\n                    i = (h + 36) | 0;\n                    do {\n                        c[h >> 2] = 0;\n                        h = (h + 4) | 0;\n                    } while ((h | 0) < (i | 0));\n                    b[(d + 36) >> 1] = 0;\n                    a[(d + 38) >> 0] = 0;\n                    c[g >> 2] = 1;\n                    fa[c[((c[k >> 2] | 0) + 28) >> 2] & 7](k, j, c[f >> 2] | 0, 1);\n                    if ((c[e >> 2] | 0) == 1) {\n                        c[f >> 2] = c[d >> 2];\n                        d = 1;\n                    }\n                    else\n                        d = 0;\n                }\n                else\n                    d = 0;\n            else\n                d = 1;\n            V = l;\n            return d | 0;\n        }\n        function Zo(a, b, d, e, f, g) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            if (ap(a, c[(b + 8) >> 2] | 0, g) | 0)\n                dp(0, b, d, e, f);\n            return;\n        }\n        function _o(b, d, e, f, g) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            var h = 0;\n            do\n                if (!(ap(b, c[(d + 8) >> 2] | 0, g) | 0)) {\n                    if (ap(b, c[d >> 2] | 0, g) | 0) {\n                        if ((c[(d + 16) >> 2] | 0) != (e | 0)\n                            ? ((h = (d + 20) | 0), (c[h >> 2] | 0) != (e | 0))\n                            : 0) {\n                            c[(d + 32) >> 2] = f;\n                            c[h >> 2] = e;\n                            g = (d + 40) | 0;\n                            c[g >> 2] = (c[g >> 2] | 0) + 1;\n                            if ((c[(d + 36) >> 2] | 0) == 1 ? (c[(d + 24) >> 2] | 0) == 2 : 0)\n                                a[(d + 54) >> 0] = 1;\n                            c[(d + 44) >> 2] = 4;\n                            break;\n                        }\n                        if ((f | 0) == 1)\n                            c[(d + 32) >> 2] = 1;\n                    }\n                }\n                else\n                    cp(0, d, e, f);\n            while (0);\n            return;\n        }\n        function $o(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            if (ap(a, c[(b + 8) >> 2] | 0, 0) | 0)\n                bp(0, b, d, e);\n            return;\n        }\n        function ap(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            if (d)\n                if ((a | 0) == (b | 0))\n                    a = 1;\n                else\n                    a = (eo(c[(a + 4) >> 2] | 0, c[(b + 4) >> 2] | 0) | 0) == 0;\n            else\n                a = (c[(a + 4) >> 2] | 0) == (c[(b + 4) >> 2] | 0);\n            return a | 0;\n        }\n        function bp(b, d, e, f) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0;\n            b = (d + 16) | 0;\n            g = c[b >> 2] | 0;\n            do\n                if (g) {\n                    if ((g | 0) != (e | 0)) {\n                        f = (d + 36) | 0;\n                        c[f >> 2] = (c[f >> 2] | 0) + 1;\n                        c[(d + 24) >> 2] = 2;\n                        a[(d + 54) >> 0] = 1;\n                        break;\n                    }\n                    b = (d + 24) | 0;\n                    if ((c[b >> 2] | 0) == 2)\n                        c[b >> 2] = f;\n                }\n                else {\n                    c[b >> 2] = e;\n                    c[(d + 24) >> 2] = f;\n                    c[(d + 36) >> 2] = 1;\n                }\n            while (0);\n            return;\n        }\n        function cp(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0;\n            if ((c[(b + 4) >> 2] | 0) == (d | 0) ? ((f = (b + 28) | 0), (c[f >> 2] | 0) != 1) : 0)\n                c[f >> 2] = e;\n            return;\n        }\n        function dp(b, d, e, f, g) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            a[(d + 53) >> 0] = 1;\n            do\n                if ((c[(d + 4) >> 2] | 0) == (f | 0)) {\n                    a[(d + 52) >> 0] = 1;\n                    b = (d + 16) | 0;\n                    f = c[b >> 2] | 0;\n                    if (!f) {\n                        c[b >> 2] = e;\n                        c[(d + 24) >> 2] = g;\n                        c[(d + 36) >> 2] = 1;\n                        if (!((g | 0) == 1 ? (c[(d + 48) >> 2] | 0) == 1 : 0))\n                            break;\n                        a[(d + 54) >> 0] = 1;\n                        break;\n                    }\n                    if ((f | 0) != (e | 0)) {\n                        g = (d + 36) | 0;\n                        c[g >> 2] = (c[g >> 2] | 0) + 1;\n                        a[(d + 54) >> 0] = 1;\n                        break;\n                    }\n                    f = (d + 24) | 0;\n                    b = c[f >> 2] | 0;\n                    if ((b | 0) == 2) {\n                        c[f >> 2] = g;\n                        b = g;\n                    }\n                    if ((b | 0) == 1 ? (c[(d + 48) >> 2] | 0) == 1 : 0)\n                        a[(d + 54) >> 0] = 1;\n                }\n            while (0);\n            return;\n        }\n        function ep(d, e, f, g) {\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            var h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0;\n            p = V;\n            V = (V + 64) | 0;\n            n = p;\n            m = c[d >> 2] | 0;\n            o = (d + (c[(m + -8) >> 2] | 0)) | 0;\n            m = c[(m + -4) >> 2] | 0;\n            c[n >> 2] = f;\n            c[(n + 4) >> 2] = d;\n            c[(n + 8) >> 2] = e;\n            c[(n + 12) >> 2] = g;\n            d = (n + 16) | 0;\n            e = (n + 20) | 0;\n            g = (n + 24) | 0;\n            h = (n + 28) | 0;\n            i = (n + 32) | 0;\n            j = (n + 40) | 0;\n            k = d;\n            l = (k + 36) | 0;\n            do {\n                c[k >> 2] = 0;\n                k = (k + 4) | 0;\n            } while ((k | 0) < (l | 0));\n            b[(d + 36) >> 1] = 0;\n            a[(d + 38) >> 0] = 0;\n            a: do\n                if (ap(m, f, 0) | 0) {\n                    c[(n + 48) >> 2] = 1;\n                    ha[c[((c[m >> 2] | 0) + 20) >> 2] & 3](m, n, o, o, 1, 0);\n                    d = (c[g >> 2] | 0) == 1 ? o : 0;\n                }\n                else {\n                    ga[c[((c[m >> 2] | 0) + 24) >> 2] & 3](m, n, o, 1, 0);\n                    switch (c[(n + 36) >> 2] | 0) {\n                        case 0: {\n                            d =\n                                ((c[j >> 2] | 0) == 1) & ((c[h >> 2] | 0) == 1) & ((c[i >> 2] | 0) == 1)\n                                    ? c[e >> 2] | 0\n                                    : 0;\n                            break a;\n                        }\n                        case 1:\n                            break;\n                        default: {\n                            d = 0;\n                            break a;\n                        }\n                    }\n                    if ((c[g >> 2] | 0) != 1\n                        ? !(((c[j >> 2] | 0) == 0) & ((c[h >> 2] | 0) == 1) & ((c[i >> 2] | 0) == 1))\n                        : 0) {\n                        d = 0;\n                        break;\n                    }\n                    d = c[d >> 2] | 0;\n                }\n            while (0);\n            V = p;\n            return d | 0;\n        }\n        function fp(a) {\n            a = a | 0;\n            Uo(a);\n            jp(a);\n            return;\n        }\n        function gp(a, b, d, e, f, g) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            if (ap(a, c[(b + 8) >> 2] | 0, g) | 0)\n                dp(0, b, d, e, f);\n            else {\n                a = c[(a + 8) >> 2] | 0;\n                ha[c[((c[a >> 2] | 0) + 20) >> 2] & 3](a, b, d, e, f, g);\n            }\n            return;\n        }\n        function hp(b, d, e, f, g) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            var h = 0, i = 0, j = 0;\n            a: do\n                if (!(ap(b, c[(d + 8) >> 2] | 0, g) | 0)) {\n                    if (!(ap(b, c[d >> 2] | 0, g) | 0)) {\n                        i = c[(b + 8) >> 2] | 0;\n                        ga[c[((c[i >> 2] | 0) + 24) >> 2] & 3](i, d, e, f, g);\n                        break;\n                    }\n                    if ((c[(d + 16) >> 2] | 0) != (e | 0) ? ((i = (d + 20) | 0), (c[i >> 2] | 0) != (e | 0)) : 0) {\n                        c[(d + 32) >> 2] = f;\n                        f = (d + 44) | 0;\n                        do\n                            if ((c[f >> 2] | 0) != 4) {\n                                h = (d + 52) | 0;\n                                a[h >> 0] = 0;\n                                j = (d + 53) | 0;\n                                a[j >> 0] = 0;\n                                b = c[(b + 8) >> 2] | 0;\n                                ha[c[((c[b >> 2] | 0) + 20) >> 2] & 3](b, d, e, e, 1, g);\n                                if (a[j >> 0] | 0) {\n                                    j = (a[h >> 0] | 0) == 0;\n                                    c[f >> 2] = 3;\n                                    if (j)\n                                        break;\n                                    else\n                                        break a;\n                                }\n                                else {\n                                    c[f >> 2] = 4;\n                                    break;\n                                }\n                            }\n                        while (0);\n                        c[i >> 2] = e;\n                        j = (d + 40) | 0;\n                        c[j >> 2] = (c[j >> 2] | 0) + 1;\n                        if ((c[(d + 36) >> 2] | 0) != 1)\n                            break;\n                        if ((c[(d + 24) >> 2] | 0) != 2)\n                            break;\n                        a[(d + 54) >> 0] = 1;\n                        break;\n                    }\n                    if ((f | 0) == 1)\n                        c[(d + 32) >> 2] = 1;\n                }\n                else\n                    cp(0, d, e, f);\n            while (0);\n            return;\n        }\n        function ip(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            if (ap(a, c[(b + 8) >> 2] | 0, 0) | 0)\n                bp(0, b, d, e);\n            else {\n                a = c[(a + 8) >> 2] | 0;\n                fa[c[((c[a >> 2] | 0) + 28) >> 2] & 7](a, b, d, e);\n            }\n            return;\n        }\n        function jp(a) {\n            a = a | 0;\n            er(a);\n            return;\n        }\n        function kp(a) {\n            a = a | 0;\n            return;\n        }\n        function lp() {\n            var a = 0, b = 0;\n            a = Qo() | 0;\n            if ((a | 0 ? ((b = c[a >> 2] | 0), b | 0) : 0) ? Ro((b + 48) | 0) | 0 : 0)\n                mp(c[(b + 12) >> 2] | 0);\n            mp(np() | 0);\n        }\n        function mp(a) {\n            a = a | 0;\n            var b = 0;\n            b = V;\n            V = (V + 16) | 0;\n            ba[a & 3]();\n            To(20559, b);\n        }\n        function np() {\n            return 2;\n        }\n        function op(a) {\n            a = a | 0;\n            return;\n        }\n        function pp(a) {\n            a = a | 0;\n            jp(a);\n            return;\n        }\n        function qp(a) {\n            a = a | 0;\n            return 20599;\n        }\n        function rp(a) {\n            a = a | 0;\n            c[a >> 2] = 5916;\n            vp((a + 4) | 0);\n            return;\n        }\n        function sp(a) {\n            a = a | 0;\n            rp(a);\n            jp(a);\n            return;\n        }\n        function tp(a) {\n            a = a | 0;\n            return up((a + 4) | 0) | 0;\n        }\n        function up(a) {\n            a = a | 0;\n            return c[a >> 2] | 0;\n        }\n        function vp(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            if (wp(a) | 0\n                ? ((b = xp(c[a >> 2] | 0) | 0),\n                    (d = (b + 8) | 0),\n                    (a = c[d >> 2] | 0),\n                    (c[d >> 2] = a + -1),\n                    (a | 0) < 1)\n                : 0)\n                jp(b);\n            return;\n        }\n        function wp(a) {\n            a = a | 0;\n            return 1;\n        }\n        function xp(a) {\n            a = a | 0;\n            return (a + -12) | 0;\n        }\n        function yp(a) {\n            a = a | 0;\n            c[a >> 2] = 5936;\n            vp((a + 4) | 0);\n            return;\n        }\n        function zp(a) {\n            a = a | 0;\n            yp(a);\n            jp(a);\n            return;\n        }\n        function Ap(a) {\n            a = a | 0;\n            return up((a + 4) | 0) | 0;\n        }\n        function Bp(a) {\n            a = a | 0;\n            rp(a);\n            jp(a);\n            return;\n        }\n        function Cp(a) {\n            a = a | 0;\n            rp(a);\n            jp(a);\n            return;\n        }\n        function Dp() {\n            var a = 0;\n            a = V;\n            V = (V + 16) | 0;\n            To(20848, a);\n        }\n        function Ep(a) {\n            a = a | 0;\n            Uo(a);\n            jp(a);\n            return;\n        }\n        function Fp(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            return ap(a, b, 0) | 0;\n        }\n        function Gp(a) {\n            a = a | 0;\n            Uo(a);\n            jp(a);\n            return;\n        }\n        function Hp(d, e, f) {\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0;\n            n = V;\n            V = (V + 64) | 0;\n            l = n;\n            do\n                if (!(ap(e, 4048, 0) | 0)) {\n                    if (Ip(d, e, 0) | 0) {\n                        e = c[f >> 2] | 0;\n                        if (!e) {\n                            e = 1;\n                            break;\n                        }\n                        c[f >> 2] = c[e >> 2];\n                        e = 1;\n                        break;\n                    }\n                    if ((e | 0) != 0 ? ((g = ep(e, 3840, 3976, 0) | 0), (g | 0) != 0) : 0) {\n                        e = c[f >> 2] | 0;\n                        if (e | 0)\n                            c[f >> 2] = c[e >> 2];\n                        e = c[(g + 8) >> 2] | 0;\n                        i = (d + 8) | 0;\n                        h = c[i >> 2] | 0;\n                        if (((e & 7 & (h ^ 7)) | 0) == 0 ? ((((e & 96) ^ 96) & h) | 0) == 0 : 0) {\n                            h = (d + 12) | 0;\n                            d = c[h >> 2] | 0;\n                            g = (g + 12) | 0;\n                            e = c[g >> 2] | 0;\n                            if (!(ap(d, e, 0) | 0)) {\n                                if (ap(d, 4040, 0) | 0) {\n                                    if (!e) {\n                                        e = 1;\n                                        break;\n                                    }\n                                    e = (ep(e, 3840, 3992, 0) | 0) == 0;\n                                    break;\n                                }\n                                if (d) {\n                                    e = ep(d, 3840, 3976, 0) | 0;\n                                    if (e | 0) {\n                                        if (!(c[i >> 2] & 1)) {\n                                            e = 0;\n                                            break;\n                                        }\n                                        e = Jp(e, c[g >> 2] | 0) | 0;\n                                        break;\n                                    }\n                                    e = c[h >> 2] | 0;\n                                    if (e) {\n                                        e = ep(e, 3840, 4008, 0) | 0;\n                                        if (e | 0) {\n                                            if (!(c[i >> 2] & 1)) {\n                                                e = 0;\n                                                break;\n                                            }\n                                            e = Kp(e, c[g >> 2] | 0) | 0;\n                                            break;\n                                        }\n                                        e = c[h >> 2] | 0;\n                                        if ((((e | 0) != 0 ? ((j = ep(e, 3840, 3824, 0) | 0), (j | 0) != 0) : 0)\n                                            ? ((k = c[g >> 2] | 0), (k | 0) != 0)\n                                            : 0)\n                                            ? ((m = ep(k, 3840, 3824, 0) | 0), (m | 0) != 0)\n                                            : 0) {\n                                            c[l >> 2] = m;\n                                            c[(l + 4) >> 2] = 0;\n                                            c[(l + 8) >> 2] = j;\n                                            c[(l + 12) >> 2] = -1;\n                                            e = (l + 16) | 0;\n                                            d = (l + 24) | 0;\n                                            g = (l + 48) | 0;\n                                            h = e;\n                                            i = (h + 36) | 0;\n                                            do {\n                                                c[h >> 2] = 0;\n                                                h = (h + 4) | 0;\n                                            } while ((h | 0) < (i | 0));\n                                            b[(e + 36) >> 1] = 0;\n                                            a[(e + 38) >> 0] = 0;\n                                            c[g >> 2] = 1;\n                                            fa[c[((c[m >> 2] | 0) + 28) >> 2] & 7](m, l, c[f >> 2] | 0, 1);\n                                            do\n                                                if ((c[d >> 2] | 0) == 1) {\n                                                    if (!(c[f >> 2] | 0)) {\n                                                        e = 1;\n                                                        break;\n                                                    }\n                                                    c[f >> 2] = c[e >> 2];\n                                                    e = 1;\n                                                }\n                                                else\n                                                    e = 0;\n                                            while (0);\n                                        }\n                                        else\n                                            e = 0;\n                                    }\n                                    else\n                                        e = 0;\n                                }\n                                else\n                                    e = 0;\n                            }\n                            else\n                                e = 1;\n                        }\n                        else\n                            e = 0;\n                    }\n                    else\n                        e = 0;\n                }\n                else {\n                    c[f >> 2] = 0;\n                    e = 1;\n                }\n            while (0);\n            V = n;\n            return e | 0;\n        }\n        function Ip(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            if (!(c[(a + 8) >> 2] & 24))\n                if ((b | 0) != 0 ? ((e = ep(b, 3840, 3960, 0) | 0), (e | 0) != 0) : 0) {\n                    d = ((c[(e + 8) >> 2] & 24) | 0) != 0;\n                    f = 5;\n                }\n                else\n                    d = 0;\n            else {\n                d = 1;\n                f = 5;\n            }\n            if ((f | 0) == 5)\n                d = ap(a, b, d) | 0;\n            return d | 0;\n        }\n        function Jp(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0, h = 0;\n            while (1) {\n                if (!b) {\n                    b = 0;\n                    break;\n                }\n                d = ep(b, 3840, 3976, 0) | 0;\n                if (!d) {\n                    b = 0;\n                    break;\n                }\n                f = c[(a + 8) >> 2] | 0;\n                if ((c[(d + 8) >> 2] & ~f) | 0) {\n                    b = 0;\n                    break;\n                }\n                e = (a + 12) | 0;\n                b = c[e >> 2] | 0;\n                d = (d + 12) | 0;\n                if (ap(b, c[d >> 2] | 0, 0) | 0) {\n                    b = 1;\n                    break;\n                }\n                if ((((f & 1) | 0) == 0) | ((b | 0) == 0)) {\n                    b = 0;\n                    break;\n                }\n                a = ep(b, 3840, 3976, 0) | 0;\n                if (!a) {\n                    h = 9;\n                    break;\n                }\n                b = c[d >> 2] | 0;\n            }\n            if ((h | 0) == 9) {\n                b = c[e >> 2] | 0;\n                if ((b | 0) != 0 ? ((g = ep(b, 3840, 4008, 0) | 0), (g | 0) != 0) : 0)\n                    b = Kp(g, c[d >> 2] | 0) | 0;\n                else\n                    b = 0;\n            }\n            return b | 0;\n        }\n        function Kp(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0;\n            if ((((b | 0) != 0 ? ((d = ep(b, 3840, 4008, 0) | 0), (d | 0) != 0) : 0)\n                ? ((c[(d + 8) >> 2] & ~c[(a + 8) >> 2]) | 0) == 0\n                : 0)\n                ? ap(c[(a + 12) >> 2] | 0, c[(d + 12) >> 2] | 0, 0) | 0\n                : 0)\n                a = ap(c[(a + 16) >> 2] | 0, c[(d + 16) >> 2] | 0, 0) | 0;\n            else\n                a = 0;\n            return a | 0;\n        }\n        function Lp(a) {\n            a = a | 0;\n            Uo(a);\n            jp(a);\n            return;\n        }\n        function Mp(b, d, e, f, g, h) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            h = h | 0;\n            var i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0;\n            if (ap(b, c[(d + 8) >> 2] | 0, h) | 0)\n                dp(0, d, e, f, g);\n            else {\n                r = (d + 52) | 0;\n                j = a[r >> 0] | 0;\n                q = (d + 53) | 0;\n                i = a[q >> 0] | 0;\n                p = c[(b + 12) >> 2] | 0;\n                m = (b + 16 + (p << 3)) | 0;\n                a[r >> 0] = 0;\n                a[q >> 0] = 0;\n                Qp((b + 16) | 0, d, e, f, g, h);\n                k = a[r >> 0] | 0;\n                j = k | j;\n                l = a[q >> 0] | 0;\n                i = l | i;\n                a: do\n                    if ((p | 0) > 1) {\n                        n = (d + 24) | 0;\n                        o = (b + 8) | 0;\n                        p = (d + 54) | 0;\n                        b = (b + 24) | 0;\n                        do {\n                            i = i & 1;\n                            j = j & 1;\n                            if (a[p >> 0] | 0)\n                                break a;\n                            if (!((k << 24) >> 24)) {\n                                if ((l << 24) >> 24 ? ((c[o >> 2] & 1) | 0) == 0 : 0)\n                                    break a;\n                            }\n                            else {\n                                if ((c[n >> 2] | 0) == 1)\n                                    break a;\n                                if (!(c[o >> 2] & 2))\n                                    break a;\n                            }\n                            a[r >> 0] = 0;\n                            a[q >> 0] = 0;\n                            Qp(b, d, e, f, g, h);\n                            k = a[r >> 0] | 0;\n                            j = k | j;\n                            l = a[q >> 0] | 0;\n                            i = l | i;\n                            b = (b + 8) | 0;\n                        } while (b >>> 0 < m >>> 0);\n                    }\n                while (0);\n                a[r >> 0] = ((j << 24) >> 24 != 0) & 1;\n                a[q >> 0] = ((i << 24) >> 24 != 0) & 1;\n            }\n            return;\n        }\n        function Np(b, d, e, f, g) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            var h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0;\n            a: do\n                if (!(ap(b, c[(d + 8) >> 2] | 0, g) | 0)) {\n                    if (!(ap(b, c[d >> 2] | 0, g) | 0)) {\n                        p = c[(b + 12) >> 2] | 0;\n                        k = (b + 16 + (p << 3)) | 0;\n                        Rp((b + 16) | 0, d, e, f, g);\n                        h = (b + 24) | 0;\n                        if ((p | 0) <= 1)\n                            break;\n                        b = c[(b + 8) >> 2] | 0;\n                        if (((b & 2) | 0) == 0 ? ((j = (d + 36) | 0), (c[j >> 2] | 0) != 1) : 0) {\n                            if (!(b & 1)) {\n                                b = (d + 54) | 0;\n                                while (1) {\n                                    if (a[b >> 0] | 0)\n                                        break a;\n                                    if ((c[j >> 2] | 0) == 1)\n                                        break a;\n                                    Rp(h, d, e, f, g);\n                                    h = (h + 8) | 0;\n                                    if (h >>> 0 >= k >>> 0)\n                                        break a;\n                                }\n                            }\n                            b = (d + 24) | 0;\n                            i = (d + 54) | 0;\n                            while (1) {\n                                if (a[i >> 0] | 0)\n                                    break a;\n                                if ((c[j >> 2] | 0) == 1 ? (c[b >> 2] | 0) == 1 : 0)\n                                    break a;\n                                Rp(h, d, e, f, g);\n                                h = (h + 8) | 0;\n                                if (h >>> 0 >= k >>> 0)\n                                    break a;\n                            }\n                        }\n                        b = (d + 54) | 0;\n                        while (1) {\n                            if (a[b >> 0] | 0)\n                                break a;\n                            Rp(h, d, e, f, g);\n                            h = (h + 8) | 0;\n                            if (h >>> 0 >= k >>> 0)\n                                break a;\n                        }\n                    }\n                    if ((c[(d + 16) >> 2] | 0) != (e | 0) ? ((p = (d + 20) | 0), (c[p >> 2] | 0) != (e | 0)) : 0) {\n                        c[(d + 32) >> 2] = f;\n                        o = (d + 44) | 0;\n                        if ((c[o >> 2] | 0) != 4) {\n                            j = (b + 16 + (c[(b + 12) >> 2] << 3)) | 0;\n                            k = (d + 52) | 0;\n                            f = (d + 53) | 0;\n                            l = (d + 54) | 0;\n                            m = (b + 8) | 0;\n                            n = (d + 24) | 0;\n                            h = 0;\n                            i = (b + 16) | 0;\n                            b = 0;\n                            b: while (1) {\n                                if (i >>> 0 >= j >>> 0) {\n                                    i = 18;\n                                    break;\n                                }\n                                a[k >> 0] = 0;\n                                a[f >> 0] = 0;\n                                Qp(i, d, e, e, 1, g);\n                                if (a[l >> 0] | 0) {\n                                    i = 18;\n                                    break;\n                                }\n                                do\n                                    if (a[f >> 0] | 0) {\n                                        if (!(a[k >> 0] | 0))\n                                            if (!(c[m >> 2] & 1)) {\n                                                i = 19;\n                                                break b;\n                                            }\n                                            else {\n                                                b = 1;\n                                                break;\n                                            }\n                                        if ((c[n >> 2] | 0) == 1) {\n                                            h = 1;\n                                            i = 19;\n                                            break b;\n                                        }\n                                        if (!(c[m >> 2] & 2)) {\n                                            h = 1;\n                                            i = 19;\n                                            break b;\n                                        }\n                                        else {\n                                            h = 1;\n                                            b = 1;\n                                        }\n                                    }\n                                while (0);\n                                i = (i + 8) | 0;\n                            }\n                            if ((i | 0) == 18)\n                                if (b)\n                                    i = 19;\n                                else\n                                    b = 4;\n                            if ((i | 0) == 19)\n                                b = 3;\n                            c[o >> 2] = b;\n                            if (h & 1)\n                                break;\n                        }\n                        c[p >> 2] = e;\n                        e = (d + 40) | 0;\n                        c[e >> 2] = (c[e >> 2] | 0) + 1;\n                        if ((c[(d + 36) >> 2] | 0) != 1)\n                            break;\n                        if ((c[(d + 24) >> 2] | 0) != 2)\n                            break;\n                        a[(d + 54) >> 0] = 1;\n                        break;\n                    }\n                    if ((f | 0) == 1)\n                        c[(d + 32) >> 2] = 1;\n                }\n                else\n                    cp(0, d, e, f);\n            while (0);\n            return;\n        }\n        function Op(b, d, e, f) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0, h = 0;\n            a: do\n                if (!(ap(b, c[(d + 8) >> 2] | 0, 0) | 0)) {\n                    h = c[(b + 12) >> 2] | 0;\n                    g = (b + 16 + (h << 3)) | 0;\n                    Pp((b + 16) | 0, d, e, f);\n                    if ((h | 0) > 1) {\n                        h = (d + 54) | 0;\n                        b = (b + 24) | 0;\n                        do {\n                            Pp(b, d, e, f);\n                            if (a[h >> 0] | 0)\n                                break a;\n                            b = (b + 8) | 0;\n                        } while (b >>> 0 < g >>> 0);\n                    }\n                }\n                else\n                    bp(0, d, e, f);\n            while (0);\n            return;\n        }\n        function Pp(a, b, d, e) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0;\n            g = c[(a + 4) >> 2] | 0;\n            if (d) {\n                f = g >> 8;\n                if (g & 1)\n                    f = c[((c[d >> 2] | 0) + f) >> 2] | 0;\n            }\n            else\n                f = 0;\n            a = c[a >> 2] | 0;\n            fa[c[((c[a >> 2] | 0) + 28) >> 2] & 7](a, b, (d + f) | 0, ((g & 2) | 0) == 0 ? 2 : e);\n            return;\n        }\n        function Qp(a, b, d, e, f, g) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            var h = 0, i = 0;\n            i = c[(a + 4) >> 2] | 0;\n            h = i >> 8;\n            if (i & 1)\n                h = c[((c[e >> 2] | 0) + h) >> 2] | 0;\n            a = c[a >> 2] | 0;\n            ha[c[((c[a >> 2] | 0) + 20) >> 2] & 3](a, b, d, (e + h) | 0, ((i & 2) | 0) == 0 ? 2 : f, g);\n            return;\n        }\n        function Rp(a, b, d, e, f) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0, h = 0;\n            h = c[(a + 4) >> 2] | 0;\n            g = h >> 8;\n            if (h & 1)\n                g = c[((c[d >> 2] | 0) + g) >> 2] | 0;\n            a = c[a >> 2] | 0;\n            ga[c[((c[a >> 2] | 0) + 24) >> 2] & 3](a, b, (d + g) | 0, ((h & 2) | 0) == 0 ? 2 : e, f);\n            return;\n        }\n        function Sp(a) {\n            a = a | 0;\n            c[a >> 2] = 5896;\n            return;\n        }\n        function Tp(a) {\n            a = a | 0;\n            var b = 0, c = 0;\n            b = V;\n            V = (V + 16) | 0;\n            c = b;\n            Up(c, a);\n            a = Vp(c) | 0;\n            V = b;\n            return a | 0;\n        }\n        function Up(a, b) {\n            a = a | 0;\n            b = b | 0;\n            _p(a, b);\n            return;\n        }\n        function Vp(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            Wp(d, c[(a + 4) >> 2] | 0);\n            if (!(((Xp(d) | 0) << 24) >> 24))\n                a = Zp(Yp(a) | 0) | 0;\n            else\n                a = 0;\n            V = b;\n            return a | 0;\n        }\n        function Wp(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = b;\n            return;\n        }\n        function Xp(b) {\n            b = b | 0;\n            return a[c[b >> 2] >> 0] | 0;\n        }\n        function Yp(a) {\n            a = a | 0;\n            return a | 0;\n        }\n        function Zp(b) {\n            b = b | 0;\n            var d = 0, e = 0, f = 0, g = 0;\n            g = V;\n            V = (V + 16) | 0;\n            f = g;\n            b = c[(b + 8) >> 2] | 0;\n            d = a[b >> 0] | 0;\n            do\n                if ((d << 24) >> 24 != 1)\n                    if (!(d & 2)) {\n                        a[b >> 0] = 2;\n                        e = 1;\n                        break;\n                    }\n                    else\n                        To(20985, f);\n                else\n                    e = 0;\n            while (0);\n            V = g;\n            return e | 0;\n        }\n        function _p(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = b;\n            c[(a + 4) >> 2] = b;\n            c[(a + 8) >> 2] = b + 1;\n            c[(a + 12) >> 2] = 0;\n            return;\n        }\n        function $p(a) {\n            a = a | 0;\n            var b = 0, c = 0;\n            b = V;\n            V = (V + 16) | 0;\n            c = b;\n            Up(c, a);\n            aq(c);\n            V = b;\n            return;\n        }\n        function aq(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = V;\n            V = (V + 16) | 0;\n            d = b;\n            Wp(d, c[(a + 4) >> 2] | 0);\n            bq(d);\n            cq(Yp(a) | 0);\n            V = b;\n            return;\n        }\n        function bq(b) {\n            b = b | 0;\n            a[c[b >> 2] >> 0] = 1;\n            return;\n        }\n        function cq(b) {\n            b = b | 0;\n            a[c[(b + 8) >> 2] >> 0] = 1;\n            return;\n        }\n        function dq() {\n            return 0;\n        }\n        function eq(a) {\n            a = a | 0;\n            var b = 0, c = 0;\n            c = (a | 0) == 0 ? 1 : a;\n            while (1) {\n                b = dr(c) | 0;\n                if (b | 0) {\n                    a = 6;\n                    break;\n                }\n                a = dq() | 0;\n                if (!a) {\n                    a = 5;\n                    break;\n                }\n                ba[a & 3]();\n            }\n            if ((a | 0) == 5) {\n                c = v(4) | 0;\n                Sp(c);\n                x(c | 0, 3880, 121);\n            }\n            else if ((a | 0) == 6)\n                return b | 0;\n            return 0;\n        }\n        function fq(a) {\n            a = a | 0;\n            return eq(a) | 0;\n        }\n        function gq(a) {\n            a = a | 0;\n            jp(a);\n            return;\n        }\n        function hq(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            f = V;\n            V = (V + 16) | 0;\n            e = f;\n            c[e >> 2] = c[d >> 2];\n            a = aa[c[((c[a >> 2] | 0) + 16) >> 2] & 7](a, b, e) | 0;\n            if (a)\n                c[d >> 2] = c[e >> 2];\n            V = f;\n            return (a & 1) | 0;\n        }\n        function iq(a) {\n            a = a | 0;\n            if (!a)\n                a = 0;\n            else\n                a = ((ep(a, 3840, 3976, 0) | 0) != 0) & 1;\n            return a | 0;\n        }\n        function jq(a) {\n            a = a | 0;\n            return 0;\n        }\n        function kq() {\n            return ((lq() | 0) > 0) | 0;\n        }\n        function lq() {\n            return y() | 0;\n        }\n        function mq(a) {\n            a = a | 0;\n            return;\n        }\n        function nq(a) {\n            a = a | 0;\n            mq(a);\n            jp(a);\n            return;\n        }\n        function oq(a) {\n            a = a | 0;\n            return 21039;\n        }\n        function pq(a) {\n            a = a | 0;\n            return;\n        }\n        function qq(a) {\n            a = a | 0;\n            var b = 0, d = 0;\n            b = (a + 8) | 0;\n            if (!((c[b >> 2] | 0) != 0 ? ((d = c[b >> 2] | 0), (c[b >> 2] = d + -1), (d | 0) != 0) : 0))\n                ca[c[((c[a >> 2] | 0) + 16) >> 2] & 255](a);\n            return;\n        }\n        function rq(a) {\n            a = a | 0;\n            a = jq(a) | 0;\n            if (!a)\n                return;\n            else\n                br(a, 21145);\n        }\n        function sq(a) {\n            a = a | 0;\n            return;\n        }\n        function tq(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0;\n            e = fo(b) | 0;\n            d = eq((e + 13) | 0) | 0;\n            c[d >> 2] = e;\n            c[(d + 4) >> 2] = e;\n            c[(d + 8) >> 2] = 0;\n            d = uq(d) | 0;\n            ur(d | 0, b | 0, (e + 1) | 0) | 0;\n            c[a >> 2] = d;\n            return;\n        }\n        function uq(a) {\n            a = a | 0;\n            return (a + 12) | 0;\n        }\n        function vq(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = 5916;\n            tq((a + 4) | 0, b);\n            return;\n        }\n        function wq(b, d) {\n            b = b | 0;\n            d = d | 0;\n            c[b >> 2] = 5936;\n            tq((b + 4) | 0, (a[(d + 11) >> 0] | 0) < 0 ? c[d >> 2] | 0 : d);\n            return;\n        }\n        function xq(a, b) {\n            a = a | 0;\n            b = b | 0;\n            c[a >> 2] = 5936;\n            tq((a + 4) | 0, b);\n            return;\n        }\n        function yq(a) {\n            a = a | 0;\n            a = v(8) | 0;\n            vq(a, 21163);\n            c[a >> 2] = 5956;\n            x(a | 0, 3928, 123);\n        }\n        function zq(a) {\n            a = a | 0;\n            a = v(8) | 0;\n            vq(a, 21163);\n            c[a >> 2] = 5976;\n            x(a | 0, 3944, 123);\n        }\n        function Aq(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0, i = 0;\n            g = V;\n            V = (V + 16) | 0;\n            f = g;\n            if (e >>> 0 > 4294967279)\n                yq(b);\n            if (e >>> 0 < 11)\n                a[(b + 11) >> 0] = e;\n            else {\n                i = (e + 16) & -16;\n                h = eq(i) | 0;\n                c[b >> 2] = h;\n                c[(b + 8) >> 2] = i | -2147483648;\n                c[(b + 4) >> 2] = e;\n                b = h;\n            }\n            Bq(b, d, e) | 0;\n            a[f >> 0] = 0;\n            nb((b + e) | 0, f);\n            V = g;\n            return;\n        }\n        function Bq(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            if (c | 0)\n                ur(a | 0, b | 0, c | 0) | 0;\n            return a | 0;\n        }\n        function Cq(b) {\n            b = b | 0;\n            if ((a[(b + 11) >> 0] | 0) < 0)\n                Da(c[b >> 2] | 0, c[(b + 8) >> 2] & 2147483647);\n            return;\n        }\n        function Dq(b, d, e, f, g, h, i, j) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            h = h | 0;\n            i = i | 0;\n            j = j | 0;\n            var k = 0, l = 0, m = 0, n = 0, o = 0;\n            o = V;\n            V = (V + 16) | 0;\n            n = o;\n            if (((-18 - d) | 0) >>> 0 < e >>> 0)\n                yq(b);\n            if ((a[(b + 11) >> 0] | 0) < 0)\n                m = c[b >> 2] | 0;\n            else\n                m = b;\n            if (d >>> 0 < 2147483623) {\n                k = (e + d) | 0;\n                l = d << 1;\n                k = k >>> 0 < l >>> 0 ? l : k;\n                k = k >>> 0 < 11 ? 11 : (k + 16) & -16;\n            }\n            else\n                k = -17;\n            l = eq(k) | 0;\n            if (g | 0)\n                Bq(l, m, g) | 0;\n            if (i | 0)\n                Bq((l + g) | 0, j, i) | 0;\n            f = (f - h) | 0;\n            e = (f - g) | 0;\n            if (e | 0)\n                Bq((l + g + i) | 0, (m + g + h) | 0, e) | 0;\n            e = (d + 1) | 0;\n            if ((e | 0) != 11)\n                Da(m, e);\n            c[b >> 2] = l;\n            c[(b + 8) >> 2] = k | -2147483648;\n            i = (f + i) | 0;\n            c[(b + 4) >> 2] = i;\n            a[n >> 0] = 0;\n            nb((l + i) | 0, n);\n            V = o;\n            return;\n        }\n        function Eq(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0;\n            k = V;\n            V = (V + 16) | 0;\n            i = k;\n            j = (b + 11) | 0;\n            f = a[j >> 0] | 0;\n            h = (f << 24) >> 24 < 0;\n            if (h) {\n                g = ((c[(b + 8) >> 2] & 2147483647) + -1) | 0;\n                f = c[(b + 4) >> 2] | 0;\n            }\n            else {\n                g = 10;\n                f = f & 255;\n            }\n            if (((g - f) | 0) >>> 0 >= e >>> 0) {\n                if (e | 0) {\n                    if (h)\n                        g = c[b >> 2] | 0;\n                    else\n                        g = b;\n                    Bq((g + f) | 0, d, e) | 0;\n                    f = (f + e) | 0;\n                    if ((a[j >> 0] | 0) < 0)\n                        c[(b + 4) >> 2] = f;\n                    else\n                        a[j >> 0] = f;\n                    a[i >> 0] = 0;\n                    nb((g + f) | 0, i);\n                }\n            }\n            else\n                Dq(b, g, (f + e - g) | 0, f, f, 0, e, d);\n            V = k;\n            return b | 0;\n        }\n        function Fq(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return Eq(a, b, lb(b) | 0) | 0;\n        }\n        function Gq(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            if (!c)\n                a = 0;\n            else\n                a = Fo(a, b, c) | 0;\n            return a | 0;\n        }\n        function Hq(b, d, e, f, g) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            var h = 0, i = 0;\n            h = a[(b + 11) >> 0] | 0;\n            i = (h << 24) >> 24 < 0;\n            if (i)\n                h = c[(b + 4) >> 2] | 0;\n            else\n                h = h & 255;\n            if (((g | 0) == -1) | (h >>> 0 < d >>> 0))\n                zq(b);\n            h = (h - d) | 0;\n            e = h >>> 0 < e >>> 0 ? h : e;\n            if (i)\n                b = c[b >> 2] | 0;\n            h = e >>> 0 > g >>> 0;\n            b = Gq((b + d) | 0, f, h ? g : e) | 0;\n            if (!b)\n                return (e >>> 0 < g >>> 0 ? -1 : h & 1) | 0;\n            else\n                return b | 0;\n            return 0;\n        }\n        function Iq(a) {\n            a = a | 0;\n            return;\n        }\n        function Jq(a) {\n            a = a | 0;\n            jp(a);\n            return;\n        }\n        function Kq(a) {\n            a = a | 0;\n            return 21228;\n        }\n        function Lq(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            c[a >> 2] = d;\n            c[(a + 4) >> 2] = b;\n            return;\n        }\n        function Mq(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            f = V;\n            V = (V + 16) | 0;\n            e = f;\n            ea[c[((c[a >> 2] | 0) + 12) >> 2] & 15](e, a, b);\n            if ((c[(e + 4) >> 2] | 0) == (c[(d + 4) >> 2] | 0))\n                a = (c[e >> 2] | 0) == (c[d >> 2] | 0);\n            else\n                a = 0;\n            V = f;\n            return a | 0;\n        }\n        function Nq(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            return ((c[b >> 2] | 0) == (d | 0) ? (c[(b + 4) >> 2] | 0) == (a | 0) : 0) | 0;\n        }\n        function Oq(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            if ((c | 0) > 256)\n                Aq(a, 21176, lb(21176) | 0);\n            else\n                Pq(a, 0, c);\n            return;\n        }\n        function Pq(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            Qq(a, c);\n            return;\n        }\n        function Qq(b, d) {\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0, h = 0, i = 0;\n            i = V;\n            V = (V + 1040) | 0;\n            g = (i + 1024) | 0;\n            e = i;\n            h = c[(ao() | 0) >> 2] | 0;\n            f = Rq(Oo(d, e, 1024) | 0, e) | 0;\n            if (!(a[f >> 0] | 0)) {\n                c[g >> 2] = d;\n                Go(e, 1024, 21211, g) | 0;\n            }\n            else\n                e = f;\n            c[(ao() | 0) >> 2] = h;\n            Aq(b, e, lb(e) | 0);\n            V = i;\n            return;\n        }\n        function Rq(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0;\n            switch (a | 0) {\n                case 0: {\n                    d = b;\n                    break;\n                }\n                case -1: {\n                    a = c[(ao() | 0) >> 2] | 0;\n                    e = 3;\n                    break;\n                }\n                default:\n                    e = 3;\n            }\n            if ((e | 0) == 3)\n                if ((a | 0) == 28)\n                    d = 22145;\n                else\n                    P();\n            return d | 0;\n        }\n        function Sq(a) {\n            a = a | 0;\n            jp(a);\n            return;\n        }\n        function Tq(a) {\n            a = a | 0;\n            return 21353;\n        }\n        function Uq(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            if ((d | 0) > 256) {\n                Wq() | 0;\n                b = 6180;\n            }\n            else {\n                Xq() | 0;\n                b = 6176;\n            }\n            c[a >> 2] = d;\n            c[(a + 4) >> 2] = b;\n            return;\n        }\n        function Vq(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            if ((c | 0) > 256)\n                Aq(a, 21319, lb(21319) | 0);\n            else\n                Pq(a, 0, c);\n            return;\n        }\n        function Wq() {\n            if ((a[21488] | 0) == 0 ? Tp(21488) | 0 : 0)\n                $p(21488);\n            return 6180;\n        }\n        function Xq() {\n            if ((a[21480] | 0) == 0 ? Tp(21480) | 0 : 0)\n                $p(21480);\n            return 6176;\n        }\n        function Yq(a) {\n            a = a | 0;\n            yp(a);\n            return;\n        }\n        function Zq(a) {\n            a = a | 0;\n            Yq(a);\n            jp(a);\n            return;\n        }\n        function _q(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0;\n            d = c[(b + 4) >> 2] | 0;\n            ea[c[((c[d >> 2] | 0) + 24) >> 2] & 15](a, d, c[b >> 2] | 0);\n            return;\n        }\n        function $q(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0;\n            h = V;\n            V = (V + 16) | 0;\n            g = h;\n            if (c[d >> 2] | 0) {\n                f = a[(e + 11) >> 0] | 0;\n                if ((f << 24) >> 24 < 0)\n                    f = c[(e + 4) >> 2] | 0;\n                else\n                    f = f & 255;\n                if (f | 0)\n                    Fq(e, 21417) | 0;\n                _q(g, d);\n                d = a[(g + 11) >> 0] | 0;\n                f = (d << 24) >> 24 < 0;\n                Eq(e, f ? c[g >> 2] | 0 : g, f ? c[(g + 4) >> 2] | 0 : d & 255) | 0;\n                Cq(g);\n            }\n            c[b >> 2] = c[e >> 2];\n            c[(b + 4) >> 2] = c[(e + 4) >> 2];\n            c[(b + 8) >> 2] = c[(e + 8) >> 2];\n            f = 0;\n            while (1) {\n                if ((f | 0) == 3)\n                    break;\n                c[(e + (f << 2)) >> 2] = 0;\n                f = (f + 1) | 0;\n            }\n            V = h;\n            return;\n        }\n        function ar(a, b, d) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            var e = 0, f = 0, g = 0;\n            e = V;\n            V = (V + 32) | 0;\n            g = (e + 12) | 0;\n            f = e;\n            Aq(f, d, lb(d) | 0);\n            $q(g, b, f);\n            wq(a, g);\n            Cq(g);\n            Cq(f);\n            c[a >> 2] = 6192;\n            f = b;\n            b = c[(f + 4) >> 2] | 0;\n            d = (a + 8) | 0;\n            c[d >> 2] = c[f >> 2];\n            c[(d + 4) >> 2] = b;\n            V = e;\n            return;\n        }\n        function br(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var d = 0, e = 0, f = 0;\n            f = V;\n            V = (V + 16) | 0;\n            e = (f + 8) | 0;\n            d = v(16) | 0;\n            Wq() | 0;\n            c[f >> 2] = a;\n            c[(f + 4) >> 2] = 6180;\n            c[e >> 2] = c[f >> 2];\n            c[(e + 4) >> 2] = c[(f + 4) >> 2];\n            ar(d, e, b);\n            x(d | 0, 4272, 136);\n        }\n        function cr(a) {\n            a = a | 0;\n            a = v(8) | 0;\n            vq(a, 21420);\n            c[a >> 2] = 5956;\n            x(a | 0, 3928, 123);\n        }\n        function dr(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0;\n            w = V;\n            V = (V + 16) | 0;\n            n = w;\n            do\n                if (a >>> 0 < 245) {\n                    k = a >>> 0 < 11 ? 16 : (a + 11) & -8;\n                    a = k >>> 3;\n                    m = c[5412] | 0;\n                    d = m >>> a;\n                    if ((d & 3) | 0) {\n                        b = (((d & 1) ^ 1) + a) | 0;\n                        a = (21688 + ((b << 1) << 2)) | 0;\n                        d = (a + 8) | 0;\n                        e = c[d >> 2] | 0;\n                        f = (e + 8) | 0;\n                        g = c[f >> 2] | 0;\n                        if ((g | 0) == (a | 0))\n                            c[5412] = m & ~(1 << b);\n                        else {\n                            c[(g + 12) >> 2] = a;\n                            c[d >> 2] = g;\n                        }\n                        v = b << 3;\n                        c[(e + 4) >> 2] = v | 3;\n                        v = (e + v + 4) | 0;\n                        c[v >> 2] = c[v >> 2] | 1;\n                        v = f;\n                        V = w;\n                        return v | 0;\n                    }\n                    l = c[5414] | 0;\n                    if (k >>> 0 > l >>> 0) {\n                        if (d | 0) {\n                            b = 2 << a;\n                            b = (d << a) & (b | (0 - b));\n                            b = ((b & (0 - b)) + -1) | 0;\n                            i = (b >>> 12) & 16;\n                            b = b >>> i;\n                            d = (b >>> 5) & 8;\n                            b = b >>> d;\n                            g = (b >>> 2) & 4;\n                            b = b >>> g;\n                            a = (b >>> 1) & 2;\n                            b = b >>> a;\n                            e = (b >>> 1) & 1;\n                            e = ((d | i | g | a | e) + (b >>> e)) | 0;\n                            b = (21688 + ((e << 1) << 2)) | 0;\n                            a = (b + 8) | 0;\n                            g = c[a >> 2] | 0;\n                            i = (g + 8) | 0;\n                            d = c[i >> 2] | 0;\n                            if ((d | 0) == (b | 0)) {\n                                a = m & ~(1 << e);\n                                c[5412] = a;\n                            }\n                            else {\n                                c[(d + 12) >> 2] = b;\n                                c[a >> 2] = d;\n                                a = m;\n                            }\n                            v = e << 3;\n                            h = (v - k) | 0;\n                            c[(g + 4) >> 2] = k | 3;\n                            f = (g + k) | 0;\n                            c[(f + 4) >> 2] = h | 1;\n                            c[(g + v) >> 2] = h;\n                            if (l | 0) {\n                                e = c[5417] | 0;\n                                b = l >>> 3;\n                                d = (21688 + ((b << 1) << 2)) | 0;\n                                b = 1 << b;\n                                if (!(a & b)) {\n                                    c[5412] = a | b;\n                                    b = d;\n                                    a = (d + 8) | 0;\n                                }\n                                else {\n                                    a = (d + 8) | 0;\n                                    b = c[a >> 2] | 0;\n                                }\n                                c[a >> 2] = e;\n                                c[(b + 12) >> 2] = e;\n                                c[(e + 8) >> 2] = b;\n                                c[(e + 12) >> 2] = d;\n                            }\n                            c[5414] = h;\n                            c[5417] = f;\n                            v = i;\n                            V = w;\n                            return v | 0;\n                        }\n                        g = c[5413] | 0;\n                        if (g) {\n                            d = ((g & (0 - g)) + -1) | 0;\n                            f = (d >>> 12) & 16;\n                            d = d >>> f;\n                            e = (d >>> 5) & 8;\n                            d = d >>> e;\n                            h = (d >>> 2) & 4;\n                            d = d >>> h;\n                            i = (d >>> 1) & 2;\n                            d = d >>> i;\n                            j = (d >>> 1) & 1;\n                            j = c[(21952 + (((e | f | h | i | j) + (d >>> j)) << 2)) >> 2] | 0;\n                            d = j;\n                            i = j;\n                            j = ((c[(j + 4) >> 2] & -8) - k) | 0;\n                            while (1) {\n                                a = c[(d + 16) >> 2] | 0;\n                                if (!a) {\n                                    a = c[(d + 20) >> 2] | 0;\n                                    if (!a)\n                                        break;\n                                }\n                                h = ((c[(a + 4) >> 2] & -8) - k) | 0;\n                                f = h >>> 0 < j >>> 0;\n                                d = a;\n                                i = f ? a : i;\n                                j = f ? h : j;\n                            }\n                            h = (i + k) | 0;\n                            if (h >>> 0 > i >>> 0) {\n                                f = c[(i + 24) >> 2] | 0;\n                                b = c[(i + 12) >> 2] | 0;\n                                do\n                                    if ((b | 0) == (i | 0)) {\n                                        a = (i + 20) | 0;\n                                        b = c[a >> 2] | 0;\n                                        if (!b) {\n                                            a = (i + 16) | 0;\n                                            b = c[a >> 2] | 0;\n                                            if (!b) {\n                                                d = 0;\n                                                break;\n                                            }\n                                        }\n                                        while (1) {\n                                            e = (b + 20) | 0;\n                                            d = c[e >> 2] | 0;\n                                            if (!d) {\n                                                e = (b + 16) | 0;\n                                                d = c[e >> 2] | 0;\n                                                if (!d)\n                                                    break;\n                                                else {\n                                                    b = d;\n                                                    a = e;\n                                                }\n                                            }\n                                            else {\n                                                b = d;\n                                                a = e;\n                                            }\n                                        }\n                                        c[a >> 2] = 0;\n                                        d = b;\n                                    }\n                                    else {\n                                        d = c[(i + 8) >> 2] | 0;\n                                        c[(d + 12) >> 2] = b;\n                                        c[(b + 8) >> 2] = d;\n                                        d = b;\n                                    }\n                                while (0);\n                                do\n                                    if (f | 0) {\n                                        b = c[(i + 28) >> 2] | 0;\n                                        a = (21952 + (b << 2)) | 0;\n                                        if ((i | 0) == (c[a >> 2] | 0)) {\n                                            c[a >> 2] = d;\n                                            if (!d) {\n                                                c[5413] = g & ~(1 << b);\n                                                break;\n                                            }\n                                        }\n                                        else {\n                                            v = (f + 16) | 0;\n                                            c[((c[v >> 2] | 0) == (i | 0) ? v : (f + 20) | 0) >> 2] = d;\n                                            if (!d)\n                                                break;\n                                        }\n                                        c[(d + 24) >> 2] = f;\n                                        b = c[(i + 16) >> 2] | 0;\n                                        if (b | 0) {\n                                            c[(d + 16) >> 2] = b;\n                                            c[(b + 24) >> 2] = d;\n                                        }\n                                        b = c[(i + 20) >> 2] | 0;\n                                        if (b | 0) {\n                                            c[(d + 20) >> 2] = b;\n                                            c[(b + 24) >> 2] = d;\n                                        }\n                                    }\n                                while (0);\n                                if (j >>> 0 < 16) {\n                                    v = (j + k) | 0;\n                                    c[(i + 4) >> 2] = v | 3;\n                                    v = (i + v + 4) | 0;\n                                    c[v >> 2] = c[v >> 2] | 1;\n                                }\n                                else {\n                                    c[(i + 4) >> 2] = k | 3;\n                                    c[(h + 4) >> 2] = j | 1;\n                                    c[(h + j) >> 2] = j;\n                                    if (l | 0) {\n                                        e = c[5417] | 0;\n                                        b = l >>> 3;\n                                        d = (21688 + ((b << 1) << 2)) | 0;\n                                        b = 1 << b;\n                                        if (!(b & m)) {\n                                            c[5412] = b | m;\n                                            b = d;\n                                            a = (d + 8) | 0;\n                                        }\n                                        else {\n                                            a = (d + 8) | 0;\n                                            b = c[a >> 2] | 0;\n                                        }\n                                        c[a >> 2] = e;\n                                        c[(b + 12) >> 2] = e;\n                                        c[(e + 8) >> 2] = b;\n                                        c[(e + 12) >> 2] = d;\n                                    }\n                                    c[5414] = j;\n                                    c[5417] = h;\n                                }\n                                v = (i + 8) | 0;\n                                V = w;\n                                return v | 0;\n                            }\n                            else\n                                m = k;\n                        }\n                        else\n                            m = k;\n                    }\n                    else\n                        m = k;\n                }\n                else if (a >>> 0 <= 4294967231) {\n                    a = (a + 11) | 0;\n                    k = a & -8;\n                    e = c[5413] | 0;\n                    if (e) {\n                        f = (0 - k) | 0;\n                        a = a >>> 8;\n                        if (a)\n                            if (k >>> 0 > 16777215)\n                                j = 31;\n                            else {\n                                m = (((a + 1048320) | 0) >>> 16) & 8;\n                                q = a << m;\n                                i = (((q + 520192) | 0) >>> 16) & 4;\n                                q = q << i;\n                                j = (((q + 245760) | 0) >>> 16) & 2;\n                                j = (14 - (i | m | j) + ((q << j) >>> 15)) | 0;\n                                j = ((k >>> ((j + 7) | 0)) & 1) | (j << 1);\n                            }\n                        else\n                            j = 0;\n                        d = c[(21952 + (j << 2)) >> 2] | 0;\n                        a: do\n                            if (!d) {\n                                d = 0;\n                                a = 0;\n                                q = 61;\n                            }\n                            else {\n                                a = 0;\n                                i = k << ((j | 0) == 31 ? 0 : (25 - (j >>> 1)) | 0);\n                                g = 0;\n                                while (1) {\n                                    h = ((c[(d + 4) >> 2] & -8) - k) | 0;\n                                    if (h >>> 0 < f >>> 0)\n                                        if (!h) {\n                                            a = d;\n                                            f = 0;\n                                            q = 65;\n                                            break a;\n                                        }\n                                        else {\n                                            a = d;\n                                            f = h;\n                                        }\n                                    q = c[(d + 20) >> 2] | 0;\n                                    d = c[(d + 16 + ((i >>> 31) << 2)) >> 2] | 0;\n                                    g = ((q | 0) == 0) | ((q | 0) == (d | 0)) ? g : q;\n                                    if (!d) {\n                                        d = g;\n                                        q = 61;\n                                        break;\n                                    }\n                                    else\n                                        i = i << 1;\n                                }\n                            }\n                        while (0);\n                        if ((q | 0) == 61) {\n                            if (((d | 0) == 0) & ((a | 0) == 0)) {\n                                a = 2 << j;\n                                a = (a | (0 - a)) & e;\n                                if (!a) {\n                                    m = k;\n                                    break;\n                                }\n                                m = ((a & (0 - a)) + -1) | 0;\n                                h = (m >>> 12) & 16;\n                                m = m >>> h;\n                                g = (m >>> 5) & 8;\n                                m = m >>> g;\n                                i = (m >>> 2) & 4;\n                                m = m >>> i;\n                                j = (m >>> 1) & 2;\n                                m = m >>> j;\n                                d = (m >>> 1) & 1;\n                                a = 0;\n                                d = c[(21952 + (((g | h | i | j | d) + (m >>> d)) << 2)) >> 2] | 0;\n                            }\n                            if (!d) {\n                                i = a;\n                                h = f;\n                            }\n                            else\n                                q = 65;\n                        }\n                        if ((q | 0) == 65) {\n                            g = d;\n                            while (1) {\n                                m = ((c[(g + 4) >> 2] & -8) - k) | 0;\n                                d = m >>> 0 < f >>> 0;\n                                f = d ? m : f;\n                                a = d ? g : a;\n                                d = c[(g + 16) >> 2] | 0;\n                                if (!d)\n                                    d = c[(g + 20) >> 2] | 0;\n                                if (!d) {\n                                    i = a;\n                                    h = f;\n                                    break;\n                                }\n                                else\n                                    g = d;\n                            }\n                        }\n                        if (((i | 0) != 0 ? h >>> 0 < (((c[5414] | 0) - k) | 0) >>> 0 : 0)\n                            ? ((l = (i + k) | 0), l >>> 0 > i >>> 0)\n                            : 0) {\n                            g = c[(i + 24) >> 2] | 0;\n                            b = c[(i + 12) >> 2] | 0;\n                            do\n                                if ((b | 0) == (i | 0)) {\n                                    a = (i + 20) | 0;\n                                    b = c[a >> 2] | 0;\n                                    if (!b) {\n                                        a = (i + 16) | 0;\n                                        b = c[a >> 2] | 0;\n                                        if (!b) {\n                                            b = 0;\n                                            break;\n                                        }\n                                    }\n                                    while (1) {\n                                        f = (b + 20) | 0;\n                                        d = c[f >> 2] | 0;\n                                        if (!d) {\n                                            f = (b + 16) | 0;\n                                            d = c[f >> 2] | 0;\n                                            if (!d)\n                                                break;\n                                            else {\n                                                b = d;\n                                                a = f;\n                                            }\n                                        }\n                                        else {\n                                            b = d;\n                                            a = f;\n                                        }\n                                    }\n                                    c[a >> 2] = 0;\n                                }\n                                else {\n                                    v = c[(i + 8) >> 2] | 0;\n                                    c[(v + 12) >> 2] = b;\n                                    c[(b + 8) >> 2] = v;\n                                }\n                            while (0);\n                            do\n                                if (g) {\n                                    a = c[(i + 28) >> 2] | 0;\n                                    d = (21952 + (a << 2)) | 0;\n                                    if ((i | 0) == (c[d >> 2] | 0)) {\n                                        c[d >> 2] = b;\n                                        if (!b) {\n                                            e = e & ~(1 << a);\n                                            c[5413] = e;\n                                            break;\n                                        }\n                                    }\n                                    else {\n                                        v = (g + 16) | 0;\n                                        c[((c[v >> 2] | 0) == (i | 0) ? v : (g + 20) | 0) >> 2] = b;\n                                        if (!b)\n                                            break;\n                                    }\n                                    c[(b + 24) >> 2] = g;\n                                    a = c[(i + 16) >> 2] | 0;\n                                    if (a | 0) {\n                                        c[(b + 16) >> 2] = a;\n                                        c[(a + 24) >> 2] = b;\n                                    }\n                                    a = c[(i + 20) >> 2] | 0;\n                                    if (a) {\n                                        c[(b + 20) >> 2] = a;\n                                        c[(a + 24) >> 2] = b;\n                                    }\n                                }\n                            while (0);\n                            b: do\n                                if (h >>> 0 < 16) {\n                                    v = (h + k) | 0;\n                                    c[(i + 4) >> 2] = v | 3;\n                                    v = (i + v + 4) | 0;\n                                    c[v >> 2] = c[v >> 2] | 1;\n                                }\n                                else {\n                                    c[(i + 4) >> 2] = k | 3;\n                                    c[(l + 4) >> 2] = h | 1;\n                                    c[(l + h) >> 2] = h;\n                                    b = h >>> 3;\n                                    if (h >>> 0 < 256) {\n                                        d = (21688 + ((b << 1) << 2)) | 0;\n                                        a = c[5412] | 0;\n                                        b = 1 << b;\n                                        if (!(a & b)) {\n                                            c[5412] = a | b;\n                                            b = d;\n                                            a = (d + 8) | 0;\n                                        }\n                                        else {\n                                            a = (d + 8) | 0;\n                                            b = c[a >> 2] | 0;\n                                        }\n                                        c[a >> 2] = l;\n                                        c[(b + 12) >> 2] = l;\n                                        c[(l + 8) >> 2] = b;\n                                        c[(l + 12) >> 2] = d;\n                                        break;\n                                    }\n                                    b = h >>> 8;\n                                    if (b)\n                                        if (h >>> 0 > 16777215)\n                                            d = 31;\n                                        else {\n                                            u = (((b + 1048320) | 0) >>> 16) & 8;\n                                            v = b << u;\n                                            t = (((v + 520192) | 0) >>> 16) & 4;\n                                            v = v << t;\n                                            d = (((v + 245760) | 0) >>> 16) & 2;\n                                            d = (14 - (t | u | d) + ((v << d) >>> 15)) | 0;\n                                            d = ((h >>> ((d + 7) | 0)) & 1) | (d << 1);\n                                        }\n                                    else\n                                        d = 0;\n                                    b = (21952 + (d << 2)) | 0;\n                                    c[(l + 28) >> 2] = d;\n                                    a = (l + 16) | 0;\n                                    c[(a + 4) >> 2] = 0;\n                                    c[a >> 2] = 0;\n                                    a = 1 << d;\n                                    if (!(e & a)) {\n                                        c[5413] = e | a;\n                                        c[b >> 2] = l;\n                                        c[(l + 24) >> 2] = b;\n                                        c[(l + 12) >> 2] = l;\n                                        c[(l + 8) >> 2] = l;\n                                        break;\n                                    }\n                                    b = c[b >> 2] | 0;\n                                    c: do\n                                        if (((c[(b + 4) >> 2] & -8) | 0) != (h | 0)) {\n                                            e = h << ((d | 0) == 31 ? 0 : (25 - (d >>> 1)) | 0);\n                                            while (1) {\n                                                d = (b + 16 + ((e >>> 31) << 2)) | 0;\n                                                a = c[d >> 2] | 0;\n                                                if (!a)\n                                                    break;\n                                                if (((c[(a + 4) >> 2] & -8) | 0) == (h | 0)) {\n                                                    b = a;\n                                                    break c;\n                                                }\n                                                else {\n                                                    e = e << 1;\n                                                    b = a;\n                                                }\n                                            }\n                                            c[d >> 2] = l;\n                                            c[(l + 24) >> 2] = b;\n                                            c[(l + 12) >> 2] = l;\n                                            c[(l + 8) >> 2] = l;\n                                            break b;\n                                        }\n                                    while (0);\n                                    u = (b + 8) | 0;\n                                    v = c[u >> 2] | 0;\n                                    c[(v + 12) >> 2] = l;\n                                    c[u >> 2] = l;\n                                    c[(l + 8) >> 2] = v;\n                                    c[(l + 12) >> 2] = b;\n                                    c[(l + 24) >> 2] = 0;\n                                }\n                            while (0);\n                            v = (i + 8) | 0;\n                            V = w;\n                            return v | 0;\n                        }\n                        else\n                            m = k;\n                    }\n                    else\n                        m = k;\n                }\n                else\n                    m = -1;\n            while (0);\n            d = c[5414] | 0;\n            if (d >>> 0 >= m >>> 0) {\n                b = (d - m) | 0;\n                a = c[5417] | 0;\n                if (b >>> 0 > 15) {\n                    v = (a + m) | 0;\n                    c[5417] = v;\n                    c[5414] = b;\n                    c[(v + 4) >> 2] = b | 1;\n                    c[(a + d) >> 2] = b;\n                    c[(a + 4) >> 2] = m | 3;\n                }\n                else {\n                    c[5414] = 0;\n                    c[5417] = 0;\n                    c[(a + 4) >> 2] = d | 3;\n                    v = (a + d + 4) | 0;\n                    c[v >> 2] = c[v >> 2] | 1;\n                }\n                v = (a + 8) | 0;\n                V = w;\n                return v | 0;\n            }\n            h = c[5415] | 0;\n            if (h >>> 0 > m >>> 0) {\n                t = (h - m) | 0;\n                c[5415] = t;\n                v = c[5418] | 0;\n                u = (v + m) | 0;\n                c[5418] = u;\n                c[(u + 4) >> 2] = t | 1;\n                c[(v + 4) >> 2] = m | 3;\n                v = (v + 8) | 0;\n                V = w;\n                return v | 0;\n            }\n            if (!(c[5530] | 0)) {\n                c[5532] = 4096;\n                c[5531] = 4096;\n                c[5533] = -1;\n                c[5534] = -1;\n                c[5535] = 0;\n                c[5523] = 0;\n                c[5530] = (n & -16) ^ 1431655768;\n                a = 4096;\n            }\n            else\n                a = c[5532] | 0;\n            i = (m + 48) | 0;\n            j = (m + 47) | 0;\n            g = (a + j) | 0;\n            f = (0 - a) | 0;\n            k = g & f;\n            if (k >>> 0 <= m >>> 0) {\n                v = 0;\n                V = w;\n                return v | 0;\n            }\n            a = c[5522] | 0;\n            if (a | 0\n                ? ((l = c[5520] | 0), (n = (l + k) | 0), (n >>> 0 <= l >>> 0) | (n >>> 0 > a >>> 0))\n                : 0) {\n                v = 0;\n                V = w;\n                return v | 0;\n            }\n            d: do\n                if (!(c[5523] & 4)) {\n                    d = c[5418] | 0;\n                    e: do\n                        if (d) {\n                            e = 22096;\n                            while (1) {\n                                n = c[e >> 2] | 0;\n                                if (n >>> 0 <= d >>> 0 ? ((n + (c[(e + 4) >> 2] | 0)) | 0) >>> 0 > d >>> 0 : 0)\n                                    break;\n                                a = c[(e + 8) >> 2] | 0;\n                                if (!a) {\n                                    q = 128;\n                                    break e;\n                                }\n                                else\n                                    e = a;\n                            }\n                            b = (g - h) & f;\n                            if (b >>> 0 < 2147483647) {\n                                a = fr(b) | 0;\n                                if ((a | 0) == (((c[e >> 2] | 0) + (c[(e + 4) >> 2] | 0)) | 0)) {\n                                    if ((a | 0) != (-1 | 0)) {\n                                        h = b;\n                                        g = a;\n                                        q = 145;\n                                        break d;\n                                    }\n                                }\n                                else {\n                                    e = a;\n                                    q = 136;\n                                }\n                            }\n                            else\n                                b = 0;\n                        }\n                        else\n                            q = 128;\n                    while (0);\n                    do\n                        if ((q | 0) == 128) {\n                            d = fr(0) | 0;\n                            if ((d | 0) != (-1 | 0)\n                                ? ((b = d),\n                                    (o = c[5531] | 0),\n                                    (p = (o + -1) | 0),\n                                    (b = ((((p & b) | 0) == 0 ? 0 : (((p + b) & (0 - o)) - b) | 0) + k) | 0),\n                                    (o = c[5520] | 0),\n                                    (p = (b + o) | 0),\n                                    (b >>> 0 > m >>> 0) & (b >>> 0 < 2147483647))\n                                : 0) {\n                                n = c[5522] | 0;\n                                if (n | 0 ? (p >>> 0 <= o >>> 0) | (p >>> 0 > n >>> 0) : 0) {\n                                    b = 0;\n                                    break;\n                                }\n                                a = fr(b) | 0;\n                                if ((a | 0) == (d | 0)) {\n                                    h = b;\n                                    g = d;\n                                    q = 145;\n                                    break d;\n                                }\n                                else {\n                                    e = a;\n                                    q = 136;\n                                }\n                            }\n                            else\n                                b = 0;\n                        }\n                    while (0);\n                    do\n                        if ((q | 0) == 136) {\n                            d = (0 - b) | 0;\n                            if (!((i >>> 0 > b >>> 0) & ((b >>> 0 < 2147483647) & ((e | 0) != (-1 | 0)))))\n                                if ((e | 0) == (-1 | 0)) {\n                                    b = 0;\n                                    break;\n                                }\n                                else {\n                                    h = b;\n                                    g = e;\n                                    q = 145;\n                                    break d;\n                                }\n                            a = c[5532] | 0;\n                            a = (j - b + a) & (0 - a);\n                            if (a >>> 0 >= 2147483647) {\n                                h = b;\n                                g = e;\n                                q = 145;\n                                break d;\n                            }\n                            if ((fr(a) | 0) == (-1 | 0)) {\n                                fr(d) | 0;\n                                b = 0;\n                                break;\n                            }\n                            else {\n                                h = (a + b) | 0;\n                                g = e;\n                                q = 145;\n                                break d;\n                            }\n                        }\n                    while (0);\n                    c[5523] = c[5523] | 4;\n                    q = 143;\n                }\n                else {\n                    b = 0;\n                    q = 143;\n                }\n            while (0);\n            if (((q | 0) == 143 ? k >>> 0 < 2147483647 : 0)\n                ? ((t = fr(k) | 0),\n                    (p = fr(0) | 0),\n                    (r = (p - t) | 0),\n                    (s = r >>> 0 > ((m + 40) | 0) >>> 0),\n                    !(((t | 0) == (-1 | 0)) |\n                        (s ^ 1) |\n                        (((t >>> 0 < p >>> 0) & (((t | 0) != (-1 | 0)) & ((p | 0) != (-1 | 0)))) ^ 1)))\n                : 0) {\n                h = s ? r : b;\n                g = t;\n                q = 145;\n            }\n            if ((q | 0) == 145) {\n                b = ((c[5520] | 0) + h) | 0;\n                c[5520] = b;\n                if (b >>> 0 > (c[5521] | 0) >>> 0)\n                    c[5521] = b;\n                j = c[5418] | 0;\n                f: do\n                    if (j) {\n                        b = 22096;\n                        while (1) {\n                            a = c[b >> 2] | 0;\n                            d = c[(b + 4) >> 2] | 0;\n                            if ((g | 0) == ((a + d) | 0)) {\n                                q = 154;\n                                break;\n                            }\n                            e = c[(b + 8) >> 2] | 0;\n                            if (!e)\n                                break;\n                            else\n                                b = e;\n                        }\n                        if (((q | 0) == 154 ? ((u = (b + 4) | 0), ((c[(b + 12) >> 2] & 8) | 0) == 0) : 0)\n                            ? (g >>> 0 > j >>> 0) & (a >>> 0 <= j >>> 0)\n                            : 0) {\n                            c[u >> 2] = d + h;\n                            v = ((c[5415] | 0) + h) | 0;\n                            t = (j + 8) | 0;\n                            t = ((t & 7) | 0) == 0 ? 0 : (0 - t) & 7;\n                            u = (j + t) | 0;\n                            t = (v - t) | 0;\n                            c[5418] = u;\n                            c[5415] = t;\n                            c[(u + 4) >> 2] = t | 1;\n                            c[(j + v + 4) >> 2] = 40;\n                            c[5419] = c[5534];\n                            break;\n                        }\n                        if (g >>> 0 < (c[5416] | 0) >>> 0)\n                            c[5416] = g;\n                        d = (g + h) | 0;\n                        b = 22096;\n                        while (1) {\n                            if ((c[b >> 2] | 0) == (d | 0)) {\n                                q = 162;\n                                break;\n                            }\n                            a = c[(b + 8) >> 2] | 0;\n                            if (!a)\n                                break;\n                            else\n                                b = a;\n                        }\n                        if ((q | 0) == 162 ? ((c[(b + 12) >> 2] & 8) | 0) == 0 : 0) {\n                            c[b >> 2] = g;\n                            l = (b + 4) | 0;\n                            c[l >> 2] = (c[l >> 2] | 0) + h;\n                            l = (g + 8) | 0;\n                            l = (g + (((l & 7) | 0) == 0 ? 0 : (0 - l) & 7)) | 0;\n                            b = (d + 8) | 0;\n                            b = (d + (((b & 7) | 0) == 0 ? 0 : (0 - b) & 7)) | 0;\n                            k = (l + m) | 0;\n                            i = (b - l - m) | 0;\n                            c[(l + 4) >> 2] = m | 3;\n                            g: do\n                                if ((j | 0) == (b | 0)) {\n                                    v = ((c[5415] | 0) + i) | 0;\n                                    c[5415] = v;\n                                    c[5418] = k;\n                                    c[(k + 4) >> 2] = v | 1;\n                                }\n                                else {\n                                    if ((c[5417] | 0) == (b | 0)) {\n                                        v = ((c[5414] | 0) + i) | 0;\n                                        c[5414] = v;\n                                        c[5417] = k;\n                                        c[(k + 4) >> 2] = v | 1;\n                                        c[(k + v) >> 2] = v;\n                                        break;\n                                    }\n                                    a = c[(b + 4) >> 2] | 0;\n                                    if (((a & 3) | 0) == 1) {\n                                        h = a & -8;\n                                        e = a >>> 3;\n                                        h: do\n                                            if (a >>> 0 < 256) {\n                                                a = c[(b + 8) >> 2] | 0;\n                                                d = c[(b + 12) >> 2] | 0;\n                                                if ((d | 0) == (a | 0)) {\n                                                    c[5412] = c[5412] & ~(1 << e);\n                                                    break;\n                                                }\n                                                else {\n                                                    c[(a + 12) >> 2] = d;\n                                                    c[(d + 8) >> 2] = a;\n                                                    break;\n                                                }\n                                            }\n                                            else {\n                                                g = c[(b + 24) >> 2] | 0;\n                                                a = c[(b + 12) >> 2] | 0;\n                                                do\n                                                    if ((a | 0) == (b | 0)) {\n                                                        d = (b + 16) | 0;\n                                                        e = (d + 4) | 0;\n                                                        a = c[e >> 2] | 0;\n                                                        if (!a) {\n                                                            a = c[d >> 2] | 0;\n                                                            if (!a) {\n                                                                a = 0;\n                                                                break;\n                                                            }\n                                                        }\n                                                        else\n                                                            d = e;\n                                                        while (1) {\n                                                            f = (a + 20) | 0;\n                                                            e = c[f >> 2] | 0;\n                                                            if (!e) {\n                                                                f = (a + 16) | 0;\n                                                                e = c[f >> 2] | 0;\n                                                                if (!e)\n                                                                    break;\n                                                                else {\n                                                                    a = e;\n                                                                    d = f;\n                                                                }\n                                                            }\n                                                            else {\n                                                                a = e;\n                                                                d = f;\n                                                            }\n                                                        }\n                                                        c[d >> 2] = 0;\n                                                    }\n                                                    else {\n                                                        v = c[(b + 8) >> 2] | 0;\n                                                        c[(v + 12) >> 2] = a;\n                                                        c[(a + 8) >> 2] = v;\n                                                    }\n                                                while (0);\n                                                if (!g)\n                                                    break;\n                                                d = c[(b + 28) >> 2] | 0;\n                                                e = (21952 + (d << 2)) | 0;\n                                                do\n                                                    if ((c[e >> 2] | 0) != (b | 0)) {\n                                                        v = (g + 16) | 0;\n                                                        c[((c[v >> 2] | 0) == (b | 0) ? v : (g + 20) | 0) >> 2] = a;\n                                                        if (!a)\n                                                            break h;\n                                                    }\n                                                    else {\n                                                        c[e >> 2] = a;\n                                                        if (a | 0)\n                                                            break;\n                                                        c[5413] = c[5413] & ~(1 << d);\n                                                        break h;\n                                                    }\n                                                while (0);\n                                                c[(a + 24) >> 2] = g;\n                                                d = (b + 16) | 0;\n                                                e = c[d >> 2] | 0;\n                                                if (e | 0) {\n                                                    c[(a + 16) >> 2] = e;\n                                                    c[(e + 24) >> 2] = a;\n                                                }\n                                                d = c[(d + 4) >> 2] | 0;\n                                                if (!d)\n                                                    break;\n                                                c[(a + 20) >> 2] = d;\n                                                c[(d + 24) >> 2] = a;\n                                            }\n                                        while (0);\n                                        b = (b + h) | 0;\n                                        f = (h + i) | 0;\n                                    }\n                                    else\n                                        f = i;\n                                    b = (b + 4) | 0;\n                                    c[b >> 2] = c[b >> 2] & -2;\n                                    c[(k + 4) >> 2] = f | 1;\n                                    c[(k + f) >> 2] = f;\n                                    b = f >>> 3;\n                                    if (f >>> 0 < 256) {\n                                        d = (21688 + ((b << 1) << 2)) | 0;\n                                        a = c[5412] | 0;\n                                        b = 1 << b;\n                                        if (!(a & b)) {\n                                            c[5412] = a | b;\n                                            b = d;\n                                            a = (d + 8) | 0;\n                                        }\n                                        else {\n                                            a = (d + 8) | 0;\n                                            b = c[a >> 2] | 0;\n                                        }\n                                        c[a >> 2] = k;\n                                        c[(b + 12) >> 2] = k;\n                                        c[(k + 8) >> 2] = b;\n                                        c[(k + 12) >> 2] = d;\n                                        break;\n                                    }\n                                    b = f >>> 8;\n                                    do\n                                        if (!b)\n                                            e = 0;\n                                        else {\n                                            if (f >>> 0 > 16777215) {\n                                                e = 31;\n                                                break;\n                                            }\n                                            u = (((b + 1048320) | 0) >>> 16) & 8;\n                                            v = b << u;\n                                            t = (((v + 520192) | 0) >>> 16) & 4;\n                                            v = v << t;\n                                            e = (((v + 245760) | 0) >>> 16) & 2;\n                                            e = (14 - (t | u | e) + ((v << e) >>> 15)) | 0;\n                                            e = ((f >>> ((e + 7) | 0)) & 1) | (e << 1);\n                                        }\n                                    while (0);\n                                    b = (21952 + (e << 2)) | 0;\n                                    c[(k + 28) >> 2] = e;\n                                    a = (k + 16) | 0;\n                                    c[(a + 4) >> 2] = 0;\n                                    c[a >> 2] = 0;\n                                    a = c[5413] | 0;\n                                    d = 1 << e;\n                                    if (!(a & d)) {\n                                        c[5413] = a | d;\n                                        c[b >> 2] = k;\n                                        c[(k + 24) >> 2] = b;\n                                        c[(k + 12) >> 2] = k;\n                                        c[(k + 8) >> 2] = k;\n                                        break;\n                                    }\n                                    b = c[b >> 2] | 0;\n                                    i: do\n                                        if (((c[(b + 4) >> 2] & -8) | 0) != (f | 0)) {\n                                            e = f << ((e | 0) == 31 ? 0 : (25 - (e >>> 1)) | 0);\n                                            while (1) {\n                                                d = (b + 16 + ((e >>> 31) << 2)) | 0;\n                                                a = c[d >> 2] | 0;\n                                                if (!a)\n                                                    break;\n                                                if (((c[(a + 4) >> 2] & -8) | 0) == (f | 0)) {\n                                                    b = a;\n                                                    break i;\n                                                }\n                                                else {\n                                                    e = e << 1;\n                                                    b = a;\n                                                }\n                                            }\n                                            c[d >> 2] = k;\n                                            c[(k + 24) >> 2] = b;\n                                            c[(k + 12) >> 2] = k;\n                                            c[(k + 8) >> 2] = k;\n                                            break g;\n                                        }\n                                    while (0);\n                                    u = (b + 8) | 0;\n                                    v = c[u >> 2] | 0;\n                                    c[(v + 12) >> 2] = k;\n                                    c[u >> 2] = k;\n                                    c[(k + 8) >> 2] = v;\n                                    c[(k + 12) >> 2] = b;\n                                    c[(k + 24) >> 2] = 0;\n                                }\n                            while (0);\n                            v = (l + 8) | 0;\n                            V = w;\n                            return v | 0;\n                        }\n                        b = 22096;\n                        while (1) {\n                            a = c[b >> 2] | 0;\n                            if (a >>> 0 <= j >>> 0 ? ((v = (a + (c[(b + 4) >> 2] | 0)) | 0), v >>> 0 > j >>> 0) : 0)\n                                break;\n                            b = c[(b + 8) >> 2] | 0;\n                        }\n                        f = (v + -47) | 0;\n                        a = (f + 8) | 0;\n                        a = (f + (((a & 7) | 0) == 0 ? 0 : (0 - a) & 7)) | 0;\n                        f = (j + 16) | 0;\n                        a = a >>> 0 < f >>> 0 ? j : a;\n                        b = (a + 8) | 0;\n                        d = (h + -40) | 0;\n                        t = (g + 8) | 0;\n                        t = ((t & 7) | 0) == 0 ? 0 : (0 - t) & 7;\n                        u = (g + t) | 0;\n                        t = (d - t) | 0;\n                        c[5418] = u;\n                        c[5415] = t;\n                        c[(u + 4) >> 2] = t | 1;\n                        c[(g + d + 4) >> 2] = 40;\n                        c[5419] = c[5534];\n                        d = (a + 4) | 0;\n                        c[d >> 2] = 27;\n                        c[b >> 2] = c[5524];\n                        c[(b + 4) >> 2] = c[5525];\n                        c[(b + 8) >> 2] = c[5526];\n                        c[(b + 12) >> 2] = c[5527];\n                        c[5524] = g;\n                        c[5525] = h;\n                        c[5527] = 0;\n                        c[5526] = b;\n                        b = (a + 24) | 0;\n                        do {\n                            u = b;\n                            b = (b + 4) | 0;\n                            c[b >> 2] = 7;\n                        } while (((u + 8) | 0) >>> 0 < v >>> 0);\n                        if ((a | 0) != (j | 0)) {\n                            g = (a - j) | 0;\n                            c[d >> 2] = c[d >> 2] & -2;\n                            c[(j + 4) >> 2] = g | 1;\n                            c[a >> 2] = g;\n                            b = g >>> 3;\n                            if (g >>> 0 < 256) {\n                                d = (21688 + ((b << 1) << 2)) | 0;\n                                a = c[5412] | 0;\n                                b = 1 << b;\n                                if (!(a & b)) {\n                                    c[5412] = a | b;\n                                    b = d;\n                                    a = (d + 8) | 0;\n                                }\n                                else {\n                                    a = (d + 8) | 0;\n                                    b = c[a >> 2] | 0;\n                                }\n                                c[a >> 2] = j;\n                                c[(b + 12) >> 2] = j;\n                                c[(j + 8) >> 2] = b;\n                                c[(j + 12) >> 2] = d;\n                                break;\n                            }\n                            b = g >>> 8;\n                            if (b)\n                                if (g >>> 0 > 16777215)\n                                    e = 31;\n                                else {\n                                    u = (((b + 1048320) | 0) >>> 16) & 8;\n                                    v = b << u;\n                                    t = (((v + 520192) | 0) >>> 16) & 4;\n                                    v = v << t;\n                                    e = (((v + 245760) | 0) >>> 16) & 2;\n                                    e = (14 - (t | u | e) + ((v << e) >>> 15)) | 0;\n                                    e = ((g >>> ((e + 7) | 0)) & 1) | (e << 1);\n                                }\n                            else\n                                e = 0;\n                            d = (21952 + (e << 2)) | 0;\n                            c[(j + 28) >> 2] = e;\n                            c[(j + 20) >> 2] = 0;\n                            c[f >> 2] = 0;\n                            b = c[5413] | 0;\n                            a = 1 << e;\n                            if (!(b & a)) {\n                                c[5413] = b | a;\n                                c[d >> 2] = j;\n                                c[(j + 24) >> 2] = d;\n                                c[(j + 12) >> 2] = j;\n                                c[(j + 8) >> 2] = j;\n                                break;\n                            }\n                            b = c[d >> 2] | 0;\n                            j: do\n                                if (((c[(b + 4) >> 2] & -8) | 0) != (g | 0)) {\n                                    e = g << ((e | 0) == 31 ? 0 : (25 - (e >>> 1)) | 0);\n                                    while (1) {\n                                        d = (b + 16 + ((e >>> 31) << 2)) | 0;\n                                        a = c[d >> 2] | 0;\n                                        if (!a)\n                                            break;\n                                        if (((c[(a + 4) >> 2] & -8) | 0) == (g | 0)) {\n                                            b = a;\n                                            break j;\n                                        }\n                                        else {\n                                            e = e << 1;\n                                            b = a;\n                                        }\n                                    }\n                                    c[d >> 2] = j;\n                                    c[(j + 24) >> 2] = b;\n                                    c[(j + 12) >> 2] = j;\n                                    c[(j + 8) >> 2] = j;\n                                    break f;\n                                }\n                            while (0);\n                            u = (b + 8) | 0;\n                            v = c[u >> 2] | 0;\n                            c[(v + 12) >> 2] = j;\n                            c[u >> 2] = j;\n                            c[(j + 8) >> 2] = v;\n                            c[(j + 12) >> 2] = b;\n                            c[(j + 24) >> 2] = 0;\n                        }\n                    }\n                    else {\n                        v = c[5416] | 0;\n                        if (((v | 0) == 0) | (g >>> 0 < v >>> 0))\n                            c[5416] = g;\n                        c[5524] = g;\n                        c[5525] = h;\n                        c[5527] = 0;\n                        c[5421] = c[5530];\n                        c[5420] = -1;\n                        c[5425] = 21688;\n                        c[5424] = 21688;\n                        c[5427] = 21696;\n                        c[5426] = 21696;\n                        c[5429] = 21704;\n                        c[5428] = 21704;\n                        c[5431] = 21712;\n                        c[5430] = 21712;\n                        c[5433] = 21720;\n                        c[5432] = 21720;\n                        c[5435] = 21728;\n                        c[5434] = 21728;\n                        c[5437] = 21736;\n                        c[5436] = 21736;\n                        c[5439] = 21744;\n                        c[5438] = 21744;\n                        c[5441] = 21752;\n                        c[5440] = 21752;\n                        c[5443] = 21760;\n                        c[5442] = 21760;\n                        c[5445] = 21768;\n                        c[5444] = 21768;\n                        c[5447] = 21776;\n                        c[5446] = 21776;\n                        c[5449] = 21784;\n                        c[5448] = 21784;\n                        c[5451] = 21792;\n                        c[5450] = 21792;\n                        c[5453] = 21800;\n                        c[5452] = 21800;\n                        c[5455] = 21808;\n                        c[5454] = 21808;\n                        c[5457] = 21816;\n                        c[5456] = 21816;\n                        c[5459] = 21824;\n                        c[5458] = 21824;\n                        c[5461] = 21832;\n                        c[5460] = 21832;\n                        c[5463] = 21840;\n                        c[5462] = 21840;\n                        c[5465] = 21848;\n                        c[5464] = 21848;\n                        c[5467] = 21856;\n                        c[5466] = 21856;\n                        c[5469] = 21864;\n                        c[5468] = 21864;\n                        c[5471] = 21872;\n                        c[5470] = 21872;\n                        c[5473] = 21880;\n                        c[5472] = 21880;\n                        c[5475] = 21888;\n                        c[5474] = 21888;\n                        c[5477] = 21896;\n                        c[5476] = 21896;\n                        c[5479] = 21904;\n                        c[5478] = 21904;\n                        c[5481] = 21912;\n                        c[5480] = 21912;\n                        c[5483] = 21920;\n                        c[5482] = 21920;\n                        c[5485] = 21928;\n                        c[5484] = 21928;\n                        c[5487] = 21936;\n                        c[5486] = 21936;\n                        v = (h + -40) | 0;\n                        t = (g + 8) | 0;\n                        t = ((t & 7) | 0) == 0 ? 0 : (0 - t) & 7;\n                        u = (g + t) | 0;\n                        t = (v - t) | 0;\n                        c[5418] = u;\n                        c[5415] = t;\n                        c[(u + 4) >> 2] = t | 1;\n                        c[(g + v + 4) >> 2] = 40;\n                        c[5419] = c[5534];\n                    }\n                while (0);\n                b = c[5415] | 0;\n                if (b >>> 0 > m >>> 0) {\n                    t = (b - m) | 0;\n                    c[5415] = t;\n                    v = c[5418] | 0;\n                    u = (v + m) | 0;\n                    c[5418] = u;\n                    c[(u + 4) >> 2] = t | 1;\n                    c[(v + 4) >> 2] = m | 3;\n                    v = (v + 8) | 0;\n                    V = w;\n                    return v | 0;\n                }\n            }\n            c[(ao() | 0) >> 2] = 48;\n            v = 0;\n            V = w;\n            return v | 0;\n        }\n        function er(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0;\n            if (!a)\n                return;\n            d = (a + -8) | 0;\n            f = c[5416] | 0;\n            a = c[(a + -4) >> 2] | 0;\n            b = a & -8;\n            j = (d + b) | 0;\n            do\n                if (!(a & 1)) {\n                    e = c[d >> 2] | 0;\n                    if (!(a & 3))\n                        return;\n                    h = (d + (0 - e)) | 0;\n                    g = (e + b) | 0;\n                    if (h >>> 0 < f >>> 0)\n                        return;\n                    if ((c[5417] | 0) == (h | 0)) {\n                        a = (j + 4) | 0;\n                        b = c[a >> 2] | 0;\n                        if (((b & 3) | 0) != 3) {\n                            i = h;\n                            b = g;\n                            break;\n                        }\n                        c[5414] = g;\n                        c[a >> 2] = b & -2;\n                        c[(h + 4) >> 2] = g | 1;\n                        c[(h + g) >> 2] = g;\n                        return;\n                    }\n                    d = e >>> 3;\n                    if (e >>> 0 < 256) {\n                        a = c[(h + 8) >> 2] | 0;\n                        b = c[(h + 12) >> 2] | 0;\n                        if ((b | 0) == (a | 0)) {\n                            c[5412] = c[5412] & ~(1 << d);\n                            i = h;\n                            b = g;\n                            break;\n                        }\n                        else {\n                            c[(a + 12) >> 2] = b;\n                            c[(b + 8) >> 2] = a;\n                            i = h;\n                            b = g;\n                            break;\n                        }\n                    }\n                    f = c[(h + 24) >> 2] | 0;\n                    a = c[(h + 12) >> 2] | 0;\n                    do\n                        if ((a | 0) == (h | 0)) {\n                            b = (h + 16) | 0;\n                            d = (b + 4) | 0;\n                            a = c[d >> 2] | 0;\n                            if (!a) {\n                                a = c[b >> 2] | 0;\n                                if (!a) {\n                                    a = 0;\n                                    break;\n                                }\n                            }\n                            else\n                                b = d;\n                            while (1) {\n                                e = (a + 20) | 0;\n                                d = c[e >> 2] | 0;\n                                if (!d) {\n                                    e = (a + 16) | 0;\n                                    d = c[e >> 2] | 0;\n                                    if (!d)\n                                        break;\n                                    else {\n                                        a = d;\n                                        b = e;\n                                    }\n                                }\n                                else {\n                                    a = d;\n                                    b = e;\n                                }\n                            }\n                            c[b >> 2] = 0;\n                        }\n                        else {\n                            i = c[(h + 8) >> 2] | 0;\n                            c[(i + 12) >> 2] = a;\n                            c[(a + 8) >> 2] = i;\n                        }\n                    while (0);\n                    if (f) {\n                        b = c[(h + 28) >> 2] | 0;\n                        d = (21952 + (b << 2)) | 0;\n                        if ((c[d >> 2] | 0) == (h | 0)) {\n                            c[d >> 2] = a;\n                            if (!a) {\n                                c[5413] = c[5413] & ~(1 << b);\n                                i = h;\n                                b = g;\n                                break;\n                            }\n                        }\n                        else {\n                            i = (f + 16) | 0;\n                            c[((c[i >> 2] | 0) == (h | 0) ? i : (f + 20) | 0) >> 2] = a;\n                            if (!a) {\n                                i = h;\n                                b = g;\n                                break;\n                            }\n                        }\n                        c[(a + 24) >> 2] = f;\n                        b = (h + 16) | 0;\n                        d = c[b >> 2] | 0;\n                        if (d | 0) {\n                            c[(a + 16) >> 2] = d;\n                            c[(d + 24) >> 2] = a;\n                        }\n                        b = c[(b + 4) >> 2] | 0;\n                        if (b) {\n                            c[(a + 20) >> 2] = b;\n                            c[(b + 24) >> 2] = a;\n                            i = h;\n                            b = g;\n                        }\n                        else {\n                            i = h;\n                            b = g;\n                        }\n                    }\n                    else {\n                        i = h;\n                        b = g;\n                    }\n                }\n                else {\n                    i = d;\n                    h = d;\n                }\n            while (0);\n            if (h >>> 0 >= j >>> 0)\n                return;\n            a = (j + 4) | 0;\n            e = c[a >> 2] | 0;\n            if (!(e & 1))\n                return;\n            if (!(e & 2)) {\n                if ((c[5418] | 0) == (j | 0)) {\n                    j = ((c[5415] | 0) + b) | 0;\n                    c[5415] = j;\n                    c[5418] = i;\n                    c[(i + 4) >> 2] = j | 1;\n                    if ((i | 0) != (c[5417] | 0))\n                        return;\n                    c[5417] = 0;\n                    c[5414] = 0;\n                    return;\n                }\n                if ((c[5417] | 0) == (j | 0)) {\n                    j = ((c[5414] | 0) + b) | 0;\n                    c[5414] = j;\n                    c[5417] = h;\n                    c[(i + 4) >> 2] = j | 1;\n                    c[(h + j) >> 2] = j;\n                    return;\n                }\n                f = ((e & -8) + b) | 0;\n                d = e >>> 3;\n                do\n                    if (e >>> 0 < 256) {\n                        b = c[(j + 8) >> 2] | 0;\n                        a = c[(j + 12) >> 2] | 0;\n                        if ((a | 0) == (b | 0)) {\n                            c[5412] = c[5412] & ~(1 << d);\n                            break;\n                        }\n                        else {\n                            c[(b + 12) >> 2] = a;\n                            c[(a + 8) >> 2] = b;\n                            break;\n                        }\n                    }\n                    else {\n                        g = c[(j + 24) >> 2] | 0;\n                        a = c[(j + 12) >> 2] | 0;\n                        do\n                            if ((a | 0) == (j | 0)) {\n                                b = (j + 16) | 0;\n                                d = (b + 4) | 0;\n                                a = c[d >> 2] | 0;\n                                if (!a) {\n                                    a = c[b >> 2] | 0;\n                                    if (!a) {\n                                        d = 0;\n                                        break;\n                                    }\n                                }\n                                else\n                                    b = d;\n                                while (1) {\n                                    e = (a + 20) | 0;\n                                    d = c[e >> 2] | 0;\n                                    if (!d) {\n                                        e = (a + 16) | 0;\n                                        d = c[e >> 2] | 0;\n                                        if (!d)\n                                            break;\n                                        else {\n                                            a = d;\n                                            b = e;\n                                        }\n                                    }\n                                    else {\n                                        a = d;\n                                        b = e;\n                                    }\n                                }\n                                c[b >> 2] = 0;\n                                d = a;\n                            }\n                            else {\n                                d = c[(j + 8) >> 2] | 0;\n                                c[(d + 12) >> 2] = a;\n                                c[(a + 8) >> 2] = d;\n                                d = a;\n                            }\n                        while (0);\n                        if (g | 0) {\n                            a = c[(j + 28) >> 2] | 0;\n                            b = (21952 + (a << 2)) | 0;\n                            if ((c[b >> 2] | 0) == (j | 0)) {\n                                c[b >> 2] = d;\n                                if (!d) {\n                                    c[5413] = c[5413] & ~(1 << a);\n                                    break;\n                                }\n                            }\n                            else {\n                                e = (g + 16) | 0;\n                                c[((c[e >> 2] | 0) == (j | 0) ? e : (g + 20) | 0) >> 2] = d;\n                                if (!d)\n                                    break;\n                            }\n                            c[(d + 24) >> 2] = g;\n                            a = (j + 16) | 0;\n                            b = c[a >> 2] | 0;\n                            if (b | 0) {\n                                c[(d + 16) >> 2] = b;\n                                c[(b + 24) >> 2] = d;\n                            }\n                            a = c[(a + 4) >> 2] | 0;\n                            if (a | 0) {\n                                c[(d + 20) >> 2] = a;\n                                c[(a + 24) >> 2] = d;\n                            }\n                        }\n                    }\n                while (0);\n                c[(i + 4) >> 2] = f | 1;\n                c[(h + f) >> 2] = f;\n                if ((i | 0) == (c[5417] | 0)) {\n                    c[5414] = f;\n                    return;\n                }\n            }\n            else {\n                c[a >> 2] = e & -2;\n                c[(i + 4) >> 2] = b | 1;\n                c[(h + b) >> 2] = b;\n                f = b;\n            }\n            a = f >>> 3;\n            if (f >>> 0 < 256) {\n                d = (21688 + ((a << 1) << 2)) | 0;\n                b = c[5412] | 0;\n                a = 1 << a;\n                if (!(b & a)) {\n                    c[5412] = b | a;\n                    a = d;\n                    b = (d + 8) | 0;\n                }\n                else {\n                    b = (d + 8) | 0;\n                    a = c[b >> 2] | 0;\n                }\n                c[b >> 2] = i;\n                c[(a + 12) >> 2] = i;\n                c[(i + 8) >> 2] = a;\n                c[(i + 12) >> 2] = d;\n                return;\n            }\n            a = f >>> 8;\n            if (a)\n                if (f >>> 0 > 16777215)\n                    e = 31;\n                else {\n                    h = (((a + 1048320) | 0) >>> 16) & 8;\n                    j = a << h;\n                    g = (((j + 520192) | 0) >>> 16) & 4;\n                    j = j << g;\n                    e = (((j + 245760) | 0) >>> 16) & 2;\n                    e = (14 - (g | h | e) + ((j << e) >>> 15)) | 0;\n                    e = ((f >>> ((e + 7) | 0)) & 1) | (e << 1);\n                }\n            else\n                e = 0;\n            a = (21952 + (e << 2)) | 0;\n            c[(i + 28) >> 2] = e;\n            c[(i + 20) >> 2] = 0;\n            c[(i + 16) >> 2] = 0;\n            b = c[5413] | 0;\n            d = 1 << e;\n            a: do\n                if (!(b & d)) {\n                    c[5413] = b | d;\n                    c[a >> 2] = i;\n                    c[(i + 24) >> 2] = a;\n                    c[(i + 12) >> 2] = i;\n                    c[(i + 8) >> 2] = i;\n                }\n                else {\n                    a = c[a >> 2] | 0;\n                    b: do\n                        if (((c[(a + 4) >> 2] & -8) | 0) != (f | 0)) {\n                            e = f << ((e | 0) == 31 ? 0 : (25 - (e >>> 1)) | 0);\n                            while (1) {\n                                d = (a + 16 + ((e >>> 31) << 2)) | 0;\n                                b = c[d >> 2] | 0;\n                                if (!b)\n                                    break;\n                                if (((c[(b + 4) >> 2] & -8) | 0) == (f | 0)) {\n                                    a = b;\n                                    break b;\n                                }\n                                else {\n                                    e = e << 1;\n                                    a = b;\n                                }\n                            }\n                            c[d >> 2] = i;\n                            c[(i + 24) >> 2] = a;\n                            c[(i + 12) >> 2] = i;\n                            c[(i + 8) >> 2] = i;\n                            break a;\n                        }\n                    while (0);\n                    h = (a + 8) | 0;\n                    j = c[h >> 2] | 0;\n                    c[(j + 12) >> 2] = i;\n                    c[h >> 2] = i;\n                    c[(i + 8) >> 2] = j;\n                    c[(i + 12) >> 2] = a;\n                    c[(i + 24) >> 2] = 0;\n                }\n            while (0);\n            j = ((c[5420] | 0) + -1) | 0;\n            c[5420] = j;\n            if (j | 0)\n                return;\n            a = 22104;\n            while (1) {\n                a = c[a >> 2] | 0;\n                if (!a)\n                    break;\n                else\n                    a = (a + 8) | 0;\n            }\n            c[5420] = -1;\n            return;\n        }\n        function fr(a) {\n            a = a | 0;\n            var b = 0, d = 0, e = 0;\n            e = (a + 3) & -4;\n            a = sr() | 0;\n            b = c[a >> 2] | 0;\n            d = (b + e) | 0;\n            do\n                if (((e | 0) < 1) | (d >>> 0 > b >>> 0)) {\n                    if (d >>> 0 > (R() | 0) >>> 0 ? (T(d | 0) | 0) == 0 : 0)\n                        break;\n                    c[a >> 2] = d;\n                    e = b;\n                    return e | 0;\n                }\n            while (0);\n            c[(ao() | 0) >> 2] = 48;\n            e = -1;\n            return e | 0;\n        }\n        function gr(a) {\n            a = a | 0;\n            var b = 0;\n            b = V;\n            V = (V + a) | 0;\n            V = (V + 15) & -16;\n            return b | 0;\n        }\n        function hr(a) {\n            a = a | 0;\n            V = a;\n        }\n        function ir() {\n            return V | 0;\n        }\n        function jr(a, b) {\n            a = a | 0;\n            b = b | 0;\n            var c = 0, d = 0, e = 0, f = 0;\n            f = a & 65535;\n            e = b & 65535;\n            c = q(e, f) | 0;\n            d = a >>> 16;\n            a = ((c >>> 16) + (q(e, d) | 0)) | 0;\n            e = b >>> 16;\n            b = q(e, f) | 0;\n            return ((t(((a >>> 16) + (q(e, d) | 0) + ((((a & 65535) + b) | 0) >>> 16)) | 0),\n                ((a + b) << 16) | (c & 65535) | 0) | 0);\n        }\n        function kr(a, b, c, d) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            var e = 0, f = 0;\n            e = a;\n            f = c;\n            c = jr(e, f) | 0;\n            a = u() | 0;\n            return (t(((q(b, f) | 0) + (q(d, e) | 0) + a) | (a & 0) | 0), c | 0 | 0) | 0;\n        }\n        function lr(a, b, c, d) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            c = (a + c) >>> 0;\n            return (t(((b + d + ((c >>> 0 < a >>> 0) | 0)) >>> 0) | 0), c | 0) | 0;\n        }\n        function mr(a, b, c, d) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            d = (b - d - ((c >>> 0 > a >>> 0) | 0)) >>> 0;\n            return (t(d | 0), ((a - c) >>> 0) | 0) | 0;\n        }\n        function nr(a) {\n            a = a | 0;\n            return (a ? (31 - (r(a ^ (a - 1)) | 0)) | 0 : 32) | 0;\n        }\n        function or(a, b, d, e, f) {\n            a = a | 0;\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            var g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0;\n            l = a;\n            j = b;\n            k = j;\n            h = d;\n            n = e;\n            i = n;\n            if (!k) {\n                g = (f | 0) != 0;\n                if (!i) {\n                    if (g) {\n                        c[f >> 2] = (l >>> 0) % (h >>> 0);\n                        c[(f + 4) >> 2] = 0;\n                    }\n                    n = 0;\n                    f = ((l >>> 0) / (h >>> 0)) >>> 0;\n                    return (t(n | 0), f) | 0;\n                }\n                else {\n                    if (!g) {\n                        n = 0;\n                        f = 0;\n                        return (t(n | 0), f) | 0;\n                    }\n                    c[f >> 2] = a | 0;\n                    c[(f + 4) >> 2] = b & 0;\n                    n = 0;\n                    f = 0;\n                    return (t(n | 0), f) | 0;\n                }\n            }\n            g = (i | 0) == 0;\n            do\n                if (h) {\n                    if (!g) {\n                        g = ((r(i | 0) | 0) - (r(k | 0) | 0)) | 0;\n                        if (g >>> 0 <= 31) {\n                            m = (g + 1) | 0;\n                            i = (31 - g) | 0;\n                            b = (g - 31) >> 31;\n                            h = m;\n                            a = ((l >>> (m >>> 0)) & b) | (k << i);\n                            b = (k >>> (m >>> 0)) & b;\n                            g = 0;\n                            i = l << i;\n                            break;\n                        }\n                        if (!f) {\n                            n = 0;\n                            f = 0;\n                            return (t(n | 0), f) | 0;\n                        }\n                        c[f >> 2] = a | 0;\n                        c[(f + 4) >> 2] = j | (b & 0);\n                        n = 0;\n                        f = 0;\n                        return (t(n | 0), f) | 0;\n                    }\n                    g = (h - 1) | 0;\n                    if ((g & h) | 0) {\n                        i = ((r(h | 0) | 0) + 33 - (r(k | 0) | 0)) | 0;\n                        p = (64 - i) | 0;\n                        m = (32 - i) | 0;\n                        j = m >> 31;\n                        o = (i - 32) | 0;\n                        b = o >> 31;\n                        h = i;\n                        a = (((m - 1) >> 31) & (k >>> (o >>> 0))) | (((k << m) | (l >>> (i >>> 0))) & b);\n                        b = b & (k >>> (i >>> 0));\n                        g = (l << p) & j;\n                        i = (((k << p) | (l >>> (o >>> 0))) & j) | ((l << m) & ((i - 33) >> 31));\n                        break;\n                    }\n                    if (f | 0) {\n                        c[f >> 2] = g & l;\n                        c[(f + 4) >> 2] = 0;\n                    }\n                    if ((h | 0) == 1) {\n                        o = j | (b & 0);\n                        p = a | 0 | 0;\n                        return (t(o | 0), p) | 0;\n                    }\n                    else {\n                        p = nr(h | 0) | 0;\n                        o = (k >>> (p >>> 0)) | 0;\n                        p = (k << (32 - p)) | (l >>> (p >>> 0)) | 0;\n                        return (t(o | 0), p) | 0;\n                    }\n                }\n                else {\n                    if (g) {\n                        if (f | 0) {\n                            c[f >> 2] = (k >>> 0) % (h >>> 0);\n                            c[(f + 4) >> 2] = 0;\n                        }\n                        o = 0;\n                        p = ((k >>> 0) / (h >>> 0)) >>> 0;\n                        return (t(o | 0), p) | 0;\n                    }\n                    if (!l) {\n                        if (f | 0) {\n                            c[f >> 2] = 0;\n                            c[(f + 4) >> 2] = (k >>> 0) % (i >>> 0);\n                        }\n                        o = 0;\n                        p = ((k >>> 0) / (i >>> 0)) >>> 0;\n                        return (t(o | 0), p) | 0;\n                    }\n                    g = (i - 1) | 0;\n                    if (!(g & i)) {\n                        if (f | 0) {\n                            c[f >> 2] = a | 0;\n                            c[(f + 4) >> 2] = (g & k) | (b & 0);\n                        }\n                        o = 0;\n                        p = k >>> ((nr(i | 0) | 0) >>> 0);\n                        return (t(o | 0), p) | 0;\n                    }\n                    g = ((r(i | 0) | 0) - (r(k | 0) | 0)) | 0;\n                    if (g >>> 0 <= 30) {\n                        b = (g + 1) | 0;\n                        i = (31 - g) | 0;\n                        h = b;\n                        a = (k << i) | (l >>> (b >>> 0));\n                        b = k >>> (b >>> 0);\n                        g = 0;\n                        i = l << i;\n                        break;\n                    }\n                    if (!f) {\n                        o = 0;\n                        p = 0;\n                        return (t(o | 0), p) | 0;\n                    }\n                    c[f >> 2] = a | 0;\n                    c[(f + 4) >> 2] = j | (b & 0);\n                    o = 0;\n                    p = 0;\n                    return (t(o | 0), p) | 0;\n                }\n            while (0);\n            if (!h) {\n                k = i;\n                j = 0;\n                i = 0;\n            }\n            else {\n                m = d | 0 | 0;\n                l = n | (e & 0);\n                k = lr(m | 0, l | 0, -1, -1) | 0;\n                d = u() | 0;\n                j = i;\n                i = 0;\n                do {\n                    e = j;\n                    j = (g >>> 31) | (j << 1);\n                    g = i | (g << 1);\n                    e = (a << 1) | (e >>> 31) | 0;\n                    n = (a >>> 31) | (b << 1) | 0;\n                    mr(k | 0, d | 0, e | 0, n | 0) | 0;\n                    p = u() | 0;\n                    o = (p >> 31) | (((p | 0) < 0 ? -1 : 0) << 1);\n                    i = o & 1;\n                    a =\n                        mr(e | 0, n | 0, (o & m) | 0, (((((p | 0) < 0 ? -1 : 0) >> 31) | (((p | 0) < 0 ? -1 : 0) << 1)) & l) | 0) | 0;\n                    b = u() | 0;\n                    h = (h - 1) | 0;\n                } while ((h | 0) != 0);\n                k = j;\n                j = 0;\n            }\n            h = 0;\n            if (f | 0) {\n                c[f >> 2] = a;\n                c[(f + 4) >> 2] = b;\n            }\n            o = ((g | 0) >>> 31) | ((k | h) << 1) | (((h << 1) | (g >>> 31)) & 0) | j;\n            p = (((g << 1) | (0 >>> 31)) & -2) | i;\n            return (t(o | 0), p) | 0;\n        }\n        function pr(a, b, c, d) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            return or(a, b, c, d, 0) | 0;\n        }\n        function qr(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            if ((c | 0) < 32) {\n                t((b >>> c) | 0);\n                return (a >>> c) | ((b & ((1 << c) - 1)) << (32 - c));\n            }\n            t(0);\n            return (b >>> (c - 32)) | 0;\n        }\n        function rr(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            if ((c | 0) < 32) {\n                t((b << c) | ((a & (((1 << c) - 1) << (32 - c))) >>> (32 - c)) | 0);\n                return a << c;\n            }\n            t((a << (c - 32)) | 0);\n            return 0;\n        }\n        function sr() {\n            return 22176;\n        }\n        function tr(a) {\n            a = a | 0;\n            return (((a & 255) << 24) | (((a >> 8) & 255) << 16) | (((a >> 16) & 255) << 8) | (a >>> 24) | 0);\n        }\n        function ur(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0;\n            if ((e | 0) >= 512) {\n                S(b | 0, d | 0, e | 0) | 0;\n                return b | 0;\n            }\n            h = b | 0;\n            g = (b + e) | 0;\n            if ((b & 3) == (d & 3)) {\n                while (b & 3) {\n                    if (!e)\n                        return h | 0;\n                    a[b >> 0] = a[d >> 0] | 0;\n                    b = (b + 1) | 0;\n                    d = (d + 1) | 0;\n                    e = (e - 1) | 0;\n                }\n                e = (g & -4) | 0;\n                f = (e - 64) | 0;\n                while ((b | 0) <= (f | 0)) {\n                    c[b >> 2] = c[d >> 2];\n                    c[(b + 4) >> 2] = c[(d + 4) >> 2];\n                    c[(b + 8) >> 2] = c[(d + 8) >> 2];\n                    c[(b + 12) >> 2] = c[(d + 12) >> 2];\n                    c[(b + 16) >> 2] = c[(d + 16) >> 2];\n                    c[(b + 20) >> 2] = c[(d + 20) >> 2];\n                    c[(b + 24) >> 2] = c[(d + 24) >> 2];\n                    c[(b + 28) >> 2] = c[(d + 28) >> 2];\n                    c[(b + 32) >> 2] = c[(d + 32) >> 2];\n                    c[(b + 36) >> 2] = c[(d + 36) >> 2];\n                    c[(b + 40) >> 2] = c[(d + 40) >> 2];\n                    c[(b + 44) >> 2] = c[(d + 44) >> 2];\n                    c[(b + 48) >> 2] = c[(d + 48) >> 2];\n                    c[(b + 52) >> 2] = c[(d + 52) >> 2];\n                    c[(b + 56) >> 2] = c[(d + 56) >> 2];\n                    c[(b + 60) >> 2] = c[(d + 60) >> 2];\n                    b = (b + 64) | 0;\n                    d = (d + 64) | 0;\n                }\n                while ((b | 0) < (e | 0)) {\n                    c[b >> 2] = c[d >> 2];\n                    b = (b + 4) | 0;\n                    d = (d + 4) | 0;\n                }\n            }\n            else {\n                e = (g - 4) | 0;\n                while ((b | 0) < (e | 0)) {\n                    a[b >> 0] = a[d >> 0] | 0;\n                    a[(b + 1) >> 0] = a[(d + 1) >> 0] | 0;\n                    a[(b + 2) >> 0] = a[(d + 2) >> 0] | 0;\n                    a[(b + 3) >> 0] = a[(d + 3) >> 0] | 0;\n                    b = (b + 4) | 0;\n                    d = (d + 4) | 0;\n                }\n            }\n            while ((b | 0) < (g | 0)) {\n                a[b >> 0] = a[d >> 0] | 0;\n                b = (b + 1) | 0;\n                d = (d + 1) | 0;\n            }\n            return h | 0;\n        }\n        function vr(b, c, d) {\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            var e = 0;\n            if (((c | 0) < (b | 0)) & ((b | 0) < ((c + d) | 0))) {\n                e = b;\n                c = (c + d) | 0;\n                b = (b + d) | 0;\n                while ((d | 0) > 0) {\n                    b = (b - 1) | 0;\n                    c = (c - 1) | 0;\n                    d = (d - 1) | 0;\n                    a[b >> 0] = a[c >> 0] | 0;\n                }\n                b = e;\n            }\n            else\n                ur(b, c, d) | 0;\n            return b | 0;\n        }\n        function wr(b, d, e) {\n            b = b | 0;\n            d = d | 0;\n            e = e | 0;\n            var f = 0, g = 0, h = 0, i = 0;\n            h = (b + e) | 0;\n            d = d & 255;\n            if ((e | 0) >= 67) {\n                while (b & 3) {\n                    a[b >> 0] = d;\n                    b = (b + 1) | 0;\n                }\n                f = (h & -4) | 0;\n                i = d | (d << 8) | (d << 16) | (d << 24);\n                g = (f - 64) | 0;\n                while ((b | 0) <= (g | 0)) {\n                    c[b >> 2] = i;\n                    c[(b + 4) >> 2] = i;\n                    c[(b + 8) >> 2] = i;\n                    c[(b + 12) >> 2] = i;\n                    c[(b + 16) >> 2] = i;\n                    c[(b + 20) >> 2] = i;\n                    c[(b + 24) >> 2] = i;\n                    c[(b + 28) >> 2] = i;\n                    c[(b + 32) >> 2] = i;\n                    c[(b + 36) >> 2] = i;\n                    c[(b + 40) >> 2] = i;\n                    c[(b + 44) >> 2] = i;\n                    c[(b + 48) >> 2] = i;\n                    c[(b + 52) >> 2] = i;\n                    c[(b + 56) >> 2] = i;\n                    c[(b + 60) >> 2] = i;\n                    b = (b + 64) | 0;\n                }\n                while ((b | 0) < (f | 0)) {\n                    c[b >> 2] = i;\n                    b = (b + 4) | 0;\n                }\n            }\n            while ((b | 0) < (h | 0)) {\n                a[b >> 0] = d;\n                b = (b + 1) | 0;\n            }\n            return (h - e) | 0;\n        }\n        function xr(a) {\n            a = a | 0;\n            return Y[a & 3]() | 0;\n        }\n        function yr(a, b) {\n            a = a | 0;\n            b = b | 0;\n            return Z[a & 15](b | 0) | 0;\n        }\n        function zr(a, b, c, d, e, f, g) {\n            a = a | 0;\n            b = b | 0;\n            c = +c;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            return _[a & 1](b | 0, +c, d | 0, e | 0, f | 0, g | 0) | 0;\n        }\n        function Ar(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            return $[a & 63](b | 0, c | 0) | 0;\n        }\n        function Br(a, b, c, d) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            return aa[a & 7](b | 0, c | 0, d | 0) | 0;\n        }\n        function Cr(a) {\n            a = a | 0;\n            ba[a & 3]();\n        }\n        function Dr(a, b) {\n            a = a | 0;\n            b = b | 0;\n            ca[a & 255](b | 0);\n        }\n        function Er(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            da[a & 15](b | 0, c | 0);\n        }\n        function Fr(a, b, c, d) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            ea[a & 15](b | 0, c | 0, d | 0);\n        }\n        function Gr(a, b, c, d, e) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            e = e | 0;\n            fa[a & 7](b | 0, c | 0, d | 0, e | 0);\n        }\n        function Hr(a, b, c, d, e, f) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            ga[a & 3](b | 0, c | 0, d | 0, e | 0, f | 0);\n        }\n        function Ir(a, b, c, d, e, f, g) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            g = g | 0;\n            ha[a & 3](b | 0, c | 0, d | 0, e | 0, f | 0, g | 0);\n        }\n        function Jr() {\n            s(0);\n            return 0;\n        }\n        function Kr(a) {\n            a = a | 0;\n            s(1);\n            return 0;\n        }\n        function Lr(a, b, c, d, e, f) {\n            a = a | 0;\n            b = +b;\n            c = c | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            s(2);\n            return 0;\n        }\n        function Mr(a, b) {\n            a = a | 0;\n            b = b | 0;\n            s(3);\n            return 0;\n        }\n        function Nr(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            s(4);\n            return 0;\n        }\n        function Or() {\n            s(5);\n        }\n        function Pr(a) {\n            a = a | 0;\n            s(6);\n        }\n        function Qr(a, b) {\n            a = a | 0;\n            b = b | 0;\n            s(7);\n        }\n        function Rr(a, b, c) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            s(8);\n        }\n        function Sr(a, b, c, d) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            s(9);\n        }\n        function Tr(a, b, c, d, e) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            e = e | 0;\n            s(10);\n        }\n        function Ur(a, b, c, d, e, f) {\n            a = a | 0;\n            b = b | 0;\n            c = c | 0;\n            d = d | 0;\n            e = e | 0;\n            f = f | 0;\n            s(11);\n        }\n        // EMSCRIPTEN_END_FUNCS\n        var Y = [Jr, Mk, Fl, Jr];\n        var Z = [Kr, Ap, zb, Fb, qp, tp, oq, Kq, Tq, wk, na, tl, Ok, Hl, Kr, Kr];\n        var _ = [Lr, po];\n        var $ = [\n            Mr,\n            Ba,\n            Ka,\n            Eb,\n            jd,\n            Nd,\n            Xd,\n            je,\n            ke,\n            ne,\n            _e,\n            ff,\n            yf,\n            Ff,\n            Of,\n            Vf,\n            Hg,\n            Qg,\n            Zg,\n            ch,\n            lh,\n            qh,\n            zh,\n            Eh,\n            Nh,\n            _h,\n            fi,\n            ki,\n            si,\n            Bi,\n            Si,\n            Zi,\n            fj,\n            oj,\n            yj,\n            Fj,\n            Pj,\n            Yj,\n            ek,\n            lk,\n            tk,\n            ll,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr,\n            Mr\n        ];\n        var aa = [Nr, Io, Yo, Fp, Hp, Mq, Nq, Nr];\n        var ba = [Or, Dp, Po, Or];\n        var ca = [\n            Pr,\n            pq,\n            za,\n            Aa,\n            Ca,\n            Ia,\n            Ja,\n            La,\n            yp,\n            ob,\n            Gb,\n            yb,\n            Bb,\n            Cb,\n            Lb,\n            Mb,\n            Xb,\n            Yb,\n            sc,\n            tc,\n            uc,\n            Nc,\n            hd,\n            id,\n            kd,\n            Jd,\n            Od,\n            Pd,\n            Qd,\n            Rd,\n            Vd,\n            Wd,\n            Yd,\n            he,\n            ie,\n            le,\n            me,\n            Ye,\n            Ze,\n            $e,\n            df,\n            ef,\n            wf,\n            xf,\n            zf,\n            Df,\n            Ef,\n            Mf,\n            Nf,\n            Pf,\n            Tf,\n            Uf,\n            Fg,\n            Gg,\n            Ig,\n            Rg,\n            Sg,\n            Xg,\n            Yg,\n            _g,\n            dh,\n            eh,\n            jh,\n            kh,\n            mh,\n            rh,\n            sh,\n            xh,\n            yh,\n            Ah,\n            Fh,\n            Gh,\n            Lh,\n            Mh,\n            Oh,\n            Yh,\n            Zh,\n            $h,\n            di,\n            ei,\n            gi,\n            li,\n            mi,\n            qi,\n            ri,\n            ti,\n            zi,\n            Ai,\n            Qi,\n            Ri,\n            Ti,\n            Xi,\n            Yi,\n            dj,\n            ej,\n            gj,\n            mj,\n            nj,\n            wj,\n            xj,\n            zj,\n            Dj,\n            Ej,\n            Nj,\n            Oj,\n            Qj,\n            Wj,\n            Xj,\n            ck,\n            dk,\n            fk,\n            jk,\n            kk,\n            rk,\n            sk,\n            uk,\n            Uo,\n            Vo,\n            Wo,\n            Xo,\n            fp,\n            op,\n            pp,\n            rp,\n            sp,\n            zp,\n            Bp,\n            Cp,\n            Ep,\n            Gp,\n            Lp,\n            mq,\n            nq,\n            Iq,\n            Jq,\n            Sq,\n            Yq,\n            Zq,\n            zk,\n            wl,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr,\n            Pr\n        ];\n        var da = [Qr, Ab, Db, ma, pa, qa, ra, sa, qo, Qr, Qr, Qr, Qr, Qr, Qr, Qr];\n        var ea = [Rr, Lq, Oq, Uq, Vq, la, oa, dl, Vl, $l, Rr, Rr, Rr, Rr, Rr, Rr];\n        var fa = [Sr, $o, ip, Op, Vk, Ol, Sr, Sr];\n        var ga = [Tr, _o, hp, Np];\n        var ha = [Ur, Zo, gp, Mp];\n        return {\n            __ZSt18uncaught_exceptionv: kq,\n            ___cxa_can_catch: hq,\n            ___cxa_is_pointer_type: iq,\n            ___embind_register_native_and_builtin_types: im,\n            ___errno_location: ao,\n            ___getTypeName: $n,\n            ___muldi3: kr,\n            ___udivdi3: pr,\n            _bitshift64Lshr: qr,\n            _bitshift64Shl: rr,\n            _emscripten_get_sbrk_ptr: sr,\n            _free: er,\n            _i64Add: lr,\n            _i64Subtract: mr,\n            _llvm_bswap_i32: tr,\n            _malloc: dr,\n            _memcpy: ur,\n            _memmove: vr,\n            _memset: wr,\n            dynCall_i: xr,\n            dynCall_ii: yr,\n            dynCall_iidiiii: zr,\n            dynCall_iii: Ar,\n            dynCall_iiii: Br,\n            dynCall_v: Cr,\n            dynCall_vi: Dr,\n            dynCall_vii: Er,\n            dynCall_viii: Fr,\n            dynCall_viiii: Gr,\n            dynCall_viiiii: Hr,\n            dynCall_viiiiii: Ir,\n            globalCtors: ia,\n            stackAlloc: gr,\n            stackRestore: hr,\n            stackSave: ir\n        };\n    })(\n    // EMSCRIPTEN_END_ASM\n    asmGlobalArg, asmLibraryArg, buffer);\n    var __ZSt18uncaught_exceptionv = (Module['__ZSt18uncaught_exceptionv'] =\n        asm['__ZSt18uncaught_exceptionv']);\n    (Module['___cxa_can_catch'] = asm['___cxa_can_catch']);\n    (Module['___cxa_is_pointer_type'] = asm['___cxa_is_pointer_type']);\n    (Module['___embind_register_native_and_builtin_types'] = asm['___embind_register_native_and_builtin_types']);\n    (Module['___errno_location'] = asm['___errno_location']);\n    var ___getTypeName = (Module['___getTypeName'] = asm['___getTypeName']);\n    (Module['___muldi3'] = asm['___muldi3']);\n    (Module['___udivdi3'] = asm['___udivdi3']);\n    (Module['_bitshift64Lshr'] = asm['_bitshift64Lshr']);\n    (Module['_bitshift64Shl'] = asm['_bitshift64Shl']);\n    (Module['_emscripten_get_sbrk_ptr'] =\n        asm['_emscripten_get_sbrk_ptr']);\n    var _free = (Module['_free'] = asm['_free']);\n    (Module['_i64Add'] = asm['_i64Add']);\n    (Module['_i64Subtract'] = asm['_i64Subtract']);\n    (Module['_llvm_bswap_i32'] = asm['_llvm_bswap_i32']);\n    var _malloc = (Module['_malloc'] = asm['_malloc']);\n    (Module['_memcpy'] = asm['_memcpy']);\n    (Module['_memmove'] = asm['_memmove']);\n    (Module['_memset'] = asm['_memset']);\n    var globalCtors = (Module['globalCtors'] = asm['globalCtors']);\n    (Module['stackAlloc'] = asm['stackAlloc']);\n    (Module['stackRestore'] = asm['stackRestore']);\n    (Module['stackSave'] = asm['stackSave']);\n    (Module['dynCall_i'] = asm['dynCall_i']);\n    (Module['dynCall_ii'] = asm['dynCall_ii']);\n    (Module['dynCall_iidiiii'] = asm['dynCall_iidiiii']);\n    (Module['dynCall_iii'] = asm['dynCall_iii']);\n    (Module['dynCall_iiii'] = asm['dynCall_iiii']);\n    (Module['dynCall_v'] = asm['dynCall_v']);\n    (Module['dynCall_vi'] = asm['dynCall_vi']);\n    (Module['dynCall_vii'] = asm['dynCall_vii']);\n    (Module['dynCall_viii'] = asm['dynCall_viii']);\n    (Module['dynCall_viiii'] = asm['dynCall_viiii']);\n    (Module['dynCall_viiiii'] = asm['dynCall_viiiii']);\n    (Module['dynCall_viiiiii'] = asm['dynCall_viiiiii']);\n    Module['asm'] = asm;\n    if (memoryInitializer) {\n        if (!isDataURI(memoryInitializer)) {\n            memoryInitializer = locateFile(memoryInitializer);\n        }\n        if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {\n            var data = readBinary(memoryInitializer);\n            HEAPU8.set(data, GLOBAL_BASE);\n        }\n        else {\n            addRunDependency();\n            var applyMemoryInitializer = function (data) {\n                if (data.byteLength)\n                    data = new Uint8Array(data);\n                HEAPU8.set(data, GLOBAL_BASE);\n                if (Module['memoryInitializerRequest'])\n                    delete Module['memoryInitializerRequest'].response;\n                removeRunDependency();\n            };\n            var doBrowserLoad = function () {\n                readAsync(memoryInitializer, applyMemoryInitializer, function () {\n                    var e = new Error('could not load memory initializer ' + memoryInitializer);\n                    throw e;\n                });\n            };\n            var memoryInitializerBytes = tryParseAsDataURI(memoryInitializer);\n            if (memoryInitializerBytes) {\n                applyMemoryInitializer(memoryInitializerBytes.buffer);\n            }\n            else if (Module['memoryInitializerRequest']) {\n                var useRequest = function () {\n                    var request = Module['memoryInitializerRequest'];\n                    var response = request.response;\n                    if (request.status !== 200 && request.status !== 0) {\n                        var data = tryParseAsDataURI(Module['memoryInitializerRequestURL']);\n                        if (data) {\n                            response = data.buffer;\n                        }\n                        else {\n                            console.warn('a problem seems to have happened with Module.memoryInitializerRequest, status: ' +\n                                request.status +\n                                ', retrying ' +\n                                memoryInitializer);\n                            doBrowserLoad();\n                            return;\n                        }\n                    }\n                    applyMemoryInitializer(response);\n                };\n                if (Module['memoryInitializerRequest'].response) {\n                    setTimeout(useRequest, 0);\n                }\n                else {\n                    Module['memoryInitializerRequest'].addEventListener('load', useRequest);\n                }\n            }\n            else {\n                doBrowserLoad();\n            }\n        }\n    }\n    var calledRun;\n    function ExitStatus(status) {\n        this.name = 'ExitStatus';\n        this.message = 'Program terminated with exit(' + status + ')';\n        this.status = status;\n    }\n    dependenciesFulfilled = function runCaller() {\n        if (!calledRun)\n            run();\n        if (!calledRun)\n            dependenciesFulfilled = runCaller;\n    };\n    function run(args) {\n        if (runDependencies > 0) {\n            return;\n        }\n        preRun();\n        if (runDependencies > 0)\n            return;\n        function doRun() {\n            if (calledRun)\n                return;\n            calledRun = true;\n            Module['calledRun'] = true;\n            if (ABORT)\n                return;\n            initRuntime();\n            preMain();\n            if (Module['onRuntimeInitialized'])\n                Module['onRuntimeInitialized']();\n            postRun();\n        }\n        if (Module['setStatus']) {\n            Module['setStatus']('Running...');\n            setTimeout(function () {\n                setTimeout(function () {\n                    Module['setStatus']('');\n                }, 1);\n                doRun();\n            }, 1);\n        }\n        else {\n            doRun();\n        }\n    }\n    Module['run'] = run;\n    if (Module['preInit']) {\n        if (typeof Module['preInit'] == 'function')\n            Module['preInit'] = [Module['preInit']];\n        while (Module['preInit'].length > 0) {\n            Module['preInit'].pop()();\n        }\n    }\n    run();\n    return Module;\n}\n\nlet Module = null;\nconst POINT_FORMAT_READERS = {\n    0: (dv) => {\n        return {\n            position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],\n            intensity: dv.getUint16(12, true),\n            classification: dv.getUint8(15)\n        };\n    },\n    1: (dv) => {\n        return {\n            position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],\n            intensity: dv.getUint16(12, true),\n            classification: dv.getUint8(15)\n        };\n    },\n    2: (dv) => {\n        return {\n            position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],\n            intensity: dv.getUint16(12, true),\n            classification: dv.getUint8(15),\n            color: [dv.getUint16(20, true), dv.getUint16(22, true), dv.getUint16(24, true)]\n        };\n    },\n    3: (dv) => {\n        return {\n            position: [dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)],\n            intensity: dv.getUint16(12, true),\n            classification: dv.getUint8(15),\n            color: [dv.getUint16(28, true), dv.getUint16(30, true), dv.getUint16(32, true)]\n        };\n    }\n};\n/**\n * Reads incoming binary data depends on the Type parameter\n * @param buf\n * @param Type\n * @param offset\n * @param count\n * @returns number | number[] from incoming binary data\n */\nfunction readAs(buf, Type = {}, offset, count) {\n    count = count === undefined || count === 0 ? 1 : count;\n    const sub = buf.slice(offset, offset + Type.BYTES_PER_ELEMENT * count);\n    const r = new Type(sub);\n    if (count === 1) {\n        return r[0];\n    }\n    const ret = [];\n    for (let i = 0; i < count; i++) {\n        ret.push(r[i]);\n    }\n    return ret;\n}\n/**\n * Parsing of header's attributes\n * @param arraybuffer\n * @returns header as LASHeader\n */\nfunction parseLASHeader(arraybuffer) {\n    let start = 32 * 3 + 35;\n    const o = {\n        pointsOffset: readAs(arraybuffer, Uint32Array, 32 * 3),\n        pointsFormatId: readAs(arraybuffer, Uint8Array, 32 * 3 + 8),\n        pointsStructSize: readAs(arraybuffer, Uint16Array, 32 * 3 + 8 + 1),\n        pointsCount: readAs(arraybuffer, Uint32Array, 32 * 3 + 11),\n        scale: readAs(arraybuffer, Float64Array, start, 3)\n    };\n    start += 24; // 8*3\n    o.offset = readAs(arraybuffer, Float64Array, start, 3);\n    start += 24;\n    const bounds = readAs(arraybuffer, Float64Array, start, 6);\n    start += 48; // 8*6;\n    o.maxs = [bounds[0], bounds[2], bounds[4]];\n    o.mins = [bounds[1], bounds[3], bounds[5]];\n    return o;\n}\n// LAS Loader\n// Loads uncompressed files\n//\nclass LASLoader$1 {\n    arraybuffer;\n    readOffset = 0;\n    header = {\n        pointsOffset: 0,\n        pointsFormatId: 0,\n        pointsStructSize: 0,\n        pointsCount: 0,\n        scale: [0, 0, 0],\n        offset: [0, 0, 0],\n        maxs: [0],\n        mins: [0],\n        totalToRead: 0,\n        totalRead: 0,\n        versionAsString: '',\n        isCompressed: true\n    };\n    constructor(arraybuffer) {\n        this.arraybuffer = arraybuffer;\n    }\n    /**\n     * @returns boolean\n     */\n    open() {\n        // Nothing needs to be done to open this\n        return true;\n    }\n    /**\n     * Parsing of incoming binary\n     * @returns LASHeader\n     */\n    getHeader() {\n        this.header = parseLASHeader(this.arraybuffer);\n        return this.header;\n    }\n    /**\n     * Reading data\n     * @param count\n     * @param skip\n     * @returns new ArrayBuffer, count, hasMoreData\n     */\n    readData(count, skip) {\n        const { header, arraybuffer } = this;\n        if (!header) {\n            throw new Error('Cannot start reading data till a header request is issued');\n        }\n        let { readOffset } = this;\n        let start;\n        if (skip <= 1) {\n            count = Math.min(count, header.pointsCount - readOffset);\n            start = header.pointsOffset + readOffset * header.pointsStructSize;\n            const end = start + count * header.pointsStructSize;\n            readOffset += count;\n            this.readOffset = readOffset;\n            return {\n                buffer: arraybuffer.slice(start, end),\n                count,\n                hasMoreData: readOffset < header.pointsCount\n            };\n        }\n        const pointsToRead = Math.min(count * skip, header.pointsCount - readOffset);\n        const bufferSize = Math.ceil(pointsToRead / skip);\n        let pointsRead = 0;\n        const buf = new Uint8Array(bufferSize * header.pointsStructSize);\n        for (let i = 0; i < pointsToRead; i++) {\n            if (i % skip === 0) {\n                start = header.pointsOffset + readOffset * header.pointsStructSize;\n                const src = new Uint8Array(arraybuffer, start, header.pointsStructSize);\n                buf.set(src, pointsRead * header.pointsStructSize);\n                pointsRead++;\n            }\n            readOffset++;\n        }\n        this.readOffset = readOffset;\n        return {\n            buffer: buf.buffer,\n            count: pointsRead,\n            hasMoreData: readOffset < header.pointsCount\n        };\n    }\n    /**\n     * Method which brings data to null to close the file\n     * @returns\n     */\n    close() {\n        // @ts-ignore Possibly null\n        this.arraybuffer = null;\n        return true;\n    }\n}\n/**\n * LAZ Loader\n * Uses NaCL module to load LAZ files\n */\nclass LAZLoader {\n    arraybuffer;\n    instance = null; // LASZip instance\n    header = null;\n    constructor(arraybuffer) {\n        this.arraybuffer = arraybuffer;\n        if (!Module) {\n            // Avoid executing laz-perf on import\n            Module = getModule();\n        }\n    }\n    /**\n     * Opens the file\n     * @returns boolean\n     */\n    open() {\n        try {\n            const { arraybuffer } = this;\n            this.instance = new Module.LASZip();\n            const abInt = new Uint8Array(arraybuffer);\n            const buf = Module._malloc(arraybuffer.byteLength);\n            this.instance.arraybuffer = arraybuffer;\n            this.instance.buf = buf;\n            Module.HEAPU8.set(abInt, buf);\n            this.instance.open(buf, arraybuffer.byteLength);\n            this.instance.readOffset = 0;\n            return true;\n        }\n        catch (error) {\n            throw new Error(`Failed to open file: ${error.message}`);\n        }\n    }\n    getHeader() {\n        if (!this.instance) {\n            throw new Error('You need to open the file before trying to read header');\n        }\n        try {\n            const header = parseLASHeader(this.instance.arraybuffer);\n            header.pointsFormatId &= 0x3f;\n            this.header = header;\n            return header;\n        }\n        catch (error) {\n            throw new Error(`Failed to get header: ${error.message}`);\n        }\n    }\n    /**\n     * @param count\n     * @param offset\n     * @param skip\n     * @returns Data\n     */\n    readData(count, offset, skip) {\n        if (!this.instance) {\n            throw new Error('You need to open the file before trying to read stuff');\n        }\n        const { header, instance } = this;\n        if (!header) {\n            throw new Error('You need to query header before reading, I maintain state that way, sorry :(');\n        }\n        try {\n            const pointsToRead = Math.min(count * skip, header.pointsCount - instance.readOffset);\n            const bufferSize = Math.ceil(pointsToRead / skip);\n            let pointsRead = 0;\n            const thisBuf = new Uint8Array(bufferSize * header.pointsStructSize);\n            const bufRead = Module._malloc(header.pointsStructSize);\n            for (let i = 0; i < pointsToRead; i++) {\n                instance.getPoint(bufRead);\n                if (i % skip === 0) {\n                    const a = new Uint8Array(Module.HEAPU8.buffer, bufRead, header.pointsStructSize);\n                    thisBuf.set(a, pointsRead * header.pointsStructSize);\n                    pointsRead++;\n                }\n                instance.readOffset++;\n            }\n            Module._free(bufRead);\n            return {\n                buffer: thisBuf.buffer,\n                count: pointsRead,\n                hasMoreData: instance.readOffset < header.pointsCount\n            };\n        }\n        catch (error) {\n            throw new Error(`Failed to read data: ${error.message}`);\n        }\n    }\n    /**\n     * Deletes the instance\n     * @returns boolean\n     */\n    close() {\n        try {\n            if (this.instance !== null) {\n                Module._free(this.instance.buf);\n                this.instance.delete();\n                this.instance = null;\n            }\n            return true;\n        }\n        catch (error) {\n            throw new Error(`Failed to close file: ${error.message}`);\n        }\n    }\n}\n/**\n * Helper class: Decodes LAS records into points\n */\nclass LASDecoder {\n    arrayb;\n    decoder;\n    pointsCount;\n    pointSize;\n    scale;\n    offset;\n    mins;\n    maxs;\n    constructor(buffer, len, header) {\n        this.arrayb = buffer;\n        this.decoder = POINT_FORMAT_READERS[header.pointsFormatId];\n        this.pointsCount = len;\n        this.pointSize = header.pointsStructSize;\n        this.scale = header.scale;\n        this.offset = header.offset;\n        this.mins = header.mins;\n        this.maxs = header.maxs;\n    }\n    /**\n     * Decodes data depends on this point size\n     * @param index\n     * @returns New object\n     */\n    getPoint(index) {\n        if (index < 0 || index >= this.pointsCount) {\n            throw new Error('Point index out of range');\n        }\n        const dv = new DataView(this.arrayb, index * this.pointSize, this.pointSize);\n        return this.decoder(dv);\n    }\n}\n/**\n * A single consistent interface for loading LAS/LAZ files\n */\nclass LASFile {\n    arraybuffer;\n    formatId = 0;\n    loader;\n    isCompressed = true;\n    isOpen = false;\n    version = 0;\n    versionAsString = '';\n    constructor(arraybuffer) {\n        this.arraybuffer = arraybuffer;\n        if (this.determineVersion() > 13) {\n            throw new Error('Only file versions <= 1.3 are supported at this time');\n        }\n        this.determineFormat();\n        if (POINT_FORMAT_READERS[this.formatId] === undefined) {\n            throw new Error('The point format ID is not supported');\n        }\n        this.loader = this.isCompressed\n            ? new LAZLoader(this.arraybuffer)\n            : new LASLoader$1(this.arraybuffer);\n    }\n    /**\n     * Determines format in parameters of LASHeaer\n     */\n    determineFormat() {\n        const formatId = readAs(this.arraybuffer, Uint8Array, 32 * 3 + 8);\n        const bit7 = (formatId & 0x80) >> 7;\n        const bit6 = (formatId & 0x40) >> 6;\n        if (bit7 === 1 && bit6 === 1) {\n            throw new Error('Old style compression not supported');\n        }\n        this.formatId = formatId & 0x3f;\n        this.isCompressed = bit7 === 1 || bit6 === 1;\n    }\n    /**\n     * Determines version\n     * @returns version\n     */\n    determineVersion() {\n        const ver = new Int8Array(this.arraybuffer, 24, 2);\n        this.version = ver[0] * 10 + ver[1];\n        this.versionAsString = `${ver[0]}.${ver[1]}`;\n        return this.version;\n    }\n    /**\n     * Reads if the file is open\n     * @returns boolean\n     */\n    open() {\n        if (this.loader.open()) {\n            this.isOpen = true;\n        }\n    }\n    /**\n     * Gets the header\n     * @returns Header\n     */\n    getHeader() {\n        return this.loader.getHeader();\n    }\n    /**\n     * @param count\n     * @param start\n     * @param skip\n     * @returns Data\n     */\n    readData(count, start, skip) {\n        return this.loader.readData(count, start, skip);\n    }\n    /**\n     * Closes the file\n     */\n    close() {\n        if (this.loader.close()) {\n            this.isOpen = false;\n        }\n    }\n    /**\n     */\n    getUnpacker() {\n        return LASDecoder;\n    }\n}\n/* eslint no-use-before-define: 2 */\n\n/**\n * Gets schema from PLY header\n * @param lasHeader\n * @param metadata\n * @returns Schema\n */\nfunction getLASSchema(lasHeader, attributes) {\n    const metadataMap = makeMetadataFromLasHeader(lasHeader);\n    const schema = deduceMeshSchema(attributes, metadataMap);\n    return schema;\n}\n/**\n * Make arrow like schema metadata by LASHeader properties\n * @param lasHeader\n * @returns\n */\nfunction makeMetadataFromLasHeader(lasHeader) {\n    const metadata = {};\n    /* eslint-disable camelcase */\n    metadata.las_pointsOffset = lasHeader.pointsOffset.toString(10);\n    metadata.las_pointsFormatId = lasHeader.pointsFormatId.toString(10);\n    metadata.las_pointsStructSize = lasHeader.pointsStructSize.toString(10);\n    metadata.las_pointsCount = lasHeader.pointsCount.toString(10);\n    metadata.las_scale = JSON.stringify(lasHeader.scale);\n    metadata.las_offset = JSON.stringify(lasHeader.offset);\n    if (lasHeader.maxs !== undefined) {\n        metadata.las_maxs = JSON.stringify(lasHeader.maxs);\n    }\n    if (lasHeader.mins !== undefined) {\n        metadata.las_mins = JSON.stringify(lasHeader.mins);\n    }\n    metadata.las_totalToRead = lasHeader.totalToRead.toString(10);\n    metadata.las_pointsFortotalReadmatId = lasHeader.totalRead.toString(10);\n    if (lasHeader.versionAsString !== undefined) {\n        metadata.las_versionAsString = lasHeader.versionAsString;\n    }\n    if (lasHeader.isCompressed !== undefined) {\n        metadata.las_isCompressed = lasHeader.isCompressed.toString();\n    }\n    return metadata;\n}\n\n/**\n * Parsing of .las file\n * @param arrayBuffer\n * @param options\n * @returns LASHeader\n */\nfunction parseLAS(arrayBuffer, options) {\n    return parseLASMesh(arrayBuffer, options);\n    // This code breaks pointcloud example on the website\n    // const mesh = parseLASMesh(arrayBuffer, options);\n    // return convertMesh(mesh, options?.las?.shape || 'mesh') as LASMesh | ArrowTable | ColumnarTable;\n}\n/**\n * Parsing of .las file\n * @param arrayBuffer\n * @param options\n * @returns LASHeader\n */\nfunction parseLASMesh(arrayBuffer, options = {}) {\n    let pointIndex = 0;\n    let positions;\n    let colors;\n    let intensities;\n    let classifications;\n    let originalHeader;\n    const lasMesh = {\n        loader: 'las',\n        loaderData: {},\n        // shape: 'mesh',\n        schema: { fields: [], metadata: {} },\n        header: {\n            vertexCount: 0,\n            boundingBox: [\n                [0, 0, 0],\n                [0, 0, 0]\n            ]\n        },\n        attributes: {},\n        topology: 'point-list',\n        mode: 0 // GL.POINTS\n    };\n    /* eslint-disable max-statements */\n    // @ts-ignore Possibly undefined\n    parseLASChunked(arrayBuffer, options.las?.skip, (decoder = {}, lasHeader) => {\n        if (!originalHeader) {\n            originalHeader = lasHeader;\n            const total = lasHeader.totalToRead;\n            const PositionsType = options.las?.fp64 ? Float64Array : Float32Array;\n            positions = new PositionsType(total * 3);\n            // laslaz-decoder.js `pointFormatReaders`\n            colors = lasHeader.pointsFormatId >= 2 ? new Uint8Array(total * 4) : null;\n            intensities = new Uint16Array(total);\n            classifications = new Uint8Array(total);\n            lasMesh.loaderData = lasHeader;\n            lasMesh.attributes = {\n                POSITION: { value: positions, size: 3 },\n                // non-gltf attributes, use non-capitalized names for now\n                intensity: { value: intensities, size: 1 },\n                classification: { value: classifications, size: 1 }\n            };\n            if (colors) {\n                lasMesh.attributes.COLOR_0 = { value: colors, size: 4 };\n            }\n        }\n        const batchSize = decoder.pointsCount;\n        const { scale: [scaleX, scaleY, scaleZ], offset: [offsetX, offsetY, offsetZ] } = lasHeader;\n        const twoByteColor = detectTwoByteColors(decoder, batchSize, options.las?.colorDepth);\n        for (let i = 0; i < batchSize; i++) {\n            const { position, color, intensity, classification } = decoder.getPoint(i);\n            positions[pointIndex * 3] = position[0] * scaleX + offsetX;\n            positions[pointIndex * 3 + 1] = position[1] * scaleY + offsetY;\n            positions[pointIndex * 3 + 2] = position[2] * scaleZ + offsetZ;\n            if (color && colors) {\n                if (twoByteColor) {\n                    colors[pointIndex * 4] = color[0] / 256;\n                    colors[pointIndex * 4 + 1] = color[1] / 256;\n                    colors[pointIndex * 4 + 2] = color[2] / 256;\n                }\n                else {\n                    colors[pointIndex * 4] = color[0];\n                    colors[pointIndex * 4 + 1] = color[1];\n                    colors[pointIndex * 4 + 2] = color[2];\n                }\n                colors[pointIndex * 4 + 3] = 255;\n            }\n            intensities[pointIndex] = intensity;\n            classifications[pointIndex] = classification;\n            pointIndex++;\n        }\n        const meshBatch = {\n            ...lasMesh,\n            header: {\n                vertexCount: lasHeader.totalRead\n            },\n            progress: lasHeader.totalRead / lasHeader.totalToRead\n        };\n        options?.onProgress?.(meshBatch);\n    });\n    /* eslint-enable max-statements */\n    lasMesh.header = {\n        vertexCount: originalHeader.totalToRead,\n        boundingBox: getMeshBoundingBox(lasMesh?.attributes || {})\n    };\n    if (lasMesh) {\n        lasMesh.schema = getLASSchema(lasMesh.loaderData, lasMesh.attributes);\n    }\n    return lasMesh;\n}\n/**\n * parse laz data\n * @param rawData\n * @param skip\n * @param onParseData\n * @return parsed point cloud\n */\n/* eslint-enable max-statements */\nfunction parseLASChunked(rawData, skip, onParseData = {}) {\n    const dataHandler = new LASFile(rawData);\n    try {\n        // open data\n        dataHandler.open();\n        const header = dataHandler.getHeader();\n        // start loading\n        const Unpacker = dataHandler.getUnpacker();\n        const totalToRead = Math.ceil(header.pointsCount / Math.max(1, skip));\n        header.totalToRead = totalToRead;\n        let totalRead = 0;\n        /* eslint-disable no-constant-condition */\n        while (true) {\n            const chunk = dataHandler.readData(1000 * 100, 0, skip);\n            totalRead += chunk.count;\n            header.totalRead = totalRead;\n            header.versionAsString = chunk.versionAsString;\n            header.isCompressed = chunk.isCompressed;\n            const unpacker = new Unpacker(chunk.buffer, chunk.count, header);\n            // surface unpacker and progress via call back\n            // use unpacker.pointsCount and unpacker.getPoint(i) to handle data in app\n            onParseData(unpacker, header);\n            if (!chunk.hasMoreData || totalRead >= totalToRead) {\n                break;\n            }\n        }\n    }\n    catch (e) {\n        throw e;\n    }\n    finally {\n        dataHandler.close();\n    }\n}\n/**\n * @param decoder\n * @param batchSize\n * @param colorDepth\n * @returns boolean\n */\nfunction detectTwoByteColors(decoder = {}, batchSize, colorDepth) {\n    let twoByteColor = false;\n    switch (colorDepth) {\n        case 8:\n            twoByteColor = false;\n            break;\n        case 16:\n            twoByteColor = true;\n            break;\n        case 'auto':\n            if (decoder.getPoint(0).color) {\n                for (let i = 0; i < batchSize; i++) {\n                    const { color } = decoder.getPoint(i);\n                    // eslint-disable-next-line max-depth\n                    if (color[0] > 255 || color[1] > 255 || color[2] > 255) {\n                        twoByteColor = true;\n                    }\n                }\n            }\n            break;\n        default:\n            // eslint-disable-next-line\n            console.warn('las: illegal value for options.las.colorDepth');\n            break;\n    }\n    return twoByteColor;\n}\n\n/**\n * Loader for the LAS (LASer) point cloud format\n * @note Does not support LAS v1.4\n */\nconst LASLoader = {\n    ...LASLoader$2,\n    parse: async (arrayBuffer, options) => parseLAS(arrayBuffer, options),\n    parseSync: (arrayBuffer, options) => parseLAS(arrayBuffer, options)\n};\n\n/*!\n * html2canvas 1.4.1 <https://html2canvas.hertzen.com>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\n/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n    extendStatics = Object.setPrototypeOf ||\r\n        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n    return extendStatics(d, b);\r\n};\r\n\r\nfunction __extends(d, b) {\r\n    if (typeof b !== \"function\" && b !== null)\r\n        throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n    extendStatics(d, b);\r\n    function __() { this.constructor = d; }\r\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nvar __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    };\r\n    return __assign.apply(this, arguments);\r\n};\r\n\r\nfunction __awaiter(thisArg, _arguments, P, generator) {\r\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n    return new (P || (P = Promise))(function (resolve, reject) {\r\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n    });\r\n}\r\n\r\nfunction __generator(thisArg, body) {\r\n    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n    return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n    function verb(n) { return function (v) { return step([n, v]); }; }\r\n    function step(op) {\r\n        if (f) throw new TypeError(\"Generator is already executing.\");\r\n        while (_) try {\r\n            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;\r\n            if (y = 0, t) op = [op[0] & 2, t.value];\r\n            switch (op[0]) {\r\n                case 0: case 1: t = op; break;\r\n                case 4: _.label++; return { value: op[1], done: false };\r\n                case 5: _.label++; y = op[1]; op = [0]; continue;\r\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n                default:\r\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n                    if (t[2]) _.ops.pop();\r\n                    _.trys.pop(); continue;\r\n            }\r\n            op = body.call(thisArg, _);\r\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n    }\r\n}\r\n\r\nfunction __spreadArray(to, from, pack) {\r\n    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n        if (ar || !(i in from)) {\r\n            if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n            ar[i] = from[i];\r\n        }\r\n    }\r\n    return to.concat(ar || from);\r\n}\n\nvar Bounds = /** @class */ (function () {\n    function Bounds(left, top, width, height) {\n        this.left = left;\n        this.top = top;\n        this.width = width;\n        this.height = height;\n    }\n    Bounds.prototype.add = function (x, y, w, h) {\n        return new Bounds(this.left + x, this.top + y, this.width + w, this.height + h);\n    };\n    Bounds.fromClientRect = function (context, clientRect) {\n        return new Bounds(clientRect.left + context.windowBounds.left, clientRect.top + context.windowBounds.top, clientRect.width, clientRect.height);\n    };\n    Bounds.fromDOMRectList = function (context, domRectList) {\n        var domRect = Array.from(domRectList).find(function (rect) { return rect.width !== 0; });\n        return domRect\n            ? new Bounds(domRect.left + context.windowBounds.left, domRect.top + context.windowBounds.top, domRect.width, domRect.height)\n            : Bounds.EMPTY;\n    };\n    Bounds.EMPTY = new Bounds(0, 0, 0, 0);\n    return Bounds;\n}());\nvar parseBounds = function (context, node) {\n    return Bounds.fromClientRect(context, node.getBoundingClientRect());\n};\nvar parseDocumentSize = function (document) {\n    var body = document.body;\n    var documentElement = document.documentElement;\n    if (!body || !documentElement) {\n        throw new Error(\"Unable to get document size\");\n    }\n    var width = Math.max(Math.max(body.scrollWidth, documentElement.scrollWidth), Math.max(body.offsetWidth, documentElement.offsetWidth), Math.max(body.clientWidth, documentElement.clientWidth));\n    var height = Math.max(Math.max(body.scrollHeight, documentElement.scrollHeight), Math.max(body.offsetHeight, documentElement.offsetHeight), Math.max(body.clientHeight, documentElement.clientHeight));\n    return new Bounds(0, 0, width, height);\n};\n\n/*\n * css-line-break 2.1.0 <https://github.com/niklasvh/css-line-break#readme>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar toCodePoints$1 = function (str) {\n    var codePoints = [];\n    var i = 0;\n    var length = str.length;\n    while (i < length) {\n        var value = str.charCodeAt(i++);\n        if (value >= 0xd800 && value <= 0xdbff && i < length) {\n            var extra = str.charCodeAt(i++);\n            if ((extra & 0xfc00) === 0xdc00) {\n                codePoints.push(((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000);\n            }\n            else {\n                codePoints.push(value);\n                i--;\n            }\n        }\n        else {\n            codePoints.push(value);\n        }\n    }\n    return codePoints;\n};\nvar fromCodePoint$1 = function () {\n    var codePoints = [];\n    for (var _i = 0; _i < arguments.length; _i++) {\n        codePoints[_i] = arguments[_i];\n    }\n    if (String.fromCodePoint) {\n        return String.fromCodePoint.apply(String, codePoints);\n    }\n    var length = codePoints.length;\n    if (!length) {\n        return '';\n    }\n    var codeUnits = [];\n    var index = -1;\n    var result = '';\n    while (++index < length) {\n        var codePoint = codePoints[index];\n        if (codePoint <= 0xffff) {\n            codeUnits.push(codePoint);\n        }\n        else {\n            codePoint -= 0x10000;\n            codeUnits.push((codePoint >> 10) + 0xd800, (codePoint % 0x400) + 0xdc00);\n        }\n        if (index + 1 === length || codeUnits.length > 0x4000) {\n            result += String.fromCharCode.apply(String, codeUnits);\n            codeUnits.length = 0;\n        }\n    }\n    return result;\n};\nvar chars$2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup$2 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i$2 = 0; i$2 < chars$2.length; i$2++) {\n    lookup$2[chars$2.charCodeAt(i$2)] = i$2;\n}\n\n/*\n * utrie 1.0.2 <https://github.com/niklasvh/utrie>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar chars$1$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup$1$1 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i$1$1 = 0; i$1$1 < chars$1$1.length; i$1$1++) {\n    lookup$1$1[chars$1$1.charCodeAt(i$1$1)] = i$1$1;\n}\nvar decode$1 = function (base64) {\n    var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;\n    if (base64[base64.length - 1] === '=') {\n        bufferLength--;\n        if (base64[base64.length - 2] === '=') {\n            bufferLength--;\n        }\n    }\n    var buffer = typeof ArrayBuffer !== 'undefined' &&\n        typeof Uint8Array !== 'undefined' &&\n        typeof Uint8Array.prototype.slice !== 'undefined'\n        ? new ArrayBuffer(bufferLength)\n        : new Array(bufferLength);\n    var bytes = Array.isArray(buffer) ? buffer : new Uint8Array(buffer);\n    for (i = 0; i < len; i += 4) {\n        encoded1 = lookup$1$1[base64.charCodeAt(i)];\n        encoded2 = lookup$1$1[base64.charCodeAt(i + 1)];\n        encoded3 = lookup$1$1[base64.charCodeAt(i + 2)];\n        encoded4 = lookup$1$1[base64.charCodeAt(i + 3)];\n        bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n        bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n        bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n    }\n    return buffer;\n};\nvar polyUint16Array$1 = function (buffer) {\n    var length = buffer.length;\n    var bytes = [];\n    for (var i = 0; i < length; i += 2) {\n        bytes.push((buffer[i + 1] << 8) | buffer[i]);\n    }\n    return bytes;\n};\nvar polyUint32Array$1 = function (buffer) {\n    var length = buffer.length;\n    var bytes = [];\n    for (var i = 0; i < length; i += 4) {\n        bytes.push((buffer[i + 3] << 24) | (buffer[i + 2] << 16) | (buffer[i + 1] << 8) | buffer[i]);\n    }\n    return bytes;\n};\n\n/** Shift size for getting the index-2 table offset. */\nvar UTRIE2_SHIFT_2$1 = 5;\n/** Shift size for getting the index-1 table offset. */\nvar UTRIE2_SHIFT_1$1 = 6 + 5;\n/**\n * Shift size for shifting left the index array values.\n * Increases possible data size with 16-bit index values at the cost\n * of compactability.\n * This requires data blocks to be aligned by UTRIE2_DATA_GRANULARITY.\n */\nvar UTRIE2_INDEX_SHIFT$1 = 2;\n/**\n * Difference between the two shift sizes,\n * for getting an index-1 offset from an index-2 offset. 6=11-5\n */\nvar UTRIE2_SHIFT_1_2$1 = UTRIE2_SHIFT_1$1 - UTRIE2_SHIFT_2$1;\n/**\n * The part of the index-2 table for U+D800..U+DBFF stores values for\n * lead surrogate code _units_ not code _points_.\n * Values for lead surrogate code _points_ are indexed with this portion of the table.\n * Length=32=0x20=0x400>>UTRIE2_SHIFT_2. (There are 1024=0x400 lead surrogates.)\n */\nvar UTRIE2_LSCP_INDEX_2_OFFSET$1 = 0x10000 >> UTRIE2_SHIFT_2$1;\n/** Number of entries in a data block. 32=0x20 */\nvar UTRIE2_DATA_BLOCK_LENGTH$1 = 1 << UTRIE2_SHIFT_2$1;\n/** Mask for getting the lower bits for the in-data-block offset. */\nvar UTRIE2_DATA_MASK$1 = UTRIE2_DATA_BLOCK_LENGTH$1 - 1;\nvar UTRIE2_LSCP_INDEX_2_LENGTH$1 = 0x400 >> UTRIE2_SHIFT_2$1;\n/** Count the lengths of both BMP pieces. 2080=0x820 */\nvar UTRIE2_INDEX_2_BMP_LENGTH$1 = UTRIE2_LSCP_INDEX_2_OFFSET$1 + UTRIE2_LSCP_INDEX_2_LENGTH$1;\n/**\n * The 2-byte UTF-8 version of the index-2 table follows at offset 2080=0x820.\n * Length 32=0x20 for lead bytes C0..DF, regardless of UTRIE2_SHIFT_2.\n */\nvar UTRIE2_UTF8_2B_INDEX_2_OFFSET$1 = UTRIE2_INDEX_2_BMP_LENGTH$1;\nvar UTRIE2_UTF8_2B_INDEX_2_LENGTH$1 = 0x800 >> 6; /* U+0800 is the first code point after 2-byte UTF-8 */\n/**\n * The index-1 table, only used for supplementary code points, at offset 2112=0x840.\n * Variable length, for code points up to highStart, where the last single-value range starts.\n * Maximum length 512=0x200=0x100000>>UTRIE2_SHIFT_1.\n * (For 0x100000 supplementary code points U+10000..U+10ffff.)\n *\n * The part of the index-2 table for supplementary code points starts\n * after this index-1 table.\n *\n * Both the index-1 table and the following part of the index-2 table\n * are omitted completely if there is only BMP data.\n */\nvar UTRIE2_INDEX_1_OFFSET$1 = UTRIE2_UTF8_2B_INDEX_2_OFFSET$1 + UTRIE2_UTF8_2B_INDEX_2_LENGTH$1;\n/**\n * Number of index-1 entries for the BMP. 32=0x20\n * This part of the index-1 table is omitted from the serialized form.\n */\nvar UTRIE2_OMITTED_BMP_INDEX_1_LENGTH$1 = 0x10000 >> UTRIE2_SHIFT_1$1;\n/** Number of entries in an index-2 block. 64=0x40 */\nvar UTRIE2_INDEX_2_BLOCK_LENGTH$1 = 1 << UTRIE2_SHIFT_1_2$1;\n/** Mask for getting the lower bits for the in-index-2-block offset. */\nvar UTRIE2_INDEX_2_MASK$1 = UTRIE2_INDEX_2_BLOCK_LENGTH$1 - 1;\nvar slice16$1 = function (view, start, end) {\n    if (view.slice) {\n        return view.slice(start, end);\n    }\n    return new Uint16Array(Array.prototype.slice.call(view, start, end));\n};\nvar slice32$1 = function (view, start, end) {\n    if (view.slice) {\n        return view.slice(start, end);\n    }\n    return new Uint32Array(Array.prototype.slice.call(view, start, end));\n};\nvar createTrieFromBase64$1 = function (base64, _byteLength) {\n    var buffer = decode$1(base64);\n    var view32 = Array.isArray(buffer) ? polyUint32Array$1(buffer) : new Uint32Array(buffer);\n    var view16 = Array.isArray(buffer) ? polyUint16Array$1(buffer) : new Uint16Array(buffer);\n    var headerLength = 24;\n    var index = slice16$1(view16, headerLength / 2, view32[4] / 2);\n    var data = view32[5] === 2\n        ? slice16$1(view16, (headerLength + view32[4]) / 2)\n        : slice32$1(view32, Math.ceil((headerLength + view32[4]) / 4));\n    return new Trie$1(view32[0], view32[1], view32[2], view32[3], index, data);\n};\nvar Trie$1 = /** @class */ (function () {\n    function Trie(initialValue, errorValue, highStart, highValueIndex, index, data) {\n        this.initialValue = initialValue;\n        this.errorValue = errorValue;\n        this.highStart = highStart;\n        this.highValueIndex = highValueIndex;\n        this.index = index;\n        this.data = data;\n    }\n    /**\n     * Get the value for a code point as stored in the Trie.\n     *\n     * @param codePoint the code point\n     * @return the value\n     */\n    Trie.prototype.get = function (codePoint) {\n        var ix;\n        if (codePoint >= 0) {\n            if (codePoint < 0x0d800 || (codePoint > 0x0dbff && codePoint <= 0x0ffff)) {\n                // Ordinary BMP code point, excluding leading surrogates.\n                // BMP uses a single level lookup.  BMP index starts at offset 0 in the Trie2 index.\n                // 16 bit data is stored in the index array itself.\n                ix = this.index[codePoint >> UTRIE2_SHIFT_2$1];\n                ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);\n                return this.data[ix];\n            }\n            if (codePoint <= 0xffff) {\n                // Lead Surrogate Code Point.  A Separate index section is stored for\n                // lead surrogate code units and code points.\n                //   The main index has the code unit data.\n                //   For this function, we need the code point data.\n                // Note: this expression could be refactored for slightly improved efficiency, but\n                //       surrogate code points will be so rare in practice that it's not worth it.\n                ix = this.index[UTRIE2_LSCP_INDEX_2_OFFSET$1 + ((codePoint - 0xd800) >> UTRIE2_SHIFT_2$1)];\n                ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);\n                return this.data[ix];\n            }\n            if (codePoint < this.highStart) {\n                // Supplemental code point, use two-level lookup.\n                ix = UTRIE2_INDEX_1_OFFSET$1 - UTRIE2_OMITTED_BMP_INDEX_1_LENGTH$1 + (codePoint >> UTRIE2_SHIFT_1$1);\n                ix = this.index[ix];\n                ix += (codePoint >> UTRIE2_SHIFT_2$1) & UTRIE2_INDEX_2_MASK$1;\n                ix = this.index[ix];\n                ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);\n                return this.data[ix];\n            }\n            if (codePoint <= 0x10ffff) {\n                return this.data[this.highValueIndex];\n            }\n        }\n        // Fall through.  The code point is outside of the legal range of 0..0x10ffff.\n        return this.errorValue;\n    };\n    return Trie;\n}());\n\n/*\n * base64-arraybuffer 1.0.2 <https://github.com/niklasvh/base64-arraybuffer>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar chars$3 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup$3 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i$3 = 0; i$3 < chars$3.length; i$3++) {\n    lookup$3[chars$3.charCodeAt(i$3)] = i$3;\n}\n\nvar base64$1 = 'KwAAAAAAAAAACA4AUD0AADAgAAACAAAAAAAIABAAGABAAEgAUABYAGAAaABgAGgAYgBqAF8AZwBgAGgAcQB5AHUAfQCFAI0AlQCdAKIAqgCyALoAYABoAGAAaABgAGgAwgDKAGAAaADGAM4A0wDbAOEA6QDxAPkAAQEJAQ8BFwF1AH0AHAEkASwBNAE6AUIBQQFJAVEBWQFhAWgBcAF4ATAAgAGGAY4BlQGXAZ8BpwGvAbUBvQHFAc0B0wHbAeMB6wHxAfkBAQIJAvEBEQIZAiECKQIxAjgCQAJGAk4CVgJeAmQCbAJ0AnwCgQKJApECmQKgAqgCsAK4ArwCxAIwAMwC0wLbAjAA4wLrAvMC+AIAAwcDDwMwABcDHQMlAy0DNQN1AD0DQQNJA0kDSQNRA1EDVwNZA1kDdQB1AGEDdQBpA20DdQN1AHsDdQCBA4kDkQN1AHUAmQOhA3UAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AKYDrgN1AHUAtgO+A8YDzgPWAxcD3gPjA+sD8wN1AHUA+wMDBAkEdQANBBUEHQQlBCoEFwMyBDgEYABABBcDSARQBFgEYARoBDAAcAQzAXgEgASIBJAEdQCXBHUAnwSnBK4EtgS6BMIEyAR1AHUAdQB1AHUAdQCVANAEYABgAGAAYABgAGAAYABgANgEYADcBOQEYADsBPQE/AQEBQwFFAUcBSQFLAU0BWQEPAVEBUsFUwVbBWAAYgVgAGoFcgV6BYIFigWRBWAAmQWfBaYFYABgAGAAYABgAKoFYACxBbAFuQW6BcEFwQXHBcEFwQXPBdMF2wXjBeoF8gX6BQIGCgYSBhoGIgYqBjIGOgZgAD4GRgZMBmAAUwZaBmAAYABgAGAAYABgAGAAYABgAGAAYABgAGIGYABpBnAGYABgAGAAYABgAGAAYABgAGAAYAB4Bn8GhQZgAGAAYAB1AHcDFQSLBmAAYABgAJMGdQA9A3UAmwajBqsGqwaVALMGuwbDBjAAywbSBtIG1QbSBtIG0gbSBtIG0gbdBuMG6wbzBvsGAwcLBxMHAwcbByMHJwcsBywHMQcsB9IGOAdAB0gHTgfSBkgHVgfSBtIG0gbSBtIG0gbSBtIG0gbSBiwHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAdgAGAALAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAdbB2MHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsB2kH0gZwB64EdQB1AHUAdQB1AHUAdQB1AHUHfQdgAIUHjQd1AHUAlQedB2AAYAClB6sHYACzB7YHvgfGB3UAzgfWBzMB3gfmB1EB7gf1B/0HlQENAQUIDQh1ABUIHQglCBcDLQg1CD0IRQhNCEEDUwh1AHUAdQBbCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIcAh3CHoIMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIgggwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAALAcsBywHLAcsBywHLAcsBywHLAcsB4oILAcsB44I0gaWCJ4Ipgh1AHUAqgiyCHUAdQB1AHUAdQB1AHUAdQB1AHUAtwh8AXUAvwh1AMUIyQjRCNkI4AjoCHUAdQB1AO4I9gj+CAYJDgkTCS0HGwkjCYIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiAAIAAAAFAAYABgAGIAXwBgAHEAdQBFAJUAogCyAKAAYABgAEIA4ABGANMA4QDxAMEBDwE1AFwBLAE6AQEBUQF4QkhCmEKoQrhCgAHIQsAB0MLAAcABwAHAAeDC6ABoAHDCwMMAAcABwAHAAdDDGMMAAcAB6MM4wwjDWMNow3jDaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAEjDqABWw6bDqABpg6gAaABoAHcDvwOPA+gAaABfA/8DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DpcPAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcAB9cPKwkyCToJMAB1AHUAdQBCCUoJTQl1AFUJXAljCWcJawkwADAAMAAwAHMJdQB2CX4JdQCECYoJjgmWCXUAngkwAGAAYABxAHUApgn3A64JtAl1ALkJdQDACTAAMAAwADAAdQB1AHUAdQB1AHUAdQB1AHUAowYNBMUIMAAwADAAMADICcsJ0wnZCRUE4QkwAOkJ8An4CTAAMAB1AAAKvwh1AAgKDwoXCh8KdQAwACcKLgp1ADYKqAmICT4KRgowADAAdQB1AE4KMAB1AFYKdQBeCnUAZQowADAAMAAwADAAMAAwADAAMAAVBHUAbQowADAAdQC5CXUKMAAwAHwBxAijBogEMgF9CoQKiASMCpQKmgqIBKIKqgquCogEDQG2Cr4KxgrLCjAAMADTCtsKCgHjCusK8Qr5CgELMAAwADAAMAB1AIsECQsRC3UANAEZCzAAMAAwADAAMAB1ACELKQswAHUANAExCzkLdQBBC0kLMABRC1kLMAAwADAAMAAwADAAdQBhCzAAMAAwAGAAYABpC3ELdwt/CzAAMACHC4sLkwubC58Lpwt1AK4Ltgt1APsDMAAwADAAMAAwADAAMAAwAL4LwwvLC9IL1wvdCzAAMADlC+kL8Qv5C/8LSQswADAAMAAwADAAMAAwADAAMAAHDDAAMAAwADAAMAAODBYMHgx1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1ACYMMAAwADAAdQB1AHUALgx1AHUAdQB1AHUAdQA2DDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AD4MdQBGDHUAdQB1AHUAdQB1AEkMdQB1AHUAdQB1AFAMMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQBYDHUAdQB1AF8MMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUA+wMVBGcMMAAwAHwBbwx1AHcMfwyHDI8MMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAYABgAJcMMAAwADAAdQB1AJ8MlQClDDAAMACtDCwHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsB7UMLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AA0EMAC9DDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAsBywHLAcsBywHLAcsBywHLQcwAMEMyAwsBywHLAcsBywHLAcsBywHLAcsBywHzAwwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1ANQM2QzhDDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMABgAGAAYABgAGAAYABgAOkMYADxDGAA+AwADQYNYABhCWAAYAAODTAAMAAwADAAFg1gAGAAHg37AzAAMAAwADAAYABgACYNYAAsDTQNPA1gAEMNPg1LDWAAYABgAGAAYABgAGAAYABgAGAAUg1aDYsGVglhDV0NcQBnDW0NdQ15DWAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAlQCBDZUAiA2PDZcNMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAnw2nDTAAMAAwADAAMAAwAHUArw23DTAAMAAwADAAMAAwADAAMAAwADAAMAB1AL8NMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAB1AHUAdQB1AHUAdQDHDTAAYABgAM8NMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAA1w11ANwNMAAwAD0B5A0wADAAMAAwADAAMADsDfQN/A0EDgwOFA4wABsOMAAwADAAMAAwADAAMAAwANIG0gbSBtIG0gbSBtIG0gYjDigOwQUuDsEFMw7SBjoO0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGQg5KDlIOVg7SBtIGXg5lDm0OdQ7SBtIGfQ6EDooOjQ6UDtIGmg6hDtIG0gaoDqwO0ga0DrwO0gZgAGAAYADEDmAAYAAkBtIGzA5gANIOYADaDokO0gbSBt8O5w7SBu8O0gb1DvwO0gZgAGAAxA7SBtIG0gbSBtIGYABgAGAAYAAED2AAsAUMD9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGFA8sBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAccD9IGLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHJA8sBywHLAcsBywHLAccDywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywPLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAc0D9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAccD9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGFA8sBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHPA/SBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gYUD0QPlQCVAJUAMAAwADAAMACVAJUAlQCVAJUAlQCVAEwPMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAA//8EAAQABAAEAAQABAAEAAQABAANAAMAAQABAAIABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQACgATABcAHgAbABoAHgAXABYAEgAeABsAGAAPABgAHABLAEsASwBLAEsASwBLAEsASwBLABgAGAAeAB4AHgATAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABYAGwASAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAWAA0AEQAeAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAFAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJABYAGgAbABsAGwAeAB0AHQAeAE8AFwAeAA0AHgAeABoAGwBPAE8ADgBQAB0AHQAdAE8ATwAXAE8ATwBPABYAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAFAATwBAAE8ATwBPAEAATwBQAFAATwBQAB4AHgAeAB4AHgAeAB0AHQAdAB0AHgAdAB4ADgBQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgBQAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAkACQAJAAkACQAJAAkABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAFAAHgAeAB4AKwArAFAAUABQAFAAGABQACsAKwArACsAHgAeAFAAHgBQAFAAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUAAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAYAA0AKwArAB4AHgAbACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAB4ABAAEAB4ABAAEABMABAArACsAKwArACsAKwArACsAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAKwArACsAKwBWAFYAVgBWAB4AHgArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AGgAaABoAGAAYAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQAEwAEACsAEwATAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABLAEsASwBLAEsASwBLAEsASwBLABoAGQAZAB4AUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABMAUAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABABQAFAABAAEAB4ABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUAAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAFAABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQAUABQAB4AHgAYABMAUAArACsABAAbABsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAFAABAAEAAQABAAEAFAABAAEAAQAUAAEAAQABAAEAAQAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArACsAHgArAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAUAAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEAA0ADQBLAEsASwBLAEsASwBLAEsASwBLAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUAArACsAKwBQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABABQACsAKwArACsAKwArACsAKwAEACsAKwArACsAUABQACsAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUAAaABoAUABQAFAAUABQAEwAHgAbAFAAHgAEACsAKwAEAAQABAArAFAAUABQAFAAUABQACsAKwArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQACsAUABQACsAKwAEACsABAAEAAQABAAEACsAKwArACsABAAEACsAKwAEAAQABAArACsAKwAEACsAKwArACsAKwArACsAUABQAFAAUAArAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLAAQABABQAFAAUAAEAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAArACsAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAB4AGwArACsAKwArACsAKwArAFAABAAEAAQABAAEAAQAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAKwArACsAKwArAAQABAAEACsAKwArACsAUABQACsAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAB4AUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAAQAUAArAFAAUABQAFAAUABQACsAKwArAFAAUABQACsAUABQAFAAUAArACsAKwBQAFAAKwBQACsAUABQACsAKwArAFAAUAArACsAKwBQAFAAUAArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArAAQABAAEAAQABAArACsAKwAEAAQABAArAAQABAAEAAQAKwArAFAAKwArACsAKwArACsABAArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAHgAeAB4AHgAeAB4AGwAeACsAKwArACsAKwAEAAQABAAEAAQAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAUAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAAEACsAKwArACsAKwArACsABAAEACsAUABQAFAAKwArACsAKwArAFAAUAAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwAOAFAAUABQAFAAUABQAFAAHgBQAAQABAAEAA4AUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAKwArAAQAUAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAAEACsAKwArACsAKwArACsABAAEACsAKwArACsAKwArACsAUAArAFAAUAAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwBQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABABQAB4AKwArACsAKwBQAFAAUAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQABoAUABQAFAAUABQAFAAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQACsAUAArACsAUABQAFAAUABQAFAAUAArACsAKwAEACsAKwArACsABAAEAAQABAAEAAQAKwAEACsABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArAAQABAAeACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAXAAqACoAKgAqACoAKgAqACsAKwArACsAGwBcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAeAEsASwBLAEsASwBLAEsASwBLAEsADQANACsAKwArACsAKwBcAFwAKwBcACsAXABcAFwAXABcACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAXAArAFwAXABcAFwAXABcAFwAXABcAFwAKgBcAFwAKgAqACoAKgAqACoAKgAqACoAXAArACsAXABcAFwAXABcACsAXAArACoAKgAqACoAKgAqACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwBcAFwAXABcAFAADgAOAA4ADgAeAA4ADgAJAA4ADgANAAkAEwATABMAEwATAAkAHgATAB4AHgAeAAQABAAeAB4AHgAeAB4AHgBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQAFAADQAEAB4ABAAeAAQAFgARABYAEQAEAAQAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAAQABAAEAAQADQAEAAQAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAA0ADQAeAB4AHgAeAB4AHgAEAB4AHgAeAB4AHgAeACsAHgAeAA4ADgANAA4AHgAeAB4AHgAeAAkACQArACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgBcAEsASwBLAEsASwBLAEsASwBLAEsADQANAB4AHgAeAB4AXABcAFwAXABcAFwAKgAqACoAKgBcAFwAXABcACoAKgAqAFwAKgAqACoAXABcACoAKgAqACoAKgAqACoAXABcAFwAKgAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKgAqAFwAKgBLAEsASwBLAEsASwBLAEsASwBLACoAKgAqACoAKgAqAFAAUABQAFAAUABQACsAUAArACsAKwArACsAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgBQAFAAUABQAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAKwBQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsABAAEAAQAHgANAB4AHgAeAB4AHgAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUAArACsADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAWABEAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAA0ADQANAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAANAA0AKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUAArAAQABAArACsAKwArACsAKwArACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqAA0ADQAVAFwADQAeAA0AGwBcACoAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwAeAB4AEwATAA0ADQAOAB4AEwATAB4ABAAEAAQACQArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUAAEAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAHgArACsAKwATABMASwBLAEsASwBLAEsASwBLAEsASwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAXABcAFwAXABcACsAKwArACsAKwArACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAXAArACsAKwAqACoAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsAHgAeAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKwAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKwArAAQASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACoAKgAqACoAKgAqACoAXAAqACoAKgAqACoAKgArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABABQAFAAUABQAFAAUABQACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwANAA0AHgANAA0ADQANAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQAHgAeAB4AHgAeAB4AHgAeAB4AKwArACsABAAEAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwAeAB4AHgAeAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArAA0ADQANAA0ADQBLAEsASwBLAEsASwBLAEsASwBLACsAKwArAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAA0ADQBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUAAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArAAQABAAEAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAAQAUABQAFAAUABQAFAABABQAFAABAAEAAQAUAArACsAKwArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAKwBQACsAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAFAAUABQACsAHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQACsAKwAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQACsAHgAeAB4AHgAeAB4AHgAOAB4AKwANAA0ADQANAA0ADQANAAkADQANAA0ACAAEAAsABAAEAA0ACQANAA0ADAAdAB0AHgAXABcAFgAXABcAFwAWABcAHQAdAB4AHgAUABQAFAANAAEAAQAEAAQABAAEAAQACQAaABoAGgAaABoAGgAaABoAHgAXABcAHQAVABUAHgAeAB4AHgAeAB4AGAAWABEAFQAVABUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ADQAeAA0ADQANAA0AHgANAA0ADQAHAB4AHgAeAB4AKwAEAAQABAAEAAQABAAEAAQABAAEAFAAUAArACsATwBQAFAAUABQAFAAHgAeAB4AFgARAE8AUABPAE8ATwBPAFAAUABQAFAAUAAeAB4AHgAWABEAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArABsAGwAbABsAGwAbABsAGgAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGgAbABsAGwAbABoAGwAbABoAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAHgAeAFAAGgAeAB0AHgBQAB4AGgAeAB4AHgAeAB4AHgAeAB4AHgBPAB4AUAAbAB4AHgBQAFAAUABQAFAAHgAeAB4AHQAdAB4AUAAeAFAAHgBQAB4AUABPAFAAUAAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAHgBQAFAAUABQAE8ATwBQAFAAUABQAFAATwBQAFAATwBQAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAFAAUABQAFAATwBPAE8ATwBPAE8ATwBPAE8ATwBQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABPAB4AHgArACsAKwArAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHQAdAB4AHgAeAB0AHQAeAB4AHQAeAB4AHgAdAB4AHQAbABsAHgAdAB4AHgAeAB4AHQAeAB4AHQAdAB0AHQAeAB4AHQAeAB0AHgAdAB0AHQAdAB0AHQAeAB0AHgAeAB4AHgAeAB0AHQAdAB0AHgAeAB4AHgAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeAB0AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAeAB0AHQAdAB0AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAWABEAHgAeAB4AHgAeAB4AHQAeAB4AHgAeAB4AHgAeACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAWABEAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAFAAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeAB4AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AHQAdAB0AHgAeAB0AHgAeAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlAB4AHQAdAB4AHgAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AJQAlAB0AHQAlAB4AJQAlACUAIAAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAeAB4AHgAeAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAdAB0AHQAeAB0AJQAdAB0AHgAdAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAdAB0AHQAdACUAHgAlACUAJQAdACUAJQAdAB0AHQAlACUAHQAdACUAHQAdACUAJQAlAB4AHQAeAB4AHgAeAB0AHQAlAB0AHQAdAB0AHQAdACUAJQAlACUAJQAdACUAJQAgACUAHQAdACUAJQAlACUAJQAlACUAJQAeAB4AHgAlACUAIAAgACAAIAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AFwAXABcAFwAXABcAHgATABMAJQAeAB4AHgAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARABYAEQAWABEAFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAEAAQABAAeAB4AKwArACsAKwArABMADQANAA0AUAATAA0AUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUAANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAA0ADQANAA0ADQANAA0ADQAeAA0AFgANAB4AHgAXABcAHgAeABcAFwAWABEAFgARABYAEQAWABEADQANAA0ADQATAFAADQANAB4ADQANAB4AHgAeAB4AHgAMAAwADQANAA0AHgANAA0AFgANAA0ADQANAA0ADQANAA0AHgANAB4ADQANAB4AHgAeACsAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArAA0AEQARACUAJQBHAFcAVwAWABEAFgARABYAEQAWABEAFgARACUAJQAWABEAFgARABYAEQAWABEAFQAWABEAEQAlAFcAVwBXAFcAVwBXAFcAVwBXAAQABAAEAAQABAAEACUAVwBXAFcAVwA2ACUAJQBXAFcAVwBHAEcAJQAlACUAKwBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBRAFcAUQBXAFEAVwBXAFcAVwBXAFcAUQBXAFcAVwBXAFcAVwBRAFEAKwArAAQABAAVABUARwBHAFcAFQBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBRAFcAVwBXAFcAVwBXAFEAUQBXAFcAVwBXABUAUQBHAEcAVwArACsAKwArACsAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwAlACUAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACsAKwArACsAKwArACsAKwArACsAKwArAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBPAE8ATwBPAE8ATwBPAE8AJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADQATAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABLAEsASwBLAEsASwBLAEsASwBLAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAABAAEAAQABAAeAAQABAAEAAQABAAEAAQABAAEAAQAHgBQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAeAA0ADQANAA0ADQArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAAQAUABQAFAABABQAFAAUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAeAB4AHgAeAAQAKwArACsAUABQAFAAUABQAFAAHgAeABoAHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADgAOABMAEwArACsAKwArACsAKwArACsABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwANAA0ASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUAAeAB4AHgBQAA4AUABQAAQAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArAB4AWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYACsAKwArAAQAHgAeAB4AHgAeAB4ADQANAA0AHgAeAB4AHgArAFAASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArAB4AHgBcAFwAXABcAFwAKgBcAFwAXABcAFwAXABcAFwAXABcAEsASwBLAEsASwBLAEsASwBLAEsAXABcAFwAXABcACsAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAFAAUABQAAQAUABQAFAAUABQAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAHgANAA0ADQBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAXAAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAKgAqACoAXABcACoAKgBcAFwAXABcAFwAKgAqAFwAKgBcACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcACoAKgBQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAA0ADQBQAFAAUAAEAAQAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQADQAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAVABVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBUAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVACsAKwArACsAKwArACsAKwArACsAKwArAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAKwArACsAKwBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAKwArACsAKwAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAKwArACsAKwArAFYABABWAFYAVgBWAFYAVgBWAFYAVgBWAB4AVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgArAFYAVgBWAFYAVgArAFYAKwBWAFYAKwBWAFYAKwBWAFYAVgBWAFYAVgBWAFYAVgBWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAEQAWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAaAB4AKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAGAARABEAGAAYABMAEwAWABEAFAArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACUAJQAlACUAJQAWABEAFgARABYAEQAWABEAFgARABYAEQAlACUAFgARACUAJQAlACUAJQAlACUAEQAlABEAKwAVABUAEwATACUAFgARABYAEQAWABEAJQAlACUAJQAlACUAJQAlACsAJQAbABoAJQArACsAKwArAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAcAKwATACUAJQAbABoAJQAlABYAEQAlACUAEQAlABEAJQBXAFcAVwBXAFcAVwBXAFcAVwBXABUAFQAlACUAJQATACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXABYAJQARACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAWACUAEQAlABYAEQARABYAEQARABUAVwBRAFEAUQBRAFEAUQBRAFEAUQBRAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcARwArACsAVwBXAFcAVwBXAFcAKwArAFcAVwBXAFcAVwBXACsAKwBXAFcAVwBXAFcAVwArACsAVwBXAFcAKwArACsAGgAbACUAJQAlABsAGwArAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAAQAB0AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsADQANAA0AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAAQAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAA0AUABQAFAAUAArACsAKwArAFAAUABQAFAAUABQAFAAUAANAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAKwArAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArACsAKwBQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAUABQAFAAUABQAAQABAAEACsABAAEACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAKwBQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAA0ADQANAA0ADQANAA0ADQAeACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAArACsAKwArAFAAUABQAFAAUAANAA0ADQANAA0ADQAUACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsADQANAA0ADQANAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAAQABAAEAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArAAQABAANACsAKwBQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAB4AHgAeAB4AHgArACsAKwArACsAKwAEAAQABAAEAAQABAAEAA0ADQAeAB4AHgAeAB4AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwAeACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsASwBLAEsASwBLAEsASwBLAEsASwANAA0ADQANAFAABAAEAFAAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAeAA4AUAArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAADQANAB4ADQAEAAQABAAEAB4ABAAEAEsASwBLAEsASwBLAEsASwBLAEsAUAAOAFAADQANAA0AKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAANAA0AHgANAA0AHgAEACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAA0AKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsABAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQACsABAAEAFAABAAEAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAUAArACsAKwArACsAKwAEACsAKwArACsAKwBQAFAAUABQAFAABAAEACsAKwAEAAQABAAEAAQABAAEACsAKwArAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABABQAFAAUABQAA0ADQANAA0AHgBLAEsASwBLAEsASwBLAEsASwBLAA0ADQArAB4ABABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAFAAUAAeAFAAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABAAEAAQADgANAA0AEwATAB4AHgAeAA0ADQANAA0ADQANAA0ADQANAA0ADQANAA0ADQANAFAAUABQAFAABAAEACsAKwAEAA0ADQAeAFAAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKwArACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBcAFwADQANAA0AKgBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAKwArAFAAKwArAFAAUABQAFAAUABQAFAAUAArAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQAKwAEAAQAKwArAAQABAAEAAQAUAAEAFAABAAEAA0ADQANACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABABQAA4AUAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAFAABAAEAAQABAAOAB4ADQANAA0ADQAOAB4ABAArACsAKwArACsAKwArACsAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAA0ADQANAFAADgAOAA4ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAAQABAAEAFAADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAOABMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAArACsAKwAEACsABAAEACsABAAEAAQABAAEAAQABABQAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAKwAEAAQAKwAEAAQABAAEAAQAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAaABoAGgAaAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABIAEgAQwBDAEMAUABQAFAAUABDAFAAUABQAEgAQwBIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABDAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAJAAkACQAJAAkACQAJABYAEQArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwANAA0AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAANACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAA0ADQANAB4AHgAeAB4AHgAeAFAAUABQAFAADQAeACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAA0AHgAeACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAARwBHABUARwAJACsAKwArACsAKwArACsAKwArACsAKwAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUQBRAFEAKwArACsAKwArACsAKwArACsAKwArACsAKwBRAFEAUQBRACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArACsAHgAEAAQADQAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAAQABAAEAAQABAAeAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQAHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQAFAAKwArAFAAKwArAFAAUAArACsAUABQAFAAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUAArAFAAUABQAFAAUABQAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAHgAeAFAAUABQAFAAUAArAFAAKwArACsAUABQAFAAUABQAFAAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeACsAKwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4ABAAeAB4AHgAeAB4AHgAeAB4AHgAeAAQAHgAeAA0ADQANAA0AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAAQAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArAAQABAAEAAQABAAEAAQAKwAEAAQAKwAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwBQAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArABsAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAB4AHgAeAB4ABAAEAAQABAAEAAQABABQACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArABYAFgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAGgBQAFAAUAAaAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQACsAKwBQACsAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwBQACsAUAArACsAKwArACsAKwBQACsAKwArACsAUAArAFAAKwBQACsAUABQAFAAKwBQAFAAKwBQACsAKwBQACsAUAArAFAAKwBQACsAUAArAFAAUAArAFAAKwArAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUAArAFAAUABQAFAAKwBQACsAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAKwBQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8AJQAlACUAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB4AHgAeACUAJQAlAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAlACUAJQAlACUAHgAlACUAJQAlACUAIAAgACAAJQAlACAAJQAlACAAIAAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACEAIQAhACEAIQAlACUAIAAgACUAJQAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAIAAlACUAJQAlACAAIAAgACUAIAAgACAAJQAlACUAJQAlACUAJQAgACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAlAB4AJQAeACUAJQAlACUAJQAgACUAJQAlACUAHgAlAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACAAIAAgACUAJQAlACAAIAAgACAAIAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABcAFwAXABUAFQAVAB4AHgAeAB4AJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAgACUAJQAgACUAJQAlACUAJQAlACUAJQAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAgACAAIAAgACAAIAAgACAAIAAgACUAJQAgACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAlACAAIAAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAgACAAIAAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAA==';\n\nvar LETTER_NUMBER_MODIFIER = 50;\n// Non-tailorable Line Breaking Classes\nvar BK = 1; //  Cause a line break (after)\nvar CR$1 = 2; //  Cause a line break (after), except between CR and LF\nvar LF$1 = 3; //  Cause a line break (after)\nvar CM = 4; //  Prohibit a line break between the character and the preceding character\nvar NL = 5; //  Cause a line break (after)\nvar WJ = 7; //  Prohibit line breaks before and after\nvar ZW = 8; //  Provide a break opportunity\nvar GL = 9; //  Prohibit line breaks before and after\nvar SP = 10; // Enable indirect line breaks\nvar ZWJ$1 = 11; // Prohibit line breaks within joiner sequences\n// Break Opportunities\nvar B2 = 12; //  Provide a line break opportunity before and after the character\nvar BA = 13; //  Generally provide a line break opportunity after the character\nvar BB = 14; //  Generally provide a line break opportunity before the character\nvar HY = 15; //  Provide a line break opportunity after the character, except in numeric context\nvar CB = 16; //   Provide a line break opportunity contingent on additional information\n// Characters Prohibiting Certain Breaks\nvar CL = 17; //  Prohibit line breaks before\nvar CP = 18; //  Prohibit line breaks before\nvar EX = 19; //  Prohibit line breaks before\nvar IN = 20; //  Allow only indirect line breaks between pairs\nvar NS = 21; //  Allow only indirect line breaks before\nvar OP = 22; //  Prohibit line breaks after\nvar QU = 23; //  Act like they are both opening and closing\n// Numeric Context\nvar IS = 24; //  Prevent breaks after any and before numeric\nvar NU = 25; //  Form numeric expressions for line breaking purposes\nvar PO = 26; //  Do not break following a numeric expression\nvar PR = 27; //  Do not break in front of a numeric expression\nvar SY = 28; //  Prevent a break before; and allow a break after\n// Other Characters\nvar AI = 29; //  Act like AL when the resolvedEAW is N; otherwise; act as ID\nvar AL = 30; //  Are alphabetic characters or symbols that are used with alphabetic characters\nvar CJ = 31; //  Treat as NS or ID for strict or normal breaking.\nvar EB = 32; //  Do not break from following Emoji Modifier\nvar EM = 33; //  Do not break from preceding Emoji Base\nvar H2 = 34; //  Form Korean syllable blocks\nvar H3 = 35; //  Form Korean syllable blocks\nvar HL = 36; //  Do not break around a following hyphen; otherwise act as Alphabetic\nvar ID = 37; //  Break before or after; except in some numeric context\nvar JL = 38; //  Form Korean syllable blocks\nvar JV = 39; //  Form Korean syllable blocks\nvar JT = 40; //  Form Korean syllable blocks\nvar RI$1 = 41; //  Keep pairs together. For pairs; break before and after other classes\nvar SA = 42; //  Provide a line break opportunity contingent on additional, language-specific context analysis\nvar XX = 43; //  Have as yet unknown line breaking behavior or unassigned code positions\nvar ea_OP = [0x2329, 0xff08];\nvar BREAK_MANDATORY = '!';\nvar BREAK_NOT_ALLOWED$1 = '×';\nvar BREAK_ALLOWED$1 = '÷';\nvar UnicodeTrie$1 = createTrieFromBase64$1(base64$1);\nvar ALPHABETICS = [AL, HL];\nvar HARD_LINE_BREAKS = [BK, CR$1, LF$1, NL];\nvar SPACE$1 = [SP, ZW];\nvar PREFIX_POSTFIX = [PR, PO];\nvar LINE_BREAKS = HARD_LINE_BREAKS.concat(SPACE$1);\nvar KOREAN_SYLLABLE_BLOCK = [JL, JV, JT, H2, H3];\nvar HYPHEN = [HY, BA];\nvar codePointsToCharacterClasses = function (codePoints, lineBreak) {\n    if (lineBreak === void 0) { lineBreak = 'strict'; }\n    var types = [];\n    var indices = [];\n    var categories = [];\n    codePoints.forEach(function (codePoint, index) {\n        var classType = UnicodeTrie$1.get(codePoint);\n        if (classType > LETTER_NUMBER_MODIFIER) {\n            categories.push(true);\n            classType -= LETTER_NUMBER_MODIFIER;\n        }\n        else {\n            categories.push(false);\n        }\n        if (['normal', 'auto', 'loose'].indexOf(lineBreak) !== -1) {\n            // U+2010, – U+2013, 〜 U+301C, ゠ U+30A0\n            if ([0x2010, 0x2013, 0x301c, 0x30a0].indexOf(codePoint) !== -1) {\n                indices.push(index);\n                return types.push(CB);\n            }\n        }\n        if (classType === CM || classType === ZWJ$1) {\n            // LB10 Treat any remaining combining mark or ZWJ as AL.\n            if (index === 0) {\n                indices.push(index);\n                return types.push(AL);\n            }\n            // LB9 Do not break a combining character sequence; treat it as if it has the line breaking class of\n            // the base character in all of the following rules. Treat ZWJ as if it were CM.\n            var prev = types[index - 1];\n            if (LINE_BREAKS.indexOf(prev) === -1) {\n                indices.push(indices[index - 1]);\n                return types.push(prev);\n            }\n            indices.push(index);\n            return types.push(AL);\n        }\n        indices.push(index);\n        if (classType === CJ) {\n            return types.push(lineBreak === 'strict' ? NS : ID);\n        }\n        if (classType === SA) {\n            return types.push(AL);\n        }\n        if (classType === AI) {\n            return types.push(AL);\n        }\n        // For supplementary characters, a useful default is to treat characters in the range 10000..1FFFD as AL\n        // and characters in the ranges 20000..2FFFD and 30000..3FFFD as ID, until the implementation can be revised\n        // to take into account the actual line breaking properties for these characters.\n        if (classType === XX) {\n            if ((codePoint >= 0x20000 && codePoint <= 0x2fffd) || (codePoint >= 0x30000 && codePoint <= 0x3fffd)) {\n                return types.push(ID);\n            }\n            else {\n                return types.push(AL);\n            }\n        }\n        types.push(classType);\n    });\n    return [indices, types, categories];\n};\nvar isAdjacentWithSpaceIgnored = function (a, b, currentIndex, classTypes) {\n    var current = classTypes[currentIndex];\n    if (Array.isArray(a) ? a.indexOf(current) !== -1 : a === current) {\n        var i = currentIndex;\n        while (i <= classTypes.length) {\n            i++;\n            var next = classTypes[i];\n            if (next === b) {\n                return true;\n            }\n            if (next !== SP) {\n                break;\n            }\n        }\n    }\n    if (current === SP) {\n        var i = currentIndex;\n        while (i > 0) {\n            i--;\n            var prev = classTypes[i];\n            if (Array.isArray(a) ? a.indexOf(prev) !== -1 : a === prev) {\n                var n = currentIndex;\n                while (n <= classTypes.length) {\n                    n++;\n                    var next = classTypes[n];\n                    if (next === b) {\n                        return true;\n                    }\n                    if (next !== SP) {\n                        break;\n                    }\n                }\n            }\n            if (prev !== SP) {\n                break;\n            }\n        }\n    }\n    return false;\n};\nvar previousNonSpaceClassType = function (currentIndex, classTypes) {\n    var i = currentIndex;\n    while (i >= 0) {\n        var type = classTypes[i];\n        if (type === SP) {\n            i--;\n        }\n        else {\n            return type;\n        }\n    }\n    return 0;\n};\nvar _lineBreakAtIndex = function (codePoints, classTypes, indicies, index, forbiddenBreaks) {\n    if (indicies[index] === 0) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    var currentIndex = index - 1;\n    if (Array.isArray(forbiddenBreaks) && forbiddenBreaks[currentIndex] === true) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    var beforeIndex = currentIndex - 1;\n    var afterIndex = currentIndex + 1;\n    var current = classTypes[currentIndex];\n    // LB4 Always break after hard line breaks.\n    // LB5 Treat CR followed by LF, as well as CR, LF, and NL as hard line breaks.\n    var before = beforeIndex >= 0 ? classTypes[beforeIndex] : 0;\n    var next = classTypes[afterIndex];\n    if (current === CR$1 && next === LF$1) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    if (HARD_LINE_BREAKS.indexOf(current) !== -1) {\n        return BREAK_MANDATORY;\n    }\n    // LB6 Do not break before hard line breaks.\n    if (HARD_LINE_BREAKS.indexOf(next) !== -1) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB7 Do not break before spaces or zero width space.\n    if (SPACE$1.indexOf(next) !== -1) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB8 Break before any character following a zero-width space, even if one or more spaces intervene.\n    if (previousNonSpaceClassType(currentIndex, classTypes) === ZW) {\n        return BREAK_ALLOWED$1;\n    }\n    // LB8a Do not break after a zero width joiner.\n    if (UnicodeTrie$1.get(codePoints[currentIndex]) === ZWJ$1) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // zwj emojis\n    if ((current === EB || current === EM) && UnicodeTrie$1.get(codePoints[afterIndex]) === ZWJ$1) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB11 Do not break before or after Word joiner and related characters.\n    if (current === WJ || next === WJ) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB12 Do not break after NBSP and related characters.\n    if (current === GL) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB12a Do not break before NBSP and related characters, except after spaces and hyphens.\n    if ([SP, BA, HY].indexOf(current) === -1 && next === GL) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB13 Do not break before ‘]’ or ‘!’ or ‘;’ or ‘/’, even after spaces.\n    if ([CL, CP, EX, IS, SY].indexOf(next) !== -1) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB14 Do not break after ‘[’, even after spaces.\n    if (previousNonSpaceClassType(currentIndex, classTypes) === OP) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB15 Do not break within ‘”[’, even with intervening spaces.\n    if (isAdjacentWithSpaceIgnored(QU, OP, currentIndex, classTypes)) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB16 Do not break between closing punctuation and a nonstarter (lb=NS), even with intervening spaces.\n    if (isAdjacentWithSpaceIgnored([CL, CP], NS, currentIndex, classTypes)) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB17 Do not break within ‘——’, even with intervening spaces.\n    if (isAdjacentWithSpaceIgnored(B2, B2, currentIndex, classTypes)) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB18 Break after spaces.\n    if (current === SP) {\n        return BREAK_ALLOWED$1;\n    }\n    // LB19 Do not break before or after quotation marks, such as ‘ ” ’.\n    if (current === QU || next === QU) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB20 Break before and after unresolved CB.\n    if (next === CB || current === CB) {\n        return BREAK_ALLOWED$1;\n    }\n    // LB21 Do not break before hyphen-minus, other hyphens, fixed-width spaces, small kana, and other non-starters, or after acute accents.\n    if ([BA, HY, NS].indexOf(next) !== -1 || current === BB) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB21a Don't break after Hebrew + Hyphen.\n    if (before === HL && HYPHEN.indexOf(current) !== -1) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB21b Don’t break between Solidus and Hebrew letters.\n    if (current === SY && next === HL) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB22 Do not break before ellipsis.\n    if (next === IN) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB23 Do not break between digits and letters.\n    if ((ALPHABETICS.indexOf(next) !== -1 && current === NU) || (ALPHABETICS.indexOf(current) !== -1 && next === NU)) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB23a Do not break between numeric prefixes and ideographs, or between ideographs and numeric postfixes.\n    if ((current === PR && [ID, EB, EM].indexOf(next) !== -1) ||\n        ([ID, EB, EM].indexOf(current) !== -1 && next === PO)) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB24 Do not break between numeric prefix/postfix and letters, or between letters and prefix/postfix.\n    if ((ALPHABETICS.indexOf(current) !== -1 && PREFIX_POSTFIX.indexOf(next) !== -1) ||\n        (PREFIX_POSTFIX.indexOf(current) !== -1 && ALPHABETICS.indexOf(next) !== -1)) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB25 Do not break between the following pairs of classes relevant to numbers:\n    if (\n    // (PR | PO) × ( OP | HY )? NU\n    ([PR, PO].indexOf(current) !== -1 &&\n        (next === NU || ([OP, HY].indexOf(next) !== -1 && classTypes[afterIndex + 1] === NU))) ||\n        // ( OP | HY ) × NU\n        ([OP, HY].indexOf(current) !== -1 && next === NU) ||\n        // NU ×\t(NU | SY | IS)\n        (current === NU && [NU, SY, IS].indexOf(next) !== -1)) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // NU (NU | SY | IS)* × (NU | SY | IS | CL | CP)\n    if ([NU, SY, IS, CL, CP].indexOf(next) !== -1) {\n        var prevIndex = currentIndex;\n        while (prevIndex >= 0) {\n            var type = classTypes[prevIndex];\n            if (type === NU) {\n                return BREAK_NOT_ALLOWED$1;\n            }\n            else if ([SY, IS].indexOf(type) !== -1) {\n                prevIndex--;\n            }\n            else {\n                break;\n            }\n        }\n    }\n    // NU (NU | SY | IS)* (CL | CP)? × (PO | PR))\n    if ([PR, PO].indexOf(next) !== -1) {\n        var prevIndex = [CL, CP].indexOf(current) !== -1 ? beforeIndex : currentIndex;\n        while (prevIndex >= 0) {\n            var type = classTypes[prevIndex];\n            if (type === NU) {\n                return BREAK_NOT_ALLOWED$1;\n            }\n            else if ([SY, IS].indexOf(type) !== -1) {\n                prevIndex--;\n            }\n            else {\n                break;\n            }\n        }\n    }\n    // LB26 Do not break a Korean syllable.\n    if ((JL === current && [JL, JV, H2, H3].indexOf(next) !== -1) ||\n        ([JV, H2].indexOf(current) !== -1 && [JV, JT].indexOf(next) !== -1) ||\n        ([JT, H3].indexOf(current) !== -1 && next === JT)) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB27 Treat a Korean Syllable Block the same as ID.\n    if ((KOREAN_SYLLABLE_BLOCK.indexOf(current) !== -1 && [IN, PO].indexOf(next) !== -1) ||\n        (KOREAN_SYLLABLE_BLOCK.indexOf(next) !== -1 && current === PR)) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB28 Do not break between alphabetics (“at”).\n    if (ALPHABETICS.indexOf(current) !== -1 && ALPHABETICS.indexOf(next) !== -1) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB29 Do not break between numeric punctuation and alphabetics (“e.g.”).\n    if (current === IS && ALPHABETICS.indexOf(next) !== -1) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB30 Do not break between letters, numbers, or ordinary symbols and opening or closing parentheses.\n    if ((ALPHABETICS.concat(NU).indexOf(current) !== -1 &&\n        next === OP &&\n        ea_OP.indexOf(codePoints[afterIndex]) === -1) ||\n        (ALPHABETICS.concat(NU).indexOf(next) !== -1 && current === CP)) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    // LB30a Break between two regional indicator symbols if and only if there are an even number of regional\n    // indicators preceding the position of the break.\n    if (current === RI$1 && next === RI$1) {\n        var i = indicies[currentIndex];\n        var count = 1;\n        while (i > 0) {\n            i--;\n            if (classTypes[i] === RI$1) {\n                count++;\n            }\n            else {\n                break;\n            }\n        }\n        if (count % 2 !== 0) {\n            return BREAK_NOT_ALLOWED$1;\n        }\n    }\n    // LB30b Do not break between an emoji base and an emoji modifier.\n    if (current === EB && next === EM) {\n        return BREAK_NOT_ALLOWED$1;\n    }\n    return BREAK_ALLOWED$1;\n};\nvar cssFormattedClasses = function (codePoints, options) {\n    if (!options) {\n        options = { lineBreak: 'normal', wordBreak: 'normal' };\n    }\n    var _a = codePointsToCharacterClasses(codePoints, options.lineBreak), indicies = _a[0], classTypes = _a[1], isLetterNumber = _a[2];\n    if (options.wordBreak === 'break-all' || options.wordBreak === 'break-word') {\n        classTypes = classTypes.map(function (type) { return ([NU, AL, SA].indexOf(type) !== -1 ? ID : type); });\n    }\n    var forbiddenBreakpoints = options.wordBreak === 'keep-all'\n        ? isLetterNumber.map(function (letterNumber, i) {\n            return letterNumber && codePoints[i] >= 0x4e00 && codePoints[i] <= 0x9fff;\n        })\n        : undefined;\n    return [indicies, classTypes, forbiddenBreakpoints];\n};\nvar Break = /** @class */ (function () {\n    function Break(codePoints, lineBreak, start, end) {\n        this.codePoints = codePoints;\n        this.required = lineBreak === BREAK_MANDATORY;\n        this.start = start;\n        this.end = end;\n    }\n    Break.prototype.slice = function () {\n        return fromCodePoint$1.apply(void 0, this.codePoints.slice(this.start, this.end));\n    };\n    return Break;\n}());\nvar LineBreaker = function (str, options) {\n    var codePoints = toCodePoints$1(str);\n    var _a = cssFormattedClasses(codePoints, options), indicies = _a[0], classTypes = _a[1], forbiddenBreakpoints = _a[2];\n    var length = codePoints.length;\n    var lastEnd = 0;\n    var nextIndex = 0;\n    return {\n        next: function () {\n            if (nextIndex >= length) {\n                return { done: true, value: null };\n            }\n            var lineBreak = BREAK_NOT_ALLOWED$1;\n            while (nextIndex < length &&\n                (lineBreak = _lineBreakAtIndex(codePoints, classTypes, indicies, ++nextIndex, forbiddenBreakpoints)) ===\n                    BREAK_NOT_ALLOWED$1) { }\n            if (lineBreak !== BREAK_NOT_ALLOWED$1 || nextIndex === length) {\n                var value = new Break(codePoints, lineBreak, lastEnd, nextIndex);\n                lastEnd = nextIndex;\n                return { value: value, done: false };\n            }\n            return { done: true, value: null };\n        },\n    };\n};\n\n// https://www.w3.org/TR/css-syntax-3\nvar FLAG_UNRESTRICTED = 1 << 0;\nvar FLAG_ID = 1 << 1;\nvar FLAG_INTEGER = 1 << 2;\nvar FLAG_NUMBER = 1 << 3;\nvar LINE_FEED = 0x000a;\nvar SOLIDUS = 0x002f;\nvar REVERSE_SOLIDUS = 0x005c;\nvar CHARACTER_TABULATION = 0x0009;\nvar SPACE = 0x0020;\nvar QUOTATION_MARK = 0x0022;\nvar EQUALS_SIGN = 0x003d;\nvar NUMBER_SIGN = 0x0023;\nvar DOLLAR_SIGN = 0x0024;\nvar PERCENTAGE_SIGN = 0x0025;\nvar APOSTROPHE = 0x0027;\nvar LEFT_PARENTHESIS = 0x0028;\nvar RIGHT_PARENTHESIS = 0x0029;\nvar LOW_LINE = 0x005f;\nvar HYPHEN_MINUS = 0x002d;\nvar EXCLAMATION_MARK = 0x0021;\nvar LESS_THAN_SIGN = 0x003c;\nvar GREATER_THAN_SIGN = 0x003e;\nvar COMMERCIAL_AT = 0x0040;\nvar LEFT_SQUARE_BRACKET = 0x005b;\nvar RIGHT_SQUARE_BRACKET = 0x005d;\nvar CIRCUMFLEX_ACCENT = 0x003d;\nvar LEFT_CURLY_BRACKET = 0x007b;\nvar QUESTION_MARK = 0x003f;\nvar RIGHT_CURLY_BRACKET = 0x007d;\nvar VERTICAL_LINE = 0x007c;\nvar TILDE = 0x007e;\nvar CONTROL = 0x0080;\nvar REPLACEMENT_CHARACTER = 0xfffd;\nvar ASTERISK = 0x002a;\nvar PLUS_SIGN = 0x002b;\nvar COMMA = 0x002c;\nvar COLON = 0x003a;\nvar SEMICOLON = 0x003b;\nvar FULL_STOP = 0x002e;\nvar NULL = 0x0000;\nvar BACKSPACE = 0x0008;\nvar LINE_TABULATION = 0x000b;\nvar SHIFT_OUT = 0x000e;\nvar INFORMATION_SEPARATOR_ONE = 0x001f;\nvar DELETE = 0x007f;\nvar EOF = -1;\nvar ZERO = 0x0030;\nvar a = 0x0061;\nvar e = 0x0065;\nvar f = 0x0066;\nvar u = 0x0075;\nvar z = 0x007a;\nvar A = 0x0041;\nvar E = 0x0045;\nvar F = 0x0046;\nvar U = 0x0055;\nvar Z = 0x005a;\nvar isDigit = function (codePoint) { return codePoint >= ZERO && codePoint <= 0x0039; };\nvar isSurrogateCodePoint = function (codePoint) { return codePoint >= 0xd800 && codePoint <= 0xdfff; };\nvar isHex = function (codePoint) {\n    return isDigit(codePoint) || (codePoint >= A && codePoint <= F) || (codePoint >= a && codePoint <= f);\n};\nvar isLowerCaseLetter = function (codePoint) { return codePoint >= a && codePoint <= z; };\nvar isUpperCaseLetter = function (codePoint) { return codePoint >= A && codePoint <= Z; };\nvar isLetter = function (codePoint) { return isLowerCaseLetter(codePoint) || isUpperCaseLetter(codePoint); };\nvar isNonASCIICodePoint = function (codePoint) { return codePoint >= CONTROL; };\nvar isWhiteSpace = function (codePoint) {\n    return codePoint === LINE_FEED || codePoint === CHARACTER_TABULATION || codePoint === SPACE;\n};\nvar isNameStartCodePoint = function (codePoint) {\n    return isLetter(codePoint) || isNonASCIICodePoint(codePoint) || codePoint === LOW_LINE;\n};\nvar isNameCodePoint = function (codePoint) {\n    return isNameStartCodePoint(codePoint) || isDigit(codePoint) || codePoint === HYPHEN_MINUS;\n};\nvar isNonPrintableCodePoint = function (codePoint) {\n    return ((codePoint >= NULL && codePoint <= BACKSPACE) ||\n        codePoint === LINE_TABULATION ||\n        (codePoint >= SHIFT_OUT && codePoint <= INFORMATION_SEPARATOR_ONE) ||\n        codePoint === DELETE);\n};\nvar isValidEscape = function (c1, c2) {\n    if (c1 !== REVERSE_SOLIDUS) {\n        return false;\n    }\n    return c2 !== LINE_FEED;\n};\nvar isIdentifierStart = function (c1, c2, c3) {\n    if (c1 === HYPHEN_MINUS) {\n        return isNameStartCodePoint(c2) || isValidEscape(c2, c3);\n    }\n    else if (isNameStartCodePoint(c1)) {\n        return true;\n    }\n    else if (c1 === REVERSE_SOLIDUS && isValidEscape(c1, c2)) {\n        return true;\n    }\n    return false;\n};\nvar isNumberStart = function (c1, c2, c3) {\n    if (c1 === PLUS_SIGN || c1 === HYPHEN_MINUS) {\n        if (isDigit(c2)) {\n            return true;\n        }\n        return c2 === FULL_STOP && isDigit(c3);\n    }\n    if (c1 === FULL_STOP) {\n        return isDigit(c2);\n    }\n    return isDigit(c1);\n};\nvar stringToNumber = function (codePoints) {\n    var c = 0;\n    var sign = 1;\n    if (codePoints[c] === PLUS_SIGN || codePoints[c] === HYPHEN_MINUS) {\n        if (codePoints[c] === HYPHEN_MINUS) {\n            sign = -1;\n        }\n        c++;\n    }\n    var integers = [];\n    while (isDigit(codePoints[c])) {\n        integers.push(codePoints[c++]);\n    }\n    var int = integers.length ? parseInt(fromCodePoint$1.apply(void 0, integers), 10) : 0;\n    if (codePoints[c] === FULL_STOP) {\n        c++;\n    }\n    var fraction = [];\n    while (isDigit(codePoints[c])) {\n        fraction.push(codePoints[c++]);\n    }\n    var fracd = fraction.length;\n    var frac = fracd ? parseInt(fromCodePoint$1.apply(void 0, fraction), 10) : 0;\n    if (codePoints[c] === E || codePoints[c] === e) {\n        c++;\n    }\n    var expsign = 1;\n    if (codePoints[c] === PLUS_SIGN || codePoints[c] === HYPHEN_MINUS) {\n        if (codePoints[c] === HYPHEN_MINUS) {\n            expsign = -1;\n        }\n        c++;\n    }\n    var exponent = [];\n    while (isDigit(codePoints[c])) {\n        exponent.push(codePoints[c++]);\n    }\n    var exp = exponent.length ? parseInt(fromCodePoint$1.apply(void 0, exponent), 10) : 0;\n    return sign * (int + frac * Math.pow(10, -fracd)) * Math.pow(10, expsign * exp);\n};\nvar LEFT_PARENTHESIS_TOKEN = {\n    type: 2 /* LEFT_PARENTHESIS_TOKEN */\n};\nvar RIGHT_PARENTHESIS_TOKEN = {\n    type: 3 /* RIGHT_PARENTHESIS_TOKEN */\n};\nvar COMMA_TOKEN = { type: 4 /* COMMA_TOKEN */ };\nvar SUFFIX_MATCH_TOKEN = { type: 13 /* SUFFIX_MATCH_TOKEN */ };\nvar PREFIX_MATCH_TOKEN = { type: 8 /* PREFIX_MATCH_TOKEN */ };\nvar COLUMN_TOKEN = { type: 21 /* COLUMN_TOKEN */ };\nvar DASH_MATCH_TOKEN = { type: 9 /* DASH_MATCH_TOKEN */ };\nvar INCLUDE_MATCH_TOKEN = { type: 10 /* INCLUDE_MATCH_TOKEN */ };\nvar LEFT_CURLY_BRACKET_TOKEN = {\n    type: 11 /* LEFT_CURLY_BRACKET_TOKEN */\n};\nvar RIGHT_CURLY_BRACKET_TOKEN = {\n    type: 12 /* RIGHT_CURLY_BRACKET_TOKEN */\n};\nvar SUBSTRING_MATCH_TOKEN = { type: 14 /* SUBSTRING_MATCH_TOKEN */ };\nvar BAD_URL_TOKEN = { type: 23 /* BAD_URL_TOKEN */ };\nvar BAD_STRING_TOKEN = { type: 1 /* BAD_STRING_TOKEN */ };\nvar CDO_TOKEN = { type: 25 /* CDO_TOKEN */ };\nvar CDC_TOKEN = { type: 24 /* CDC_TOKEN */ };\nvar COLON_TOKEN = { type: 26 /* COLON_TOKEN */ };\nvar SEMICOLON_TOKEN = { type: 27 /* SEMICOLON_TOKEN */ };\nvar LEFT_SQUARE_BRACKET_TOKEN = {\n    type: 28 /* LEFT_SQUARE_BRACKET_TOKEN */\n};\nvar RIGHT_SQUARE_BRACKET_TOKEN = {\n    type: 29 /* RIGHT_SQUARE_BRACKET_TOKEN */\n};\nvar WHITESPACE_TOKEN = { type: 31 /* WHITESPACE_TOKEN */ };\nvar EOF_TOKEN = { type: 32 /* EOF_TOKEN */ };\nvar Tokenizer = /** @class */ (function () {\n    function Tokenizer() {\n        this._value = [];\n    }\n    Tokenizer.prototype.write = function (chunk) {\n        this._value = this._value.concat(toCodePoints$1(chunk));\n    };\n    Tokenizer.prototype.read = function () {\n        var tokens = [];\n        var token = this.consumeToken();\n        while (token !== EOF_TOKEN) {\n            tokens.push(token);\n            token = this.consumeToken();\n        }\n        return tokens;\n    };\n    Tokenizer.prototype.consumeToken = function () {\n        var codePoint = this.consumeCodePoint();\n        switch (codePoint) {\n            case QUOTATION_MARK:\n                return this.consumeStringToken(QUOTATION_MARK);\n            case NUMBER_SIGN:\n                var c1 = this.peekCodePoint(0);\n                var c2 = this.peekCodePoint(1);\n                var c3 = this.peekCodePoint(2);\n                if (isNameCodePoint(c1) || isValidEscape(c2, c3)) {\n                    var flags = isIdentifierStart(c1, c2, c3) ? FLAG_ID : FLAG_UNRESTRICTED;\n                    var value = this.consumeName();\n                    return { type: 5 /* HASH_TOKEN */, value: value, flags: flags };\n                }\n                break;\n            case DOLLAR_SIGN:\n                if (this.peekCodePoint(0) === EQUALS_SIGN) {\n                    this.consumeCodePoint();\n                    return SUFFIX_MATCH_TOKEN;\n                }\n                break;\n            case APOSTROPHE:\n                return this.consumeStringToken(APOSTROPHE);\n            case LEFT_PARENTHESIS:\n                return LEFT_PARENTHESIS_TOKEN;\n            case RIGHT_PARENTHESIS:\n                return RIGHT_PARENTHESIS_TOKEN;\n            case ASTERISK:\n                if (this.peekCodePoint(0) === EQUALS_SIGN) {\n                    this.consumeCodePoint();\n                    return SUBSTRING_MATCH_TOKEN;\n                }\n                break;\n            case PLUS_SIGN:\n                if (isNumberStart(codePoint, this.peekCodePoint(0), this.peekCodePoint(1))) {\n                    this.reconsumeCodePoint(codePoint);\n                    return this.consumeNumericToken();\n                }\n                break;\n            case COMMA:\n                return COMMA_TOKEN;\n            case HYPHEN_MINUS:\n                var e1 = codePoint;\n                var e2 = this.peekCodePoint(0);\n                var e3 = this.peekCodePoint(1);\n                if (isNumberStart(e1, e2, e3)) {\n                    this.reconsumeCodePoint(codePoint);\n                    return this.consumeNumericToken();\n                }\n                if (isIdentifierStart(e1, e2, e3)) {\n                    this.reconsumeCodePoint(codePoint);\n                    return this.consumeIdentLikeToken();\n                }\n                if (e2 === HYPHEN_MINUS && e3 === GREATER_THAN_SIGN) {\n                    this.consumeCodePoint();\n                    this.consumeCodePoint();\n                    return CDC_TOKEN;\n                }\n                break;\n            case FULL_STOP:\n                if (isNumberStart(codePoint, this.peekCodePoint(0), this.peekCodePoint(1))) {\n                    this.reconsumeCodePoint(codePoint);\n                    return this.consumeNumericToken();\n                }\n                break;\n            case SOLIDUS:\n                if (this.peekCodePoint(0) === ASTERISK) {\n                    this.consumeCodePoint();\n                    while (true) {\n                        var c = this.consumeCodePoint();\n                        if (c === ASTERISK) {\n                            c = this.consumeCodePoint();\n                            if (c === SOLIDUS) {\n                                return this.consumeToken();\n                            }\n                        }\n                        if (c === EOF) {\n                            return this.consumeToken();\n                        }\n                    }\n                }\n                break;\n            case COLON:\n                return COLON_TOKEN;\n            case SEMICOLON:\n                return SEMICOLON_TOKEN;\n            case LESS_THAN_SIGN:\n                if (this.peekCodePoint(0) === EXCLAMATION_MARK &&\n                    this.peekCodePoint(1) === HYPHEN_MINUS &&\n                    this.peekCodePoint(2) === HYPHEN_MINUS) {\n                    this.consumeCodePoint();\n                    this.consumeCodePoint();\n                    return CDO_TOKEN;\n                }\n                break;\n            case COMMERCIAL_AT:\n                var a1 = this.peekCodePoint(0);\n                var a2 = this.peekCodePoint(1);\n                var a3 = this.peekCodePoint(2);\n                if (isIdentifierStart(a1, a2, a3)) {\n                    var value = this.consumeName();\n                    return { type: 7 /* AT_KEYWORD_TOKEN */, value: value };\n                }\n                break;\n            case LEFT_SQUARE_BRACKET:\n                return LEFT_SQUARE_BRACKET_TOKEN;\n            case REVERSE_SOLIDUS:\n                if (isValidEscape(codePoint, this.peekCodePoint(0))) {\n                    this.reconsumeCodePoint(codePoint);\n                    return this.consumeIdentLikeToken();\n                }\n                break;\n            case RIGHT_SQUARE_BRACKET:\n                return RIGHT_SQUARE_BRACKET_TOKEN;\n            case CIRCUMFLEX_ACCENT:\n                if (this.peekCodePoint(0) === EQUALS_SIGN) {\n                    this.consumeCodePoint();\n                    return PREFIX_MATCH_TOKEN;\n                }\n                break;\n            case LEFT_CURLY_BRACKET:\n                return LEFT_CURLY_BRACKET_TOKEN;\n            case RIGHT_CURLY_BRACKET:\n                return RIGHT_CURLY_BRACKET_TOKEN;\n            case u:\n            case U:\n                var u1 = this.peekCodePoint(0);\n                var u2 = this.peekCodePoint(1);\n                if (u1 === PLUS_SIGN && (isHex(u2) || u2 === QUESTION_MARK)) {\n                    this.consumeCodePoint();\n                    this.consumeUnicodeRangeToken();\n                }\n                this.reconsumeCodePoint(codePoint);\n                return this.consumeIdentLikeToken();\n            case VERTICAL_LINE:\n                if (this.peekCodePoint(0) === EQUALS_SIGN) {\n                    this.consumeCodePoint();\n                    return DASH_MATCH_TOKEN;\n                }\n                if (this.peekCodePoint(0) === VERTICAL_LINE) {\n                    this.consumeCodePoint();\n                    return COLUMN_TOKEN;\n                }\n                break;\n            case TILDE:\n                if (this.peekCodePoint(0) === EQUALS_SIGN) {\n                    this.consumeCodePoint();\n                    return INCLUDE_MATCH_TOKEN;\n                }\n                break;\n            case EOF:\n                return EOF_TOKEN;\n        }\n        if (isWhiteSpace(codePoint)) {\n            this.consumeWhiteSpace();\n            return WHITESPACE_TOKEN;\n        }\n        if (isDigit(codePoint)) {\n            this.reconsumeCodePoint(codePoint);\n            return this.consumeNumericToken();\n        }\n        if (isNameStartCodePoint(codePoint)) {\n            this.reconsumeCodePoint(codePoint);\n            return this.consumeIdentLikeToken();\n        }\n        return { type: 6 /* DELIM_TOKEN */, value: fromCodePoint$1(codePoint) };\n    };\n    Tokenizer.prototype.consumeCodePoint = function () {\n        var value = this._value.shift();\n        return typeof value === 'undefined' ? -1 : value;\n    };\n    Tokenizer.prototype.reconsumeCodePoint = function (codePoint) {\n        this._value.unshift(codePoint);\n    };\n    Tokenizer.prototype.peekCodePoint = function (delta) {\n        if (delta >= this._value.length) {\n            return -1;\n        }\n        return this._value[delta];\n    };\n    Tokenizer.prototype.consumeUnicodeRangeToken = function () {\n        var digits = [];\n        var codePoint = this.consumeCodePoint();\n        while (isHex(codePoint) && digits.length < 6) {\n            digits.push(codePoint);\n            codePoint = this.consumeCodePoint();\n        }\n        var questionMarks = false;\n        while (codePoint === QUESTION_MARK && digits.length < 6) {\n            digits.push(codePoint);\n            codePoint = this.consumeCodePoint();\n            questionMarks = true;\n        }\n        if (questionMarks) {\n            var start_1 = parseInt(fromCodePoint$1.apply(void 0, digits.map(function (digit) { return (digit === QUESTION_MARK ? ZERO : digit); })), 16);\n            var end = parseInt(fromCodePoint$1.apply(void 0, digits.map(function (digit) { return (digit === QUESTION_MARK ? F : digit); })), 16);\n            return { type: 30 /* UNICODE_RANGE_TOKEN */, start: start_1, end: end };\n        }\n        var start = parseInt(fromCodePoint$1.apply(void 0, digits), 16);\n        if (this.peekCodePoint(0) === HYPHEN_MINUS && isHex(this.peekCodePoint(1))) {\n            this.consumeCodePoint();\n            codePoint = this.consumeCodePoint();\n            var endDigits = [];\n            while (isHex(codePoint) && endDigits.length < 6) {\n                endDigits.push(codePoint);\n                codePoint = this.consumeCodePoint();\n            }\n            var end = parseInt(fromCodePoint$1.apply(void 0, endDigits), 16);\n            return { type: 30 /* UNICODE_RANGE_TOKEN */, start: start, end: end };\n        }\n        else {\n            return { type: 30 /* UNICODE_RANGE_TOKEN */, start: start, end: start };\n        }\n    };\n    Tokenizer.prototype.consumeIdentLikeToken = function () {\n        var value = this.consumeName();\n        if (value.toLowerCase() === 'url' && this.peekCodePoint(0) === LEFT_PARENTHESIS) {\n            this.consumeCodePoint();\n            return this.consumeUrlToken();\n        }\n        else if (this.peekCodePoint(0) === LEFT_PARENTHESIS) {\n            this.consumeCodePoint();\n            return { type: 19 /* FUNCTION_TOKEN */, value: value };\n        }\n        return { type: 20 /* IDENT_TOKEN */, value: value };\n    };\n    Tokenizer.prototype.consumeUrlToken = function () {\n        var value = [];\n        this.consumeWhiteSpace();\n        if (this.peekCodePoint(0) === EOF) {\n            return { type: 22 /* URL_TOKEN */, value: '' };\n        }\n        var next = this.peekCodePoint(0);\n        if (next === APOSTROPHE || next === QUOTATION_MARK) {\n            var stringToken = this.consumeStringToken(this.consumeCodePoint());\n            if (stringToken.type === 0 /* STRING_TOKEN */) {\n                this.consumeWhiteSpace();\n                if (this.peekCodePoint(0) === EOF || this.peekCodePoint(0) === RIGHT_PARENTHESIS) {\n                    this.consumeCodePoint();\n                    return { type: 22 /* URL_TOKEN */, value: stringToken.value };\n                }\n            }\n            this.consumeBadUrlRemnants();\n            return BAD_URL_TOKEN;\n        }\n        while (true) {\n            var codePoint = this.consumeCodePoint();\n            if (codePoint === EOF || codePoint === RIGHT_PARENTHESIS) {\n                return { type: 22 /* URL_TOKEN */, value: fromCodePoint$1.apply(void 0, value) };\n            }\n            else if (isWhiteSpace(codePoint)) {\n                this.consumeWhiteSpace();\n                if (this.peekCodePoint(0) === EOF || this.peekCodePoint(0) === RIGHT_PARENTHESIS) {\n                    this.consumeCodePoint();\n                    return { type: 22 /* URL_TOKEN */, value: fromCodePoint$1.apply(void 0, value) };\n                }\n                this.consumeBadUrlRemnants();\n                return BAD_URL_TOKEN;\n            }\n            else if (codePoint === QUOTATION_MARK ||\n                codePoint === APOSTROPHE ||\n                codePoint === LEFT_PARENTHESIS ||\n                isNonPrintableCodePoint(codePoint)) {\n                this.consumeBadUrlRemnants();\n                return BAD_URL_TOKEN;\n            }\n            else if (codePoint === REVERSE_SOLIDUS) {\n                if (isValidEscape(codePoint, this.peekCodePoint(0))) {\n                    value.push(this.consumeEscapedCodePoint());\n                }\n                else {\n                    this.consumeBadUrlRemnants();\n                    return BAD_URL_TOKEN;\n                }\n            }\n            else {\n                value.push(codePoint);\n            }\n        }\n    };\n    Tokenizer.prototype.consumeWhiteSpace = function () {\n        while (isWhiteSpace(this.peekCodePoint(0))) {\n            this.consumeCodePoint();\n        }\n    };\n    Tokenizer.prototype.consumeBadUrlRemnants = function () {\n        while (true) {\n            var codePoint = this.consumeCodePoint();\n            if (codePoint === RIGHT_PARENTHESIS || codePoint === EOF) {\n                return;\n            }\n            if (isValidEscape(codePoint, this.peekCodePoint(0))) {\n                this.consumeEscapedCodePoint();\n            }\n        }\n    };\n    Tokenizer.prototype.consumeStringSlice = function (count) {\n        var SLICE_STACK_SIZE = 50000;\n        var value = '';\n        while (count > 0) {\n            var amount = Math.min(SLICE_STACK_SIZE, count);\n            value += fromCodePoint$1.apply(void 0, this._value.splice(0, amount));\n            count -= amount;\n        }\n        this._value.shift();\n        return value;\n    };\n    Tokenizer.prototype.consumeStringToken = function (endingCodePoint) {\n        var value = '';\n        var i = 0;\n        do {\n            var codePoint = this._value[i];\n            if (codePoint === EOF || codePoint === undefined || codePoint === endingCodePoint) {\n                value += this.consumeStringSlice(i);\n                return { type: 0 /* STRING_TOKEN */, value: value };\n            }\n            if (codePoint === LINE_FEED) {\n                this._value.splice(0, i);\n                return BAD_STRING_TOKEN;\n            }\n            if (codePoint === REVERSE_SOLIDUS) {\n                var next = this._value[i + 1];\n                if (next !== EOF && next !== undefined) {\n                    if (next === LINE_FEED) {\n                        value += this.consumeStringSlice(i);\n                        i = -1;\n                        this._value.shift();\n                    }\n                    else if (isValidEscape(codePoint, next)) {\n                        value += this.consumeStringSlice(i);\n                        value += fromCodePoint$1(this.consumeEscapedCodePoint());\n                        i = -1;\n                    }\n                }\n            }\n            i++;\n        } while (true);\n    };\n    Tokenizer.prototype.consumeNumber = function () {\n        var repr = [];\n        var type = FLAG_INTEGER;\n        var c1 = this.peekCodePoint(0);\n        if (c1 === PLUS_SIGN || c1 === HYPHEN_MINUS) {\n            repr.push(this.consumeCodePoint());\n        }\n        while (isDigit(this.peekCodePoint(0))) {\n            repr.push(this.consumeCodePoint());\n        }\n        c1 = this.peekCodePoint(0);\n        var c2 = this.peekCodePoint(1);\n        if (c1 === FULL_STOP && isDigit(c2)) {\n            repr.push(this.consumeCodePoint(), this.consumeCodePoint());\n            type = FLAG_NUMBER;\n            while (isDigit(this.peekCodePoint(0))) {\n                repr.push(this.consumeCodePoint());\n            }\n        }\n        c1 = this.peekCodePoint(0);\n        c2 = this.peekCodePoint(1);\n        var c3 = this.peekCodePoint(2);\n        if ((c1 === E || c1 === e) && (((c2 === PLUS_SIGN || c2 === HYPHEN_MINUS) && isDigit(c3)) || isDigit(c2))) {\n            repr.push(this.consumeCodePoint(), this.consumeCodePoint());\n            type = FLAG_NUMBER;\n            while (isDigit(this.peekCodePoint(0))) {\n                repr.push(this.consumeCodePoint());\n            }\n        }\n        return [stringToNumber(repr), type];\n    };\n    Tokenizer.prototype.consumeNumericToken = function () {\n        var _a = this.consumeNumber(), number = _a[0], flags = _a[1];\n        var c1 = this.peekCodePoint(0);\n        var c2 = this.peekCodePoint(1);\n        var c3 = this.peekCodePoint(2);\n        if (isIdentifierStart(c1, c2, c3)) {\n            var unit = this.consumeName();\n            return { type: 15 /* DIMENSION_TOKEN */, number: number, flags: flags, unit: unit };\n        }\n        if (c1 === PERCENTAGE_SIGN) {\n            this.consumeCodePoint();\n            return { type: 16 /* PERCENTAGE_TOKEN */, number: number, flags: flags };\n        }\n        return { type: 17 /* NUMBER_TOKEN */, number: number, flags: flags };\n    };\n    Tokenizer.prototype.consumeEscapedCodePoint = function () {\n        var codePoint = this.consumeCodePoint();\n        if (isHex(codePoint)) {\n            var hex = fromCodePoint$1(codePoint);\n            while (isHex(this.peekCodePoint(0)) && hex.length < 6) {\n                hex += fromCodePoint$1(this.consumeCodePoint());\n            }\n            if (isWhiteSpace(this.peekCodePoint(0))) {\n                this.consumeCodePoint();\n            }\n            var hexCodePoint = parseInt(hex, 16);\n            if (hexCodePoint === 0 || isSurrogateCodePoint(hexCodePoint) || hexCodePoint > 0x10ffff) {\n                return REPLACEMENT_CHARACTER;\n            }\n            return hexCodePoint;\n        }\n        if (codePoint === EOF) {\n            return REPLACEMENT_CHARACTER;\n        }\n        return codePoint;\n    };\n    Tokenizer.prototype.consumeName = function () {\n        var result = '';\n        while (true) {\n            var codePoint = this.consumeCodePoint();\n            if (isNameCodePoint(codePoint)) {\n                result += fromCodePoint$1(codePoint);\n            }\n            else if (isValidEscape(codePoint, this.peekCodePoint(0))) {\n                result += fromCodePoint$1(this.consumeEscapedCodePoint());\n            }\n            else {\n                this.reconsumeCodePoint(codePoint);\n                return result;\n            }\n        }\n    };\n    return Tokenizer;\n}());\n\nvar Parser = /** @class */ (function () {\n    function Parser(tokens) {\n        this._tokens = tokens;\n    }\n    Parser.create = function (value) {\n        var tokenizer = new Tokenizer();\n        tokenizer.write(value);\n        return new Parser(tokenizer.read());\n    };\n    Parser.parseValue = function (value) {\n        return Parser.create(value).parseComponentValue();\n    };\n    Parser.parseValues = function (value) {\n        return Parser.create(value).parseComponentValues();\n    };\n    Parser.prototype.parseComponentValue = function () {\n        var token = this.consumeToken();\n        while (token.type === 31 /* WHITESPACE_TOKEN */) {\n            token = this.consumeToken();\n        }\n        if (token.type === 32 /* EOF_TOKEN */) {\n            throw new SyntaxError(\"Error parsing CSS component value, unexpected EOF\");\n        }\n        this.reconsumeToken(token);\n        var value = this.consumeComponentValue();\n        do {\n            token = this.consumeToken();\n        } while (token.type === 31 /* WHITESPACE_TOKEN */);\n        if (token.type === 32 /* EOF_TOKEN */) {\n            return value;\n        }\n        throw new SyntaxError(\"Error parsing CSS component value, multiple values found when expecting only one\");\n    };\n    Parser.prototype.parseComponentValues = function () {\n        var values = [];\n        while (true) {\n            var value = this.consumeComponentValue();\n            if (value.type === 32 /* EOF_TOKEN */) {\n                return values;\n            }\n            values.push(value);\n            values.push();\n        }\n    };\n    Parser.prototype.consumeComponentValue = function () {\n        var token = this.consumeToken();\n        switch (token.type) {\n            case 11 /* LEFT_CURLY_BRACKET_TOKEN */:\n            case 28 /* LEFT_SQUARE_BRACKET_TOKEN */:\n            case 2 /* LEFT_PARENTHESIS_TOKEN */:\n                return this.consumeSimpleBlock(token.type);\n            case 19 /* FUNCTION_TOKEN */:\n                return this.consumeFunction(token);\n        }\n        return token;\n    };\n    Parser.prototype.consumeSimpleBlock = function (type) {\n        var block = { type: type, values: [] };\n        var token = this.consumeToken();\n        while (true) {\n            if (token.type === 32 /* EOF_TOKEN */ || isEndingTokenFor(token, type)) {\n                return block;\n            }\n            this.reconsumeToken(token);\n            block.values.push(this.consumeComponentValue());\n            token = this.consumeToken();\n        }\n    };\n    Parser.prototype.consumeFunction = function (functionToken) {\n        var cssFunction = {\n            name: functionToken.value,\n            values: [],\n            type: 18 /* FUNCTION */\n        };\n        while (true) {\n            var token = this.consumeToken();\n            if (token.type === 32 /* EOF_TOKEN */ || token.type === 3 /* RIGHT_PARENTHESIS_TOKEN */) {\n                return cssFunction;\n            }\n            this.reconsumeToken(token);\n            cssFunction.values.push(this.consumeComponentValue());\n        }\n    };\n    Parser.prototype.consumeToken = function () {\n        var token = this._tokens.shift();\n        return typeof token === 'undefined' ? EOF_TOKEN : token;\n    };\n    Parser.prototype.reconsumeToken = function (token) {\n        this._tokens.unshift(token);\n    };\n    return Parser;\n}());\nvar isDimensionToken = function (token) { return token.type === 15 /* DIMENSION_TOKEN */; };\nvar isNumberToken = function (token) { return token.type === 17 /* NUMBER_TOKEN */; };\nvar isIdentToken = function (token) { return token.type === 20 /* IDENT_TOKEN */; };\nvar isStringToken = function (token) { return token.type === 0 /* STRING_TOKEN */; };\nvar isIdentWithValue = function (token, value) {\n    return isIdentToken(token) && token.value === value;\n};\nvar nonWhiteSpace = function (token) { return token.type !== 31 /* WHITESPACE_TOKEN */; };\nvar nonFunctionArgSeparator = function (token) {\n    return token.type !== 31 /* WHITESPACE_TOKEN */ && token.type !== 4 /* COMMA_TOKEN */;\n};\nvar parseFunctionArgs = function (tokens) {\n    var args = [];\n    var arg = [];\n    tokens.forEach(function (token) {\n        if (token.type === 4 /* COMMA_TOKEN */) {\n            if (arg.length === 0) {\n                throw new Error(\"Error parsing function args, zero tokens for arg\");\n            }\n            args.push(arg);\n            arg = [];\n            return;\n        }\n        if (token.type !== 31 /* WHITESPACE_TOKEN */) {\n            arg.push(token);\n        }\n    });\n    if (arg.length) {\n        args.push(arg);\n    }\n    return args;\n};\nvar isEndingTokenFor = function (token, type) {\n    if (type === 11 /* LEFT_CURLY_BRACKET_TOKEN */ && token.type === 12 /* RIGHT_CURLY_BRACKET_TOKEN */) {\n        return true;\n    }\n    if (type === 28 /* LEFT_SQUARE_BRACKET_TOKEN */ && token.type === 29 /* RIGHT_SQUARE_BRACKET_TOKEN */) {\n        return true;\n    }\n    return type === 2 /* LEFT_PARENTHESIS_TOKEN */ && token.type === 3 /* RIGHT_PARENTHESIS_TOKEN */;\n};\n\nvar isLength = function (token) {\n    return token.type === 17 /* NUMBER_TOKEN */ || token.type === 15 /* DIMENSION_TOKEN */;\n};\n\nvar isLengthPercentage = function (token) {\n    return token.type === 16 /* PERCENTAGE_TOKEN */ || isLength(token);\n};\nvar parseLengthPercentageTuple = function (tokens) {\n    return tokens.length > 1 ? [tokens[0], tokens[1]] : [tokens[0]];\n};\nvar ZERO_LENGTH = {\n    type: 17 /* NUMBER_TOKEN */,\n    number: 0,\n    flags: FLAG_INTEGER\n};\nvar FIFTY_PERCENT = {\n    type: 16 /* PERCENTAGE_TOKEN */,\n    number: 50,\n    flags: FLAG_INTEGER\n};\nvar HUNDRED_PERCENT = {\n    type: 16 /* PERCENTAGE_TOKEN */,\n    number: 100,\n    flags: FLAG_INTEGER\n};\nvar getAbsoluteValueForTuple = function (tuple, width, height) {\n    var x = tuple[0], y = tuple[1];\n    return [getAbsoluteValue(x, width), getAbsoluteValue(typeof y !== 'undefined' ? y : x, height)];\n};\nvar getAbsoluteValue = function (token, parent) {\n    if (token.type === 16 /* PERCENTAGE_TOKEN */) {\n        return (token.number / 100) * parent;\n    }\n    if (isDimensionToken(token)) {\n        switch (token.unit) {\n            case 'rem':\n            case 'em':\n                return 16 * token.number; // TODO use correct font-size\n            case 'px':\n            default:\n                return token.number;\n        }\n    }\n    return token.number;\n};\n\nvar DEG = 'deg';\nvar GRAD = 'grad';\nvar RAD = 'rad';\nvar TURN = 'turn';\nvar angle = {\n    name: 'angle',\n    parse: function (_context, value) {\n        if (value.type === 15 /* DIMENSION_TOKEN */) {\n            switch (value.unit) {\n                case DEG:\n                    return (Math.PI * value.number) / 180;\n                case GRAD:\n                    return (Math.PI / 200) * value.number;\n                case RAD:\n                    return value.number;\n                case TURN:\n                    return Math.PI * 2 * value.number;\n            }\n        }\n        throw new Error(\"Unsupported angle type\");\n    }\n};\nvar isAngle = function (value) {\n    if (value.type === 15 /* DIMENSION_TOKEN */) {\n        if (value.unit === DEG || value.unit === GRAD || value.unit === RAD || value.unit === TURN) {\n            return true;\n        }\n    }\n    return false;\n};\nvar parseNamedSide = function (tokens) {\n    var sideOrCorner = tokens\n        .filter(isIdentToken)\n        .map(function (ident) { return ident.value; })\n        .join(' ');\n    switch (sideOrCorner) {\n        case 'to bottom right':\n        case 'to right bottom':\n        case 'left top':\n        case 'top left':\n            return [ZERO_LENGTH, ZERO_LENGTH];\n        case 'to top':\n        case 'bottom':\n            return deg(0);\n        case 'to bottom left':\n        case 'to left bottom':\n        case 'right top':\n        case 'top right':\n            return [ZERO_LENGTH, HUNDRED_PERCENT];\n        case 'to right':\n        case 'left':\n            return deg(90);\n        case 'to top left':\n        case 'to left top':\n        case 'right bottom':\n        case 'bottom right':\n            return [HUNDRED_PERCENT, HUNDRED_PERCENT];\n        case 'to bottom':\n        case 'top':\n            return deg(180);\n        case 'to top right':\n        case 'to right top':\n        case 'left bottom':\n        case 'bottom left':\n            return [HUNDRED_PERCENT, ZERO_LENGTH];\n        case 'to left':\n        case 'right':\n            return deg(270);\n    }\n    return 0;\n};\nvar deg = function (deg) { return (Math.PI * deg) / 180; };\n\nvar color$1 = {\n    name: 'color',\n    parse: function (context, value) {\n        if (value.type === 18 /* FUNCTION */) {\n            var colorFunction = SUPPORTED_COLOR_FUNCTIONS[value.name];\n            if (typeof colorFunction === 'undefined') {\n                throw new Error(\"Attempting to parse an unsupported color function \\\"\" + value.name + \"\\\"\");\n            }\n            return colorFunction(context, value.values);\n        }\n        if (value.type === 5 /* HASH_TOKEN */) {\n            if (value.value.length === 3) {\n                var r = value.value.substring(0, 1);\n                var g = value.value.substring(1, 2);\n                var b = value.value.substring(2, 3);\n                return pack(parseInt(r + r, 16), parseInt(g + g, 16), parseInt(b + b, 16), 1);\n            }\n            if (value.value.length === 4) {\n                var r = value.value.substring(0, 1);\n                var g = value.value.substring(1, 2);\n                var b = value.value.substring(2, 3);\n                var a = value.value.substring(3, 4);\n                return pack(parseInt(r + r, 16), parseInt(g + g, 16), parseInt(b + b, 16), parseInt(a + a, 16) / 255);\n            }\n            if (value.value.length === 6) {\n                var r = value.value.substring(0, 2);\n                var g = value.value.substring(2, 4);\n                var b = value.value.substring(4, 6);\n                return pack(parseInt(r, 16), parseInt(g, 16), parseInt(b, 16), 1);\n            }\n            if (value.value.length === 8) {\n                var r = value.value.substring(0, 2);\n                var g = value.value.substring(2, 4);\n                var b = value.value.substring(4, 6);\n                var a = value.value.substring(6, 8);\n                return pack(parseInt(r, 16), parseInt(g, 16), parseInt(b, 16), parseInt(a, 16) / 255);\n            }\n        }\n        if (value.type === 20 /* IDENT_TOKEN */) {\n            var namedColor = COLORS[value.value.toUpperCase()];\n            if (typeof namedColor !== 'undefined') {\n                return namedColor;\n            }\n        }\n        return COLORS.TRANSPARENT;\n    }\n};\nvar isTransparent = function (color) { return (0xff & color) === 0; };\nvar asString = function (color) {\n    var alpha = 0xff & color;\n    var blue = 0xff & (color >> 8);\n    var green = 0xff & (color >> 16);\n    var red = 0xff & (color >> 24);\n    return alpha < 255 ? \"rgba(\" + red + \",\" + green + \",\" + blue + \",\" + alpha / 255 + \")\" : \"rgb(\" + red + \",\" + green + \",\" + blue + \")\";\n};\nvar pack = function (r, g, b, a) {\n    return ((r << 24) | (g << 16) | (b << 8) | (Math.round(a * 255) << 0)) >>> 0;\n};\nvar getTokenColorValue = function (token, i) {\n    if (token.type === 17 /* NUMBER_TOKEN */) {\n        return token.number;\n    }\n    if (token.type === 16 /* PERCENTAGE_TOKEN */) {\n        var max = i === 3 ? 1 : 255;\n        return i === 3 ? (token.number / 100) * max : Math.round((token.number / 100) * max);\n    }\n    return 0;\n};\nvar rgb = function (_context, args) {\n    var tokens = args.filter(nonFunctionArgSeparator);\n    if (tokens.length === 3) {\n        var _a = tokens.map(getTokenColorValue), r = _a[0], g = _a[1], b = _a[2];\n        return pack(r, g, b, 1);\n    }\n    if (tokens.length === 4) {\n        var _b = tokens.map(getTokenColorValue), r = _b[0], g = _b[1], b = _b[2], a = _b[3];\n        return pack(r, g, b, a);\n    }\n    return 0;\n};\nfunction hue2rgb(t1, t2, hue) {\n    if (hue < 0) {\n        hue += 1;\n    }\n    if (hue >= 1) {\n        hue -= 1;\n    }\n    if (hue < 1 / 6) {\n        return (t2 - t1) * hue * 6 + t1;\n    }\n    else if (hue < 1 / 2) {\n        return t2;\n    }\n    else if (hue < 2 / 3) {\n        return (t2 - t1) * 6 * (2 / 3 - hue) + t1;\n    }\n    else {\n        return t1;\n    }\n}\nvar hsl = function (context, args) {\n    var tokens = args.filter(nonFunctionArgSeparator);\n    var hue = tokens[0], saturation = tokens[1], lightness = tokens[2], alpha = tokens[3];\n    var h = (hue.type === 17 /* NUMBER_TOKEN */ ? deg(hue.number) : angle.parse(context, hue)) / (Math.PI * 2);\n    var s = isLengthPercentage(saturation) ? saturation.number / 100 : 0;\n    var l = isLengthPercentage(lightness) ? lightness.number / 100 : 0;\n    var a = typeof alpha !== 'undefined' && isLengthPercentage(alpha) ? getAbsoluteValue(alpha, 1) : 1;\n    if (s === 0) {\n        return pack(l * 255, l * 255, l * 255, 1);\n    }\n    var t2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;\n    var t1 = l * 2 - t2;\n    var r = hue2rgb(t1, t2, h + 1 / 3);\n    var g = hue2rgb(t1, t2, h);\n    var b = hue2rgb(t1, t2, h - 1 / 3);\n    return pack(r * 255, g * 255, b * 255, a);\n};\nvar SUPPORTED_COLOR_FUNCTIONS = {\n    hsl: hsl,\n    hsla: hsl,\n    rgb: rgb,\n    rgba: rgb\n};\nvar parseColor = function (context, value) {\n    return color$1.parse(context, Parser.create(value).parseComponentValue());\n};\nvar COLORS = {\n    ALICEBLUE: 0xf0f8ffff,\n    ANTIQUEWHITE: 0xfaebd7ff,\n    AQUA: 0x00ffffff,\n    AQUAMARINE: 0x7fffd4ff,\n    AZURE: 0xf0ffffff,\n    BEIGE: 0xf5f5dcff,\n    BISQUE: 0xffe4c4ff,\n    BLACK: 0x000000ff,\n    BLANCHEDALMOND: 0xffebcdff,\n    BLUE: 0x0000ffff,\n    BLUEVIOLET: 0x8a2be2ff,\n    BROWN: 0xa52a2aff,\n    BURLYWOOD: 0xdeb887ff,\n    CADETBLUE: 0x5f9ea0ff,\n    CHARTREUSE: 0x7fff00ff,\n    CHOCOLATE: 0xd2691eff,\n    CORAL: 0xff7f50ff,\n    CORNFLOWERBLUE: 0x6495edff,\n    CORNSILK: 0xfff8dcff,\n    CRIMSON: 0xdc143cff,\n    CYAN: 0x00ffffff,\n    DARKBLUE: 0x00008bff,\n    DARKCYAN: 0x008b8bff,\n    DARKGOLDENROD: 0xb886bbff,\n    DARKGRAY: 0xa9a9a9ff,\n    DARKGREEN: 0x006400ff,\n    DARKGREY: 0xa9a9a9ff,\n    DARKKHAKI: 0xbdb76bff,\n    DARKMAGENTA: 0x8b008bff,\n    DARKOLIVEGREEN: 0x556b2fff,\n    DARKORANGE: 0xff8c00ff,\n    DARKORCHID: 0x9932ccff,\n    DARKRED: 0x8b0000ff,\n    DARKSALMON: 0xe9967aff,\n    DARKSEAGREEN: 0x8fbc8fff,\n    DARKSLATEBLUE: 0x483d8bff,\n    DARKSLATEGRAY: 0x2f4f4fff,\n    DARKSLATEGREY: 0x2f4f4fff,\n    DARKTURQUOISE: 0x00ced1ff,\n    DARKVIOLET: 0x9400d3ff,\n    DEEPPINK: 0xff1493ff,\n    DEEPSKYBLUE: 0x00bfffff,\n    DIMGRAY: 0x696969ff,\n    DIMGREY: 0x696969ff,\n    DODGERBLUE: 0x1e90ffff,\n    FIREBRICK: 0xb22222ff,\n    FLORALWHITE: 0xfffaf0ff,\n    FORESTGREEN: 0x228b22ff,\n    FUCHSIA: 0xff00ffff,\n    GAINSBORO: 0xdcdcdcff,\n    GHOSTWHITE: 0xf8f8ffff,\n    GOLD: 0xffd700ff,\n    GOLDENROD: 0xdaa520ff,\n    GRAY: 0x808080ff,\n    GREEN: 0x008000ff,\n    GREENYELLOW: 0xadff2fff,\n    GREY: 0x808080ff,\n    HONEYDEW: 0xf0fff0ff,\n    HOTPINK: 0xff69b4ff,\n    INDIANRED: 0xcd5c5cff,\n    INDIGO: 0x4b0082ff,\n    IVORY: 0xfffff0ff,\n    KHAKI: 0xf0e68cff,\n    LAVENDER: 0xe6e6faff,\n    LAVENDERBLUSH: 0xfff0f5ff,\n    LAWNGREEN: 0x7cfc00ff,\n    LEMONCHIFFON: 0xfffacdff,\n    LIGHTBLUE: 0xadd8e6ff,\n    LIGHTCORAL: 0xf08080ff,\n    LIGHTCYAN: 0xe0ffffff,\n    LIGHTGOLDENRODYELLOW: 0xfafad2ff,\n    LIGHTGRAY: 0xd3d3d3ff,\n    LIGHTGREEN: 0x90ee90ff,\n    LIGHTGREY: 0xd3d3d3ff,\n    LIGHTPINK: 0xffb6c1ff,\n    LIGHTSALMON: 0xffa07aff,\n    LIGHTSEAGREEN: 0x20b2aaff,\n    LIGHTSKYBLUE: 0x87cefaff,\n    LIGHTSLATEGRAY: 0x778899ff,\n    LIGHTSLATEGREY: 0x778899ff,\n    LIGHTSTEELBLUE: 0xb0c4deff,\n    LIGHTYELLOW: 0xffffe0ff,\n    LIME: 0x00ff00ff,\n    LIMEGREEN: 0x32cd32ff,\n    LINEN: 0xfaf0e6ff,\n    MAGENTA: 0xff00ffff,\n    MAROON: 0x800000ff,\n    MEDIUMAQUAMARINE: 0x66cdaaff,\n    MEDIUMBLUE: 0x0000cdff,\n    MEDIUMORCHID: 0xba55d3ff,\n    MEDIUMPURPLE: 0x9370dbff,\n    MEDIUMSEAGREEN: 0x3cb371ff,\n    MEDIUMSLATEBLUE: 0x7b68eeff,\n    MEDIUMSPRINGGREEN: 0x00fa9aff,\n    MEDIUMTURQUOISE: 0x48d1ccff,\n    MEDIUMVIOLETRED: 0xc71585ff,\n    MIDNIGHTBLUE: 0x191970ff,\n    MINTCREAM: 0xf5fffaff,\n    MISTYROSE: 0xffe4e1ff,\n    MOCCASIN: 0xffe4b5ff,\n    NAVAJOWHITE: 0xffdeadff,\n    NAVY: 0x000080ff,\n    OLDLACE: 0xfdf5e6ff,\n    OLIVE: 0x808000ff,\n    OLIVEDRAB: 0x6b8e23ff,\n    ORANGE: 0xffa500ff,\n    ORANGERED: 0xff4500ff,\n    ORCHID: 0xda70d6ff,\n    PALEGOLDENROD: 0xeee8aaff,\n    PALEGREEN: 0x98fb98ff,\n    PALETURQUOISE: 0xafeeeeff,\n    PALEVIOLETRED: 0xdb7093ff,\n    PAPAYAWHIP: 0xffefd5ff,\n    PEACHPUFF: 0xffdab9ff,\n    PERU: 0xcd853fff,\n    PINK: 0xffc0cbff,\n    PLUM: 0xdda0ddff,\n    POWDERBLUE: 0xb0e0e6ff,\n    PURPLE: 0x800080ff,\n    REBECCAPURPLE: 0x663399ff,\n    RED: 0xff0000ff,\n    ROSYBROWN: 0xbc8f8fff,\n    ROYALBLUE: 0x4169e1ff,\n    SADDLEBROWN: 0x8b4513ff,\n    SALMON: 0xfa8072ff,\n    SANDYBROWN: 0xf4a460ff,\n    SEAGREEN: 0x2e8b57ff,\n    SEASHELL: 0xfff5eeff,\n    SIENNA: 0xa0522dff,\n    SILVER: 0xc0c0c0ff,\n    SKYBLUE: 0x87ceebff,\n    SLATEBLUE: 0x6a5acdff,\n    SLATEGRAY: 0x708090ff,\n    SLATEGREY: 0x708090ff,\n    SNOW: 0xfffafaff,\n    SPRINGGREEN: 0x00ff7fff,\n    STEELBLUE: 0x4682b4ff,\n    TAN: 0xd2b48cff,\n    TEAL: 0x008080ff,\n    THISTLE: 0xd8bfd8ff,\n    TOMATO: 0xff6347ff,\n    TRANSPARENT: 0x00000000,\n    TURQUOISE: 0x40e0d0ff,\n    VIOLET: 0xee82eeff,\n    WHEAT: 0xf5deb3ff,\n    WHITE: 0xffffffff,\n    WHITESMOKE: 0xf5f5f5ff,\n    YELLOW: 0xffff00ff,\n    YELLOWGREEN: 0x9acd32ff\n};\n\nvar backgroundClip = {\n    name: 'background-clip',\n    initialValue: 'border-box',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        return tokens.map(function (token) {\n            if (isIdentToken(token)) {\n                switch (token.value) {\n                    case 'padding-box':\n                        return 1 /* PADDING_BOX */;\n                    case 'content-box':\n                        return 2 /* CONTENT_BOX */;\n                }\n            }\n            return 0 /* BORDER_BOX */;\n        });\n    }\n};\n\nvar backgroundColor = {\n    name: \"background-color\",\n    initialValue: 'transparent',\n    prefix: false,\n    type: 3 /* TYPE_VALUE */,\n    format: 'color'\n};\n\nvar parseColorStop = function (context, args) {\n    var color = color$1.parse(context, args[0]);\n    var stop = args[1];\n    return stop && isLengthPercentage(stop) ? { color: color, stop: stop } : { color: color, stop: null };\n};\nvar processColorStops = function (stops, lineLength) {\n    var first = stops[0];\n    var last = stops[stops.length - 1];\n    if (first.stop === null) {\n        first.stop = ZERO_LENGTH;\n    }\n    if (last.stop === null) {\n        last.stop = HUNDRED_PERCENT;\n    }\n    var processStops = [];\n    var previous = 0;\n    for (var i = 0; i < stops.length; i++) {\n        var stop_1 = stops[i].stop;\n        if (stop_1 !== null) {\n            var absoluteValue = getAbsoluteValue(stop_1, lineLength);\n            if (absoluteValue > previous) {\n                processStops.push(absoluteValue);\n            }\n            else {\n                processStops.push(previous);\n            }\n            previous = absoluteValue;\n        }\n        else {\n            processStops.push(null);\n        }\n    }\n    var gapBegin = null;\n    for (var i = 0; i < processStops.length; i++) {\n        var stop_2 = processStops[i];\n        if (stop_2 === null) {\n            if (gapBegin === null) {\n                gapBegin = i;\n            }\n        }\n        else if (gapBegin !== null) {\n            var gapLength = i - gapBegin;\n            var beforeGap = processStops[gapBegin - 1];\n            var gapValue = (stop_2 - beforeGap) / (gapLength + 1);\n            for (var g = 1; g <= gapLength; g++) {\n                processStops[gapBegin + g - 1] = gapValue * g;\n            }\n            gapBegin = null;\n        }\n    }\n    return stops.map(function (_a, i) {\n        var color = _a.color;\n        return { color: color, stop: Math.max(Math.min(1, processStops[i] / lineLength), 0) };\n    });\n};\nvar getAngleFromCorner = function (corner, width, height) {\n    var centerX = width / 2;\n    var centerY = height / 2;\n    var x = getAbsoluteValue(corner[0], width) - centerX;\n    var y = centerY - getAbsoluteValue(corner[1], height);\n    return (Math.atan2(y, x) + Math.PI * 2) % (Math.PI * 2);\n};\nvar calculateGradientDirection = function (angle, width, height) {\n    var radian = typeof angle === 'number' ? angle : getAngleFromCorner(angle, width, height);\n    var lineLength = Math.abs(width * Math.sin(radian)) + Math.abs(height * Math.cos(radian));\n    var halfWidth = width / 2;\n    var halfHeight = height / 2;\n    var halfLineLength = lineLength / 2;\n    var yDiff = Math.sin(radian - Math.PI / 2) * halfLineLength;\n    var xDiff = Math.cos(radian - Math.PI / 2) * halfLineLength;\n    return [lineLength, halfWidth - xDiff, halfWidth + xDiff, halfHeight - yDiff, halfHeight + yDiff];\n};\nvar distance = function (a, b) { return Math.sqrt(a * a + b * b); };\nvar findCorner = function (width, height, x, y, closest) {\n    var corners = [\n        [0, 0],\n        [0, height],\n        [width, 0],\n        [width, height]\n    ];\n    return corners.reduce(function (stat, corner) {\n        var cx = corner[0], cy = corner[1];\n        var d = distance(x - cx, y - cy);\n        if (closest ? d < stat.optimumDistance : d > stat.optimumDistance) {\n            return {\n                optimumCorner: corner,\n                optimumDistance: d\n            };\n        }\n        return stat;\n    }, {\n        optimumDistance: closest ? Infinity : -Infinity,\n        optimumCorner: null\n    }).optimumCorner;\n};\nvar calculateRadius = function (gradient, x, y, width, height) {\n    var rx = 0;\n    var ry = 0;\n    switch (gradient.size) {\n        case 0 /* CLOSEST_SIDE */:\n            // The ending shape is sized so that that it exactly meets the side of the gradient box closest to the gradient’s center.\n            // If the shape is an ellipse, it exactly meets the closest side in each dimension.\n            if (gradient.shape === 0 /* CIRCLE */) {\n                rx = ry = Math.min(Math.abs(x), Math.abs(x - width), Math.abs(y), Math.abs(y - height));\n            }\n            else if (gradient.shape === 1 /* ELLIPSE */) {\n                rx = Math.min(Math.abs(x), Math.abs(x - width));\n                ry = Math.min(Math.abs(y), Math.abs(y - height));\n            }\n            break;\n        case 2 /* CLOSEST_CORNER */:\n            // The ending shape is sized so that that it passes through the corner of the gradient box closest to the gradient’s center.\n            // If the shape is an ellipse, the ending shape is given the same aspect-ratio it would have if closest-side were specified.\n            if (gradient.shape === 0 /* CIRCLE */) {\n                rx = ry = Math.min(distance(x, y), distance(x, y - height), distance(x - width, y), distance(x - width, y - height));\n            }\n            else if (gradient.shape === 1 /* ELLIPSE */) {\n                // Compute the ratio ry/rx (which is to be the same as for \"closest-side\")\n                var c = Math.min(Math.abs(y), Math.abs(y - height)) / Math.min(Math.abs(x), Math.abs(x - width));\n                var _a = findCorner(width, height, x, y, true), cx = _a[0], cy = _a[1];\n                rx = distance(cx - x, (cy - y) / c);\n                ry = c * rx;\n            }\n            break;\n        case 1 /* FARTHEST_SIDE */:\n            // Same as closest-side, except the ending shape is sized based on the farthest side(s)\n            if (gradient.shape === 0 /* CIRCLE */) {\n                rx = ry = Math.max(Math.abs(x), Math.abs(x - width), Math.abs(y), Math.abs(y - height));\n            }\n            else if (gradient.shape === 1 /* ELLIPSE */) {\n                rx = Math.max(Math.abs(x), Math.abs(x - width));\n                ry = Math.max(Math.abs(y), Math.abs(y - height));\n            }\n            break;\n        case 3 /* FARTHEST_CORNER */:\n            // Same as closest-corner, except the ending shape is sized based on the farthest corner.\n            // If the shape is an ellipse, the ending shape is given the same aspect ratio it would have if farthest-side were specified.\n            if (gradient.shape === 0 /* CIRCLE */) {\n                rx = ry = Math.max(distance(x, y), distance(x, y - height), distance(x - width, y), distance(x - width, y - height));\n            }\n            else if (gradient.shape === 1 /* ELLIPSE */) {\n                // Compute the ratio ry/rx (which is to be the same as for \"farthest-side\")\n                var c = Math.max(Math.abs(y), Math.abs(y - height)) / Math.max(Math.abs(x), Math.abs(x - width));\n                var _b = findCorner(width, height, x, y, false), cx = _b[0], cy = _b[1];\n                rx = distance(cx - x, (cy - y) / c);\n                ry = c * rx;\n            }\n            break;\n    }\n    if (Array.isArray(gradient.size)) {\n        rx = getAbsoluteValue(gradient.size[0], width);\n        ry = gradient.size.length === 2 ? getAbsoluteValue(gradient.size[1], height) : rx;\n    }\n    return [rx, ry];\n};\n\nvar linearGradient = function (context, tokens) {\n    var angle$1 = deg(180);\n    var stops = [];\n    parseFunctionArgs(tokens).forEach(function (arg, i) {\n        if (i === 0) {\n            var firstToken = arg[0];\n            if (firstToken.type === 20 /* IDENT_TOKEN */ && firstToken.value === 'to') {\n                angle$1 = parseNamedSide(arg);\n                return;\n            }\n            else if (isAngle(firstToken)) {\n                angle$1 = angle.parse(context, firstToken);\n                return;\n            }\n        }\n        var colorStop = parseColorStop(context, arg);\n        stops.push(colorStop);\n    });\n    return { angle: angle$1, stops: stops, type: 1 /* LINEAR_GRADIENT */ };\n};\n\nvar prefixLinearGradient = function (context, tokens) {\n    var angle$1 = deg(180);\n    var stops = [];\n    parseFunctionArgs(tokens).forEach(function (arg, i) {\n        if (i === 0) {\n            var firstToken = arg[0];\n            if (firstToken.type === 20 /* IDENT_TOKEN */ &&\n                ['top', 'left', 'right', 'bottom'].indexOf(firstToken.value) !== -1) {\n                angle$1 = parseNamedSide(arg);\n                return;\n            }\n            else if (isAngle(firstToken)) {\n                angle$1 = (angle.parse(context, firstToken) + deg(270)) % deg(360);\n                return;\n            }\n        }\n        var colorStop = parseColorStop(context, arg);\n        stops.push(colorStop);\n    });\n    return {\n        angle: angle$1,\n        stops: stops,\n        type: 1 /* LINEAR_GRADIENT */\n    };\n};\n\nvar webkitGradient = function (context, tokens) {\n    var angle = deg(180);\n    var stops = [];\n    var type = 1 /* LINEAR_GRADIENT */;\n    var shape = 0 /* CIRCLE */;\n    var size = 3 /* FARTHEST_CORNER */;\n    var position = [];\n    parseFunctionArgs(tokens).forEach(function (arg, i) {\n        var firstToken = arg[0];\n        if (i === 0) {\n            if (isIdentToken(firstToken) && firstToken.value === 'linear') {\n                type = 1 /* LINEAR_GRADIENT */;\n                return;\n            }\n            else if (isIdentToken(firstToken) && firstToken.value === 'radial') {\n                type = 2 /* RADIAL_GRADIENT */;\n                return;\n            }\n        }\n        if (firstToken.type === 18 /* FUNCTION */) {\n            if (firstToken.name === 'from') {\n                var color = color$1.parse(context, firstToken.values[0]);\n                stops.push({ stop: ZERO_LENGTH, color: color });\n            }\n            else if (firstToken.name === 'to') {\n                var color = color$1.parse(context, firstToken.values[0]);\n                stops.push({ stop: HUNDRED_PERCENT, color: color });\n            }\n            else if (firstToken.name === 'color-stop') {\n                var values = firstToken.values.filter(nonFunctionArgSeparator);\n                if (values.length === 2) {\n                    var color = color$1.parse(context, values[1]);\n                    var stop_1 = values[0];\n                    if (isNumberToken(stop_1)) {\n                        stops.push({\n                            stop: { type: 16 /* PERCENTAGE_TOKEN */, number: stop_1.number * 100, flags: stop_1.flags },\n                            color: color\n                        });\n                    }\n                }\n            }\n        }\n    });\n    return type === 1 /* LINEAR_GRADIENT */\n        ? {\n            angle: (angle + deg(180)) % deg(360),\n            stops: stops,\n            type: type\n        }\n        : { size: size, shape: shape, stops: stops, position: position, type: type };\n};\n\nvar CLOSEST_SIDE = 'closest-side';\nvar FARTHEST_SIDE = 'farthest-side';\nvar CLOSEST_CORNER = 'closest-corner';\nvar FARTHEST_CORNER = 'farthest-corner';\nvar CIRCLE = 'circle';\nvar ELLIPSE = 'ellipse';\nvar COVER = 'cover';\nvar CONTAIN = 'contain';\nvar radialGradient = function (context, tokens) {\n    var shape = 0 /* CIRCLE */;\n    var size = 3 /* FARTHEST_CORNER */;\n    var stops = [];\n    var position = [];\n    parseFunctionArgs(tokens).forEach(function (arg, i) {\n        var isColorStop = true;\n        if (i === 0) {\n            var isAtPosition_1 = false;\n            isColorStop = arg.reduce(function (acc, token) {\n                if (isAtPosition_1) {\n                    if (isIdentToken(token)) {\n                        switch (token.value) {\n                            case 'center':\n                                position.push(FIFTY_PERCENT);\n                                return acc;\n                            case 'top':\n                            case 'left':\n                                position.push(ZERO_LENGTH);\n                                return acc;\n                            case 'right':\n                            case 'bottom':\n                                position.push(HUNDRED_PERCENT);\n                                return acc;\n                        }\n                    }\n                    else if (isLengthPercentage(token) || isLength(token)) {\n                        position.push(token);\n                    }\n                }\n                else if (isIdentToken(token)) {\n                    switch (token.value) {\n                        case CIRCLE:\n                            shape = 0 /* CIRCLE */;\n                            return false;\n                        case ELLIPSE:\n                            shape = 1 /* ELLIPSE */;\n                            return false;\n                        case 'at':\n                            isAtPosition_1 = true;\n                            return false;\n                        case CLOSEST_SIDE:\n                            size = 0 /* CLOSEST_SIDE */;\n                            return false;\n                        case COVER:\n                        case FARTHEST_SIDE:\n                            size = 1 /* FARTHEST_SIDE */;\n                            return false;\n                        case CONTAIN:\n                        case CLOSEST_CORNER:\n                            size = 2 /* CLOSEST_CORNER */;\n                            return false;\n                        case FARTHEST_CORNER:\n                            size = 3 /* FARTHEST_CORNER */;\n                            return false;\n                    }\n                }\n                else if (isLength(token) || isLengthPercentage(token)) {\n                    if (!Array.isArray(size)) {\n                        size = [];\n                    }\n                    size.push(token);\n                    return false;\n                }\n                return acc;\n            }, isColorStop);\n        }\n        if (isColorStop) {\n            var colorStop = parseColorStop(context, arg);\n            stops.push(colorStop);\n        }\n    });\n    return { size: size, shape: shape, stops: stops, position: position, type: 2 /* RADIAL_GRADIENT */ };\n};\n\nvar prefixRadialGradient = function (context, tokens) {\n    var shape = 0 /* CIRCLE */;\n    var size = 3 /* FARTHEST_CORNER */;\n    var stops = [];\n    var position = [];\n    parseFunctionArgs(tokens).forEach(function (arg, i) {\n        var isColorStop = true;\n        if (i === 0) {\n            isColorStop = arg.reduce(function (acc, token) {\n                if (isIdentToken(token)) {\n                    switch (token.value) {\n                        case 'center':\n                            position.push(FIFTY_PERCENT);\n                            return false;\n                        case 'top':\n                        case 'left':\n                            position.push(ZERO_LENGTH);\n                            return false;\n                        case 'right':\n                        case 'bottom':\n                            position.push(HUNDRED_PERCENT);\n                            return false;\n                    }\n                }\n                else if (isLengthPercentage(token) || isLength(token)) {\n                    position.push(token);\n                    return false;\n                }\n                return acc;\n            }, isColorStop);\n        }\n        else if (i === 1) {\n            isColorStop = arg.reduce(function (acc, token) {\n                if (isIdentToken(token)) {\n                    switch (token.value) {\n                        case CIRCLE:\n                            shape = 0 /* CIRCLE */;\n                            return false;\n                        case ELLIPSE:\n                            shape = 1 /* ELLIPSE */;\n                            return false;\n                        case CONTAIN:\n                        case CLOSEST_SIDE:\n                            size = 0 /* CLOSEST_SIDE */;\n                            return false;\n                        case FARTHEST_SIDE:\n                            size = 1 /* FARTHEST_SIDE */;\n                            return false;\n                        case CLOSEST_CORNER:\n                            size = 2 /* CLOSEST_CORNER */;\n                            return false;\n                        case COVER:\n                        case FARTHEST_CORNER:\n                            size = 3 /* FARTHEST_CORNER */;\n                            return false;\n                    }\n                }\n                else if (isLength(token) || isLengthPercentage(token)) {\n                    if (!Array.isArray(size)) {\n                        size = [];\n                    }\n                    size.push(token);\n                    return false;\n                }\n                return acc;\n            }, isColorStop);\n        }\n        if (isColorStop) {\n            var colorStop = parseColorStop(context, arg);\n            stops.push(colorStop);\n        }\n    });\n    return { size: size, shape: shape, stops: stops, position: position, type: 2 /* RADIAL_GRADIENT */ };\n};\n\nvar isLinearGradient = function (background) {\n    return background.type === 1 /* LINEAR_GRADIENT */;\n};\nvar isRadialGradient = function (background) {\n    return background.type === 2 /* RADIAL_GRADIENT */;\n};\nvar image$1 = {\n    name: 'image',\n    parse: function (context, value) {\n        if (value.type === 22 /* URL_TOKEN */) {\n            var image_1 = { url: value.value, type: 0 /* URL */ };\n            context.cache.addImage(value.value);\n            return image_1;\n        }\n        if (value.type === 18 /* FUNCTION */) {\n            var imageFunction = SUPPORTED_IMAGE_FUNCTIONS[value.name];\n            if (typeof imageFunction === 'undefined') {\n                throw new Error(\"Attempting to parse an unsupported image function \\\"\" + value.name + \"\\\"\");\n            }\n            return imageFunction(context, value.values);\n        }\n        throw new Error(\"Unsupported image type \" + value.type);\n    }\n};\nfunction isSupportedImage(value) {\n    return (!(value.type === 20 /* IDENT_TOKEN */ && value.value === 'none') &&\n        (value.type !== 18 /* FUNCTION */ || !!SUPPORTED_IMAGE_FUNCTIONS[value.name]));\n}\nvar SUPPORTED_IMAGE_FUNCTIONS = {\n    'linear-gradient': linearGradient,\n    '-moz-linear-gradient': prefixLinearGradient,\n    '-ms-linear-gradient': prefixLinearGradient,\n    '-o-linear-gradient': prefixLinearGradient,\n    '-webkit-linear-gradient': prefixLinearGradient,\n    'radial-gradient': radialGradient,\n    '-moz-radial-gradient': prefixRadialGradient,\n    '-ms-radial-gradient': prefixRadialGradient,\n    '-o-radial-gradient': prefixRadialGradient,\n    '-webkit-radial-gradient': prefixRadialGradient,\n    '-webkit-gradient': webkitGradient\n};\n\nvar backgroundImage = {\n    name: 'background-image',\n    initialValue: 'none',\n    type: 1 /* LIST */,\n    prefix: false,\n    parse: function (context, tokens) {\n        if (tokens.length === 0) {\n            return [];\n        }\n        var first = tokens[0];\n        if (first.type === 20 /* IDENT_TOKEN */ && first.value === 'none') {\n            return [];\n        }\n        return tokens\n            .filter(function (value) { return nonFunctionArgSeparator(value) && isSupportedImage(value); })\n            .map(function (value) { return image$1.parse(context, value); });\n    }\n};\n\nvar backgroundOrigin = {\n    name: 'background-origin',\n    initialValue: 'border-box',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        return tokens.map(function (token) {\n            if (isIdentToken(token)) {\n                switch (token.value) {\n                    case 'padding-box':\n                        return 1 /* PADDING_BOX */;\n                    case 'content-box':\n                        return 2 /* CONTENT_BOX */;\n                }\n            }\n            return 0 /* BORDER_BOX */;\n        });\n    }\n};\n\nvar backgroundPosition = {\n    name: 'background-position',\n    initialValue: '0% 0%',\n    type: 1 /* LIST */,\n    prefix: false,\n    parse: function (_context, tokens) {\n        return parseFunctionArgs(tokens)\n            .map(function (values) { return values.filter(isLengthPercentage); })\n            .map(parseLengthPercentageTuple);\n    }\n};\n\nvar backgroundRepeat = {\n    name: 'background-repeat',\n    initialValue: 'repeat',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        return parseFunctionArgs(tokens)\n            .map(function (values) {\n            return values\n                .filter(isIdentToken)\n                .map(function (token) { return token.value; })\n                .join(' ');\n        })\n            .map(parseBackgroundRepeat);\n    }\n};\nvar parseBackgroundRepeat = function (value) {\n    switch (value) {\n        case 'no-repeat':\n            return 1 /* NO_REPEAT */;\n        case 'repeat-x':\n        case 'repeat no-repeat':\n            return 2 /* REPEAT_X */;\n        case 'repeat-y':\n        case 'no-repeat repeat':\n            return 3 /* REPEAT_Y */;\n        case 'repeat':\n        default:\n            return 0 /* REPEAT */;\n    }\n};\n\nvar BACKGROUND_SIZE;\n(function (BACKGROUND_SIZE) {\n    BACKGROUND_SIZE[\"AUTO\"] = \"auto\";\n    BACKGROUND_SIZE[\"CONTAIN\"] = \"contain\";\n    BACKGROUND_SIZE[\"COVER\"] = \"cover\";\n})(BACKGROUND_SIZE || (BACKGROUND_SIZE = {}));\nvar backgroundSize = {\n    name: 'background-size',\n    initialValue: '0',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        return parseFunctionArgs(tokens).map(function (values) { return values.filter(isBackgroundSizeInfoToken); });\n    }\n};\nvar isBackgroundSizeInfoToken = function (value) {\n    return isIdentToken(value) || isLengthPercentage(value);\n};\n\nvar borderColorForSide = function (side) { return ({\n    name: \"border-\" + side + \"-color\",\n    initialValue: 'transparent',\n    prefix: false,\n    type: 3 /* TYPE_VALUE */,\n    format: 'color'\n}); };\nvar borderTopColor = borderColorForSide('top');\nvar borderRightColor = borderColorForSide('right');\nvar borderBottomColor = borderColorForSide('bottom');\nvar borderLeftColor = borderColorForSide('left');\n\nvar borderRadiusForSide = function (side) { return ({\n    name: \"border-radius-\" + side,\n    initialValue: '0 0',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        return parseLengthPercentageTuple(tokens.filter(isLengthPercentage));\n    }\n}); };\nvar borderTopLeftRadius = borderRadiusForSide('top-left');\nvar borderTopRightRadius = borderRadiusForSide('top-right');\nvar borderBottomRightRadius = borderRadiusForSide('bottom-right');\nvar borderBottomLeftRadius = borderRadiusForSide('bottom-left');\n\nvar borderStyleForSide = function (side) { return ({\n    name: \"border-\" + side + \"-style\",\n    initialValue: 'solid',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, style) {\n        switch (style) {\n            case 'none':\n                return 0 /* NONE */;\n            case 'dashed':\n                return 2 /* DASHED */;\n            case 'dotted':\n                return 3 /* DOTTED */;\n            case 'double':\n                return 4 /* DOUBLE */;\n        }\n        return 1 /* SOLID */;\n    }\n}); };\nvar borderTopStyle = borderStyleForSide('top');\nvar borderRightStyle = borderStyleForSide('right');\nvar borderBottomStyle = borderStyleForSide('bottom');\nvar borderLeftStyle = borderStyleForSide('left');\n\nvar borderWidthForSide = function (side) { return ({\n    name: \"border-\" + side + \"-width\",\n    initialValue: '0',\n    type: 0 /* VALUE */,\n    prefix: false,\n    parse: function (_context, token) {\n        if (isDimensionToken(token)) {\n            return token.number;\n        }\n        return 0;\n    }\n}); };\nvar borderTopWidth = borderWidthForSide('top');\nvar borderRightWidth = borderWidthForSide('right');\nvar borderBottomWidth = borderWidthForSide('bottom');\nvar borderLeftWidth = borderWidthForSide('left');\n\nvar color = {\n    name: \"color\",\n    initialValue: 'transparent',\n    prefix: false,\n    type: 3 /* TYPE_VALUE */,\n    format: 'color'\n};\n\nvar direction = {\n    name: 'direction',\n    initialValue: 'ltr',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, direction) {\n        switch (direction) {\n            case 'rtl':\n                return 1 /* RTL */;\n            case 'ltr':\n            default:\n                return 0 /* LTR */;\n        }\n    }\n};\n\nvar display = {\n    name: 'display',\n    initialValue: 'inline-block',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        return tokens.filter(isIdentToken).reduce(function (bit, token) {\n            return bit | parseDisplayValue(token.value);\n        }, 0 /* NONE */);\n    }\n};\nvar parseDisplayValue = function (display) {\n    switch (display) {\n        case 'block':\n        case '-webkit-box':\n            return 2 /* BLOCK */;\n        case 'inline':\n            return 4 /* INLINE */;\n        case 'run-in':\n            return 8 /* RUN_IN */;\n        case 'flow':\n            return 16 /* FLOW */;\n        case 'flow-root':\n            return 32 /* FLOW_ROOT */;\n        case 'table':\n            return 64 /* TABLE */;\n        case 'flex':\n        case '-webkit-flex':\n            return 128 /* FLEX */;\n        case 'grid':\n        case '-ms-grid':\n            return 256 /* GRID */;\n        case 'ruby':\n            return 512 /* RUBY */;\n        case 'subgrid':\n            return 1024 /* SUBGRID */;\n        case 'list-item':\n            return 2048 /* LIST_ITEM */;\n        case 'table-row-group':\n            return 4096 /* TABLE_ROW_GROUP */;\n        case 'table-header-group':\n            return 8192 /* TABLE_HEADER_GROUP */;\n        case 'table-footer-group':\n            return 16384 /* TABLE_FOOTER_GROUP */;\n        case 'table-row':\n            return 32768 /* TABLE_ROW */;\n        case 'table-cell':\n            return 65536 /* TABLE_CELL */;\n        case 'table-column-group':\n            return 131072 /* TABLE_COLUMN_GROUP */;\n        case 'table-column':\n            return 262144 /* TABLE_COLUMN */;\n        case 'table-caption':\n            return 524288 /* TABLE_CAPTION */;\n        case 'ruby-base':\n            return 1048576 /* RUBY_BASE */;\n        case 'ruby-text':\n            return 2097152 /* RUBY_TEXT */;\n        case 'ruby-base-container':\n            return 4194304 /* RUBY_BASE_CONTAINER */;\n        case 'ruby-text-container':\n            return 8388608 /* RUBY_TEXT_CONTAINER */;\n        case 'contents':\n            return 16777216 /* CONTENTS */;\n        case 'inline-block':\n            return 33554432 /* INLINE_BLOCK */;\n        case 'inline-list-item':\n            return 67108864 /* INLINE_LIST_ITEM */;\n        case 'inline-table':\n            return 134217728 /* INLINE_TABLE */;\n        case 'inline-flex':\n            return 268435456 /* INLINE_FLEX */;\n        case 'inline-grid':\n            return 536870912 /* INLINE_GRID */;\n    }\n    return 0 /* NONE */;\n};\n\nvar float = {\n    name: 'float',\n    initialValue: 'none',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, float) {\n        switch (float) {\n            case 'left':\n                return 1 /* LEFT */;\n            case 'right':\n                return 2 /* RIGHT */;\n            case 'inline-start':\n                return 3 /* INLINE_START */;\n            case 'inline-end':\n                return 4 /* INLINE_END */;\n        }\n        return 0 /* NONE */;\n    }\n};\n\nvar letterSpacing = {\n    name: 'letter-spacing',\n    initialValue: '0',\n    prefix: false,\n    type: 0 /* VALUE */,\n    parse: function (_context, token) {\n        if (token.type === 20 /* IDENT_TOKEN */ && token.value === 'normal') {\n            return 0;\n        }\n        if (token.type === 17 /* NUMBER_TOKEN */) {\n            return token.number;\n        }\n        if (token.type === 15 /* DIMENSION_TOKEN */) {\n            return token.number;\n        }\n        return 0;\n    }\n};\n\nvar LINE_BREAK;\n(function (LINE_BREAK) {\n    LINE_BREAK[\"NORMAL\"] = \"normal\";\n    LINE_BREAK[\"STRICT\"] = \"strict\";\n})(LINE_BREAK || (LINE_BREAK = {}));\nvar lineBreak = {\n    name: 'line-break',\n    initialValue: 'normal',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, lineBreak) {\n        switch (lineBreak) {\n            case 'strict':\n                return LINE_BREAK.STRICT;\n            case 'normal':\n            default:\n                return LINE_BREAK.NORMAL;\n        }\n    }\n};\n\nvar lineHeight = {\n    name: 'line-height',\n    initialValue: 'normal',\n    prefix: false,\n    type: 4 /* TOKEN_VALUE */\n};\nvar computeLineHeight = function (token, fontSize) {\n    if (isIdentToken(token) && token.value === 'normal') {\n        return 1.2 * fontSize;\n    }\n    else if (token.type === 17 /* NUMBER_TOKEN */) {\n        return fontSize * token.number;\n    }\n    else if (isLengthPercentage(token)) {\n        return getAbsoluteValue(token, fontSize);\n    }\n    return fontSize;\n};\n\nvar listStyleImage = {\n    name: 'list-style-image',\n    initialValue: 'none',\n    type: 0 /* VALUE */,\n    prefix: false,\n    parse: function (context, token) {\n        if (token.type === 20 /* IDENT_TOKEN */ && token.value === 'none') {\n            return null;\n        }\n        return image$1.parse(context, token);\n    }\n};\n\nvar listStylePosition = {\n    name: 'list-style-position',\n    initialValue: 'outside',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, position) {\n        switch (position) {\n            case 'inside':\n                return 0 /* INSIDE */;\n            case 'outside':\n            default:\n                return 1 /* OUTSIDE */;\n        }\n    }\n};\n\nvar listStyleType = {\n    name: 'list-style-type',\n    initialValue: 'none',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, type) {\n        switch (type) {\n            case 'disc':\n                return 0 /* DISC */;\n            case 'circle':\n                return 1 /* CIRCLE */;\n            case 'square':\n                return 2 /* SQUARE */;\n            case 'decimal':\n                return 3 /* DECIMAL */;\n            case 'cjk-decimal':\n                return 4 /* CJK_DECIMAL */;\n            case 'decimal-leading-zero':\n                return 5 /* DECIMAL_LEADING_ZERO */;\n            case 'lower-roman':\n                return 6 /* LOWER_ROMAN */;\n            case 'upper-roman':\n                return 7 /* UPPER_ROMAN */;\n            case 'lower-greek':\n                return 8 /* LOWER_GREEK */;\n            case 'lower-alpha':\n                return 9 /* LOWER_ALPHA */;\n            case 'upper-alpha':\n                return 10 /* UPPER_ALPHA */;\n            case 'arabic-indic':\n                return 11 /* ARABIC_INDIC */;\n            case 'armenian':\n                return 12 /* ARMENIAN */;\n            case 'bengali':\n                return 13 /* BENGALI */;\n            case 'cambodian':\n                return 14 /* CAMBODIAN */;\n            case 'cjk-earthly-branch':\n                return 15 /* CJK_EARTHLY_BRANCH */;\n            case 'cjk-heavenly-stem':\n                return 16 /* CJK_HEAVENLY_STEM */;\n            case 'cjk-ideographic':\n                return 17 /* CJK_IDEOGRAPHIC */;\n            case 'devanagari':\n                return 18 /* DEVANAGARI */;\n            case 'ethiopic-numeric':\n                return 19 /* ETHIOPIC_NUMERIC */;\n            case 'georgian':\n                return 20 /* GEORGIAN */;\n            case 'gujarati':\n                return 21 /* GUJARATI */;\n            case 'gurmukhi':\n                return 22 /* GURMUKHI */;\n            case 'hebrew':\n                return 22 /* HEBREW */;\n            case 'hiragana':\n                return 23 /* HIRAGANA */;\n            case 'hiragana-iroha':\n                return 24 /* HIRAGANA_IROHA */;\n            case 'japanese-formal':\n                return 25 /* JAPANESE_FORMAL */;\n            case 'japanese-informal':\n                return 26 /* JAPANESE_INFORMAL */;\n            case 'kannada':\n                return 27 /* KANNADA */;\n            case 'katakana':\n                return 28 /* KATAKANA */;\n            case 'katakana-iroha':\n                return 29 /* KATAKANA_IROHA */;\n            case 'khmer':\n                return 30 /* KHMER */;\n            case 'korean-hangul-formal':\n                return 31 /* KOREAN_HANGUL_FORMAL */;\n            case 'korean-hanja-formal':\n                return 32 /* KOREAN_HANJA_FORMAL */;\n            case 'korean-hanja-informal':\n                return 33 /* KOREAN_HANJA_INFORMAL */;\n            case 'lao':\n                return 34 /* LAO */;\n            case 'lower-armenian':\n                return 35 /* LOWER_ARMENIAN */;\n            case 'malayalam':\n                return 36 /* MALAYALAM */;\n            case 'mongolian':\n                return 37 /* MONGOLIAN */;\n            case 'myanmar':\n                return 38 /* MYANMAR */;\n            case 'oriya':\n                return 39 /* ORIYA */;\n            case 'persian':\n                return 40 /* PERSIAN */;\n            case 'simp-chinese-formal':\n                return 41 /* SIMP_CHINESE_FORMAL */;\n            case 'simp-chinese-informal':\n                return 42 /* SIMP_CHINESE_INFORMAL */;\n            case 'tamil':\n                return 43 /* TAMIL */;\n            case 'telugu':\n                return 44 /* TELUGU */;\n            case 'thai':\n                return 45 /* THAI */;\n            case 'tibetan':\n                return 46 /* TIBETAN */;\n            case 'trad-chinese-formal':\n                return 47 /* TRAD_CHINESE_FORMAL */;\n            case 'trad-chinese-informal':\n                return 48 /* TRAD_CHINESE_INFORMAL */;\n            case 'upper-armenian':\n                return 49 /* UPPER_ARMENIAN */;\n            case 'disclosure-open':\n                return 50 /* DISCLOSURE_OPEN */;\n            case 'disclosure-closed':\n                return 51 /* DISCLOSURE_CLOSED */;\n            case 'none':\n            default:\n                return -1 /* NONE */;\n        }\n    }\n};\n\nvar marginForSide = function (side) { return ({\n    name: \"margin-\" + side,\n    initialValue: '0',\n    prefix: false,\n    type: 4 /* TOKEN_VALUE */\n}); };\nvar marginTop = marginForSide('top');\nvar marginRight = marginForSide('right');\nvar marginBottom = marginForSide('bottom');\nvar marginLeft = marginForSide('left');\n\nvar overflow = {\n    name: 'overflow',\n    initialValue: 'visible',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        return tokens.filter(isIdentToken).map(function (overflow) {\n            switch (overflow.value) {\n                case 'hidden':\n                    return 1 /* HIDDEN */;\n                case 'scroll':\n                    return 2 /* SCROLL */;\n                case 'clip':\n                    return 3 /* CLIP */;\n                case 'auto':\n                    return 4 /* AUTO */;\n                case 'visible':\n                default:\n                    return 0 /* VISIBLE */;\n            }\n        });\n    }\n};\n\nvar overflowWrap = {\n    name: 'overflow-wrap',\n    initialValue: 'normal',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, overflow) {\n        switch (overflow) {\n            case 'break-word':\n                return \"break-word\" /* BREAK_WORD */;\n            case 'normal':\n            default:\n                return \"normal\" /* NORMAL */;\n        }\n    }\n};\n\nvar paddingForSide = function (side) { return ({\n    name: \"padding-\" + side,\n    initialValue: '0',\n    prefix: false,\n    type: 3 /* TYPE_VALUE */,\n    format: 'length-percentage'\n}); };\nvar paddingTop = paddingForSide('top');\nvar paddingRight = paddingForSide('right');\nvar paddingBottom = paddingForSide('bottom');\nvar paddingLeft = paddingForSide('left');\n\nvar textAlign = {\n    name: 'text-align',\n    initialValue: 'left',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, textAlign) {\n        switch (textAlign) {\n            case 'right':\n                return 2 /* RIGHT */;\n            case 'center':\n            case 'justify':\n                return 1 /* CENTER */;\n            case 'left':\n            default:\n                return 0 /* LEFT */;\n        }\n    }\n};\n\nvar position = {\n    name: 'position',\n    initialValue: 'static',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, position) {\n        switch (position) {\n            case 'relative':\n                return 1 /* RELATIVE */;\n            case 'absolute':\n                return 2 /* ABSOLUTE */;\n            case 'fixed':\n                return 3 /* FIXED */;\n            case 'sticky':\n                return 4 /* STICKY */;\n        }\n        return 0 /* STATIC */;\n    }\n};\n\nvar textShadow = {\n    name: 'text-shadow',\n    initialValue: 'none',\n    type: 1 /* LIST */,\n    prefix: false,\n    parse: function (context, tokens) {\n        if (tokens.length === 1 && isIdentWithValue(tokens[0], 'none')) {\n            return [];\n        }\n        return parseFunctionArgs(tokens).map(function (values) {\n            var shadow = {\n                color: COLORS.TRANSPARENT,\n                offsetX: ZERO_LENGTH,\n                offsetY: ZERO_LENGTH,\n                blur: ZERO_LENGTH\n            };\n            var c = 0;\n            for (var i = 0; i < values.length; i++) {\n                var token = values[i];\n                if (isLength(token)) {\n                    if (c === 0) {\n                        shadow.offsetX = token;\n                    }\n                    else if (c === 1) {\n                        shadow.offsetY = token;\n                    }\n                    else {\n                        shadow.blur = token;\n                    }\n                    c++;\n                }\n                else {\n                    shadow.color = color$1.parse(context, token);\n                }\n            }\n            return shadow;\n        });\n    }\n};\n\nvar textTransform = {\n    name: 'text-transform',\n    initialValue: 'none',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, textTransform) {\n        switch (textTransform) {\n            case 'uppercase':\n                return 2 /* UPPERCASE */;\n            case 'lowercase':\n                return 1 /* LOWERCASE */;\n            case 'capitalize':\n                return 3 /* CAPITALIZE */;\n        }\n        return 0 /* NONE */;\n    }\n};\n\nvar transform$1 = {\n    name: 'transform',\n    initialValue: 'none',\n    prefix: true,\n    type: 0 /* VALUE */,\n    parse: function (_context, token) {\n        if (token.type === 20 /* IDENT_TOKEN */ && token.value === 'none') {\n            return null;\n        }\n        if (token.type === 18 /* FUNCTION */) {\n            var transformFunction = SUPPORTED_TRANSFORM_FUNCTIONS[token.name];\n            if (typeof transformFunction === 'undefined') {\n                throw new Error(\"Attempting to parse an unsupported transform function \\\"\" + token.name + \"\\\"\");\n            }\n            return transformFunction(token.values);\n        }\n        return null;\n    }\n};\nvar matrix = function (args) {\n    var values = args.filter(function (arg) { return arg.type === 17 /* NUMBER_TOKEN */; }).map(function (arg) { return arg.number; });\n    return values.length === 6 ? values : null;\n};\n// doesn't support 3D transforms at the moment\nvar matrix3d = function (args) {\n    var values = args.filter(function (arg) { return arg.type === 17 /* NUMBER_TOKEN */; }).map(function (arg) { return arg.number; });\n    var a1 = values[0], b1 = values[1]; values[2]; values[3]; var a2 = values[4], b2 = values[5]; values[6]; values[7]; values[8]; values[9]; values[10]; values[11]; var a4 = values[12], b4 = values[13]; values[14]; values[15];\n    return values.length === 16 ? [a1, b1, a2, b2, a4, b4] : null;\n};\nvar SUPPORTED_TRANSFORM_FUNCTIONS = {\n    matrix: matrix,\n    matrix3d: matrix3d\n};\n\nvar DEFAULT_VALUE = {\n    type: 16 /* PERCENTAGE_TOKEN */,\n    number: 50,\n    flags: FLAG_INTEGER\n};\nvar DEFAULT = [DEFAULT_VALUE, DEFAULT_VALUE];\nvar transformOrigin = {\n    name: 'transform-origin',\n    initialValue: '50% 50%',\n    prefix: true,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        var origins = tokens.filter(isLengthPercentage);\n        if (origins.length !== 2) {\n            return DEFAULT;\n        }\n        return [origins[0], origins[1]];\n    }\n};\n\nvar visibility = {\n    name: 'visible',\n    initialValue: 'none',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, visibility) {\n        switch (visibility) {\n            case 'hidden':\n                return 1 /* HIDDEN */;\n            case 'collapse':\n                return 2 /* COLLAPSE */;\n            case 'visible':\n            default:\n                return 0 /* VISIBLE */;\n        }\n    }\n};\n\nvar WORD_BREAK;\n(function (WORD_BREAK) {\n    WORD_BREAK[\"NORMAL\"] = \"normal\";\n    WORD_BREAK[\"BREAK_ALL\"] = \"break-all\";\n    WORD_BREAK[\"KEEP_ALL\"] = \"keep-all\";\n})(WORD_BREAK || (WORD_BREAK = {}));\nvar wordBreak = {\n    name: 'word-break',\n    initialValue: 'normal',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, wordBreak) {\n        switch (wordBreak) {\n            case 'break-all':\n                return WORD_BREAK.BREAK_ALL;\n            case 'keep-all':\n                return WORD_BREAK.KEEP_ALL;\n            case 'normal':\n            default:\n                return WORD_BREAK.NORMAL;\n        }\n    }\n};\n\nvar zIndex = {\n    name: 'z-index',\n    initialValue: 'auto',\n    prefix: false,\n    type: 0 /* VALUE */,\n    parse: function (_context, token) {\n        if (token.type === 20 /* IDENT_TOKEN */) {\n            return { auto: true, order: 0 };\n        }\n        if (isNumberToken(token)) {\n            return { auto: false, order: token.number };\n        }\n        throw new Error(\"Invalid z-index number parsed\");\n    }\n};\n\nvar time = {\n    name: 'time',\n    parse: function (_context, value) {\n        if (value.type === 15 /* DIMENSION_TOKEN */) {\n            switch (value.unit.toLowerCase()) {\n                case 's':\n                    return 1000 * value.number;\n                case 'ms':\n                    return value.number;\n            }\n        }\n        throw new Error(\"Unsupported time type\");\n    }\n};\n\nvar opacity = {\n    name: 'opacity',\n    initialValue: '1',\n    type: 0 /* VALUE */,\n    prefix: false,\n    parse: function (_context, token) {\n        if (isNumberToken(token)) {\n            return token.number;\n        }\n        return 1;\n    }\n};\n\nvar textDecorationColor = {\n    name: \"text-decoration-color\",\n    initialValue: 'transparent',\n    prefix: false,\n    type: 3 /* TYPE_VALUE */,\n    format: 'color'\n};\n\nvar textDecorationLine = {\n    name: 'text-decoration-line',\n    initialValue: 'none',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        return tokens\n            .filter(isIdentToken)\n            .map(function (token) {\n            switch (token.value) {\n                case 'underline':\n                    return 1 /* UNDERLINE */;\n                case 'overline':\n                    return 2 /* OVERLINE */;\n                case 'line-through':\n                    return 3 /* LINE_THROUGH */;\n                case 'none':\n                    return 4 /* BLINK */;\n            }\n            return 0 /* NONE */;\n        })\n            .filter(function (line) { return line !== 0 /* NONE */; });\n    }\n};\n\nvar fontFamily = {\n    name: \"font-family\",\n    initialValue: '',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        var accumulator = [];\n        var results = [];\n        tokens.forEach(function (token) {\n            switch (token.type) {\n                case 20 /* IDENT_TOKEN */:\n                case 0 /* STRING_TOKEN */:\n                    accumulator.push(token.value);\n                    break;\n                case 17 /* NUMBER_TOKEN */:\n                    accumulator.push(token.number.toString());\n                    break;\n                case 4 /* COMMA_TOKEN */:\n                    results.push(accumulator.join(' '));\n                    accumulator.length = 0;\n                    break;\n            }\n        });\n        if (accumulator.length) {\n            results.push(accumulator.join(' '));\n        }\n        return results.map(function (result) { return (result.indexOf(' ') === -1 ? result : \"'\" + result + \"'\"); });\n    }\n};\n\nvar fontSize = {\n    name: \"font-size\",\n    initialValue: '0',\n    prefix: false,\n    type: 3 /* TYPE_VALUE */,\n    format: 'length'\n};\n\nvar fontWeight = {\n    name: 'font-weight',\n    initialValue: 'normal',\n    type: 0 /* VALUE */,\n    prefix: false,\n    parse: function (_context, token) {\n        if (isNumberToken(token)) {\n            return token.number;\n        }\n        if (isIdentToken(token)) {\n            switch (token.value) {\n                case 'bold':\n                    return 700;\n                case 'normal':\n                default:\n                    return 400;\n            }\n        }\n        return 400;\n    }\n};\n\nvar fontVariant = {\n    name: 'font-variant',\n    initialValue: 'none',\n    type: 1 /* LIST */,\n    prefix: false,\n    parse: function (_context, tokens) {\n        return tokens.filter(isIdentToken).map(function (token) { return token.value; });\n    }\n};\n\nvar fontStyle = {\n    name: 'font-style',\n    initialValue: 'normal',\n    prefix: false,\n    type: 2 /* IDENT_VALUE */,\n    parse: function (_context, overflow) {\n        switch (overflow) {\n            case 'oblique':\n                return \"oblique\" /* OBLIQUE */;\n            case 'italic':\n                return \"italic\" /* ITALIC */;\n            case 'normal':\n            default:\n                return \"normal\" /* NORMAL */;\n        }\n    }\n};\n\nvar contains = function (bit, value) { return (bit & value) !== 0; };\n\nvar content = {\n    name: 'content',\n    initialValue: 'none',\n    type: 1 /* LIST */,\n    prefix: false,\n    parse: function (_context, tokens) {\n        if (tokens.length === 0) {\n            return [];\n        }\n        var first = tokens[0];\n        if (first.type === 20 /* IDENT_TOKEN */ && first.value === 'none') {\n            return [];\n        }\n        return tokens;\n    }\n};\n\nvar counterIncrement = {\n    name: 'counter-increment',\n    initialValue: 'none',\n    prefix: true,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        if (tokens.length === 0) {\n            return null;\n        }\n        var first = tokens[0];\n        if (first.type === 20 /* IDENT_TOKEN */ && first.value === 'none') {\n            return null;\n        }\n        var increments = [];\n        var filtered = tokens.filter(nonWhiteSpace);\n        for (var i = 0; i < filtered.length; i++) {\n            var counter = filtered[i];\n            var next = filtered[i + 1];\n            if (counter.type === 20 /* IDENT_TOKEN */) {\n                var increment = next && isNumberToken(next) ? next.number : 1;\n                increments.push({ counter: counter.value, increment: increment });\n            }\n        }\n        return increments;\n    }\n};\n\nvar counterReset = {\n    name: 'counter-reset',\n    initialValue: 'none',\n    prefix: true,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        if (tokens.length === 0) {\n            return [];\n        }\n        var resets = [];\n        var filtered = tokens.filter(nonWhiteSpace);\n        for (var i = 0; i < filtered.length; i++) {\n            var counter = filtered[i];\n            var next = filtered[i + 1];\n            if (isIdentToken(counter) && counter.value !== 'none') {\n                var reset = next && isNumberToken(next) ? next.number : 0;\n                resets.push({ counter: counter.value, reset: reset });\n            }\n        }\n        return resets;\n    }\n};\n\nvar duration = {\n    name: 'duration',\n    initialValue: '0s',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (context, tokens) {\n        return tokens.filter(isDimensionToken).map(function (token) { return time.parse(context, token); });\n    }\n};\n\nvar quotes = {\n    name: 'quotes',\n    initialValue: 'none',\n    prefix: true,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        if (tokens.length === 0) {\n            return null;\n        }\n        var first = tokens[0];\n        if (first.type === 20 /* IDENT_TOKEN */ && first.value === 'none') {\n            return null;\n        }\n        var quotes = [];\n        var filtered = tokens.filter(isStringToken);\n        if (filtered.length % 2 !== 0) {\n            return null;\n        }\n        for (var i = 0; i < filtered.length; i += 2) {\n            var open_1 = filtered[i].value;\n            var close_1 = filtered[i + 1].value;\n            quotes.push({ open: open_1, close: close_1 });\n        }\n        return quotes;\n    }\n};\nvar getQuote = function (quotes, depth, open) {\n    if (!quotes) {\n        return '';\n    }\n    var quote = quotes[Math.min(depth, quotes.length - 1)];\n    if (!quote) {\n        return '';\n    }\n    return open ? quote.open : quote.close;\n};\n\nvar boxShadow = {\n    name: 'box-shadow',\n    initialValue: 'none',\n    type: 1 /* LIST */,\n    prefix: false,\n    parse: function (context, tokens) {\n        if (tokens.length === 1 && isIdentWithValue(tokens[0], 'none')) {\n            return [];\n        }\n        return parseFunctionArgs(tokens).map(function (values) {\n            var shadow = {\n                color: 0x000000ff,\n                offsetX: ZERO_LENGTH,\n                offsetY: ZERO_LENGTH,\n                blur: ZERO_LENGTH,\n                spread: ZERO_LENGTH,\n                inset: false\n            };\n            var c = 0;\n            for (var i = 0; i < values.length; i++) {\n                var token = values[i];\n                if (isIdentWithValue(token, 'inset')) {\n                    shadow.inset = true;\n                }\n                else if (isLength(token)) {\n                    if (c === 0) {\n                        shadow.offsetX = token;\n                    }\n                    else if (c === 1) {\n                        shadow.offsetY = token;\n                    }\n                    else if (c === 2) {\n                        shadow.blur = token;\n                    }\n                    else {\n                        shadow.spread = token;\n                    }\n                    c++;\n                }\n                else {\n                    shadow.color = color$1.parse(context, token);\n                }\n            }\n            return shadow;\n        });\n    }\n};\n\nvar paintOrder = {\n    name: 'paint-order',\n    initialValue: 'normal',\n    prefix: false,\n    type: 1 /* LIST */,\n    parse: function (_context, tokens) {\n        var DEFAULT_VALUE = [0 /* FILL */, 1 /* STROKE */, 2 /* MARKERS */];\n        var layers = [];\n        tokens.filter(isIdentToken).forEach(function (token) {\n            switch (token.value) {\n                case 'stroke':\n                    layers.push(1 /* STROKE */);\n                    break;\n                case 'fill':\n                    layers.push(0 /* FILL */);\n                    break;\n                case 'markers':\n                    layers.push(2 /* MARKERS */);\n                    break;\n            }\n        });\n        DEFAULT_VALUE.forEach(function (value) {\n            if (layers.indexOf(value) === -1) {\n                layers.push(value);\n            }\n        });\n        return layers;\n    }\n};\n\nvar webkitTextStrokeColor = {\n    name: \"-webkit-text-stroke-color\",\n    initialValue: 'currentcolor',\n    prefix: false,\n    type: 3 /* TYPE_VALUE */,\n    format: 'color'\n};\n\nvar webkitTextStrokeWidth = {\n    name: \"-webkit-text-stroke-width\",\n    initialValue: '0',\n    type: 0 /* VALUE */,\n    prefix: false,\n    parse: function (_context, token) {\n        if (isDimensionToken(token)) {\n            return token.number;\n        }\n        return 0;\n    }\n};\n\nvar CSSParsedDeclaration = /** @class */ (function () {\n    function CSSParsedDeclaration(context, declaration) {\n        var _a, _b;\n        this.animationDuration = parse$1(context, duration, declaration.animationDuration);\n        this.backgroundClip = parse$1(context, backgroundClip, declaration.backgroundClip);\n        this.backgroundColor = parse$1(context, backgroundColor, declaration.backgroundColor);\n        this.backgroundImage = parse$1(context, backgroundImage, declaration.backgroundImage);\n        this.backgroundOrigin = parse$1(context, backgroundOrigin, declaration.backgroundOrigin);\n        this.backgroundPosition = parse$1(context, backgroundPosition, declaration.backgroundPosition);\n        this.backgroundRepeat = parse$1(context, backgroundRepeat, declaration.backgroundRepeat);\n        this.backgroundSize = parse$1(context, backgroundSize, declaration.backgroundSize);\n        this.borderTopColor = parse$1(context, borderTopColor, declaration.borderTopColor);\n        this.borderRightColor = parse$1(context, borderRightColor, declaration.borderRightColor);\n        this.borderBottomColor = parse$1(context, borderBottomColor, declaration.borderBottomColor);\n        this.borderLeftColor = parse$1(context, borderLeftColor, declaration.borderLeftColor);\n        this.borderTopLeftRadius = parse$1(context, borderTopLeftRadius, declaration.borderTopLeftRadius);\n        this.borderTopRightRadius = parse$1(context, borderTopRightRadius, declaration.borderTopRightRadius);\n        this.borderBottomRightRadius = parse$1(context, borderBottomRightRadius, declaration.borderBottomRightRadius);\n        this.borderBottomLeftRadius = parse$1(context, borderBottomLeftRadius, declaration.borderBottomLeftRadius);\n        this.borderTopStyle = parse$1(context, borderTopStyle, declaration.borderTopStyle);\n        this.borderRightStyle = parse$1(context, borderRightStyle, declaration.borderRightStyle);\n        this.borderBottomStyle = parse$1(context, borderBottomStyle, declaration.borderBottomStyle);\n        this.borderLeftStyle = parse$1(context, borderLeftStyle, declaration.borderLeftStyle);\n        this.borderTopWidth = parse$1(context, borderTopWidth, declaration.borderTopWidth);\n        this.borderRightWidth = parse$1(context, borderRightWidth, declaration.borderRightWidth);\n        this.borderBottomWidth = parse$1(context, borderBottomWidth, declaration.borderBottomWidth);\n        this.borderLeftWidth = parse$1(context, borderLeftWidth, declaration.borderLeftWidth);\n        this.boxShadow = parse$1(context, boxShadow, declaration.boxShadow);\n        this.color = parse$1(context, color, declaration.color);\n        this.direction = parse$1(context, direction, declaration.direction);\n        this.display = parse$1(context, display, declaration.display);\n        this.float = parse$1(context, float, declaration.cssFloat);\n        this.fontFamily = parse$1(context, fontFamily, declaration.fontFamily);\n        this.fontSize = parse$1(context, fontSize, declaration.fontSize);\n        this.fontStyle = parse$1(context, fontStyle, declaration.fontStyle);\n        this.fontVariant = parse$1(context, fontVariant, declaration.fontVariant);\n        this.fontWeight = parse$1(context, fontWeight, declaration.fontWeight);\n        this.letterSpacing = parse$1(context, letterSpacing, declaration.letterSpacing);\n        this.lineBreak = parse$1(context, lineBreak, declaration.lineBreak);\n        this.lineHeight = parse$1(context, lineHeight, declaration.lineHeight);\n        this.listStyleImage = parse$1(context, listStyleImage, declaration.listStyleImage);\n        this.listStylePosition = parse$1(context, listStylePosition, declaration.listStylePosition);\n        this.listStyleType = parse$1(context, listStyleType, declaration.listStyleType);\n        this.marginTop = parse$1(context, marginTop, declaration.marginTop);\n        this.marginRight = parse$1(context, marginRight, declaration.marginRight);\n        this.marginBottom = parse$1(context, marginBottom, declaration.marginBottom);\n        this.marginLeft = parse$1(context, marginLeft, declaration.marginLeft);\n        this.opacity = parse$1(context, opacity, declaration.opacity);\n        var overflowTuple = parse$1(context, overflow, declaration.overflow);\n        this.overflowX = overflowTuple[0];\n        this.overflowY = overflowTuple[overflowTuple.length > 1 ? 1 : 0];\n        this.overflowWrap = parse$1(context, overflowWrap, declaration.overflowWrap);\n        this.paddingTop = parse$1(context, paddingTop, declaration.paddingTop);\n        this.paddingRight = parse$1(context, paddingRight, declaration.paddingRight);\n        this.paddingBottom = parse$1(context, paddingBottom, declaration.paddingBottom);\n        this.paddingLeft = parse$1(context, paddingLeft, declaration.paddingLeft);\n        this.paintOrder = parse$1(context, paintOrder, declaration.paintOrder);\n        this.position = parse$1(context, position, declaration.position);\n        this.textAlign = parse$1(context, textAlign, declaration.textAlign);\n        this.textDecorationColor = parse$1(context, textDecorationColor, (_a = declaration.textDecorationColor) !== null && _a !== void 0 ? _a : declaration.color);\n        this.textDecorationLine = parse$1(context, textDecorationLine, (_b = declaration.textDecorationLine) !== null && _b !== void 0 ? _b : declaration.textDecoration);\n        this.textShadow = parse$1(context, textShadow, declaration.textShadow);\n        this.textTransform = parse$1(context, textTransform, declaration.textTransform);\n        this.transform = parse$1(context, transform$1, declaration.transform);\n        this.transformOrigin = parse$1(context, transformOrigin, declaration.transformOrigin);\n        this.visibility = parse$1(context, visibility, declaration.visibility);\n        this.webkitTextStrokeColor = parse$1(context, webkitTextStrokeColor, declaration.webkitTextStrokeColor);\n        this.webkitTextStrokeWidth = parse$1(context, webkitTextStrokeWidth, declaration.webkitTextStrokeWidth);\n        this.wordBreak = parse$1(context, wordBreak, declaration.wordBreak);\n        this.zIndex = parse$1(context, zIndex, declaration.zIndex);\n    }\n    CSSParsedDeclaration.prototype.isVisible = function () {\n        return this.display > 0 && this.opacity > 0 && this.visibility === 0 /* VISIBLE */;\n    };\n    CSSParsedDeclaration.prototype.isTransparent = function () {\n        return isTransparent(this.backgroundColor);\n    };\n    CSSParsedDeclaration.prototype.isTransformed = function () {\n        return this.transform !== null;\n    };\n    CSSParsedDeclaration.prototype.isPositioned = function () {\n        return this.position !== 0 /* STATIC */;\n    };\n    CSSParsedDeclaration.prototype.isPositionedWithZIndex = function () {\n        return this.isPositioned() && !this.zIndex.auto;\n    };\n    CSSParsedDeclaration.prototype.isFloating = function () {\n        return this.float !== 0 /* NONE */;\n    };\n    CSSParsedDeclaration.prototype.isInlineLevel = function () {\n        return (contains(this.display, 4 /* INLINE */) ||\n            contains(this.display, 33554432 /* INLINE_BLOCK */) ||\n            contains(this.display, 268435456 /* INLINE_FLEX */) ||\n            contains(this.display, 536870912 /* INLINE_GRID */) ||\n            contains(this.display, 67108864 /* INLINE_LIST_ITEM */) ||\n            contains(this.display, 134217728 /* INLINE_TABLE */));\n    };\n    return CSSParsedDeclaration;\n}());\nvar CSSParsedPseudoDeclaration = /** @class */ (function () {\n    function CSSParsedPseudoDeclaration(context, declaration) {\n        this.content = parse$1(context, content, declaration.content);\n        this.quotes = parse$1(context, quotes, declaration.quotes);\n    }\n    return CSSParsedPseudoDeclaration;\n}());\nvar CSSParsedCounterDeclaration = /** @class */ (function () {\n    function CSSParsedCounterDeclaration(context, declaration) {\n        this.counterIncrement = parse$1(context, counterIncrement, declaration.counterIncrement);\n        this.counterReset = parse$1(context, counterReset, declaration.counterReset);\n    }\n    return CSSParsedCounterDeclaration;\n}());\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nvar parse$1 = function (context, descriptor, style) {\n    var tokenizer = new Tokenizer();\n    var value = style !== null && typeof style !== 'undefined' ? style.toString() : descriptor.initialValue;\n    tokenizer.write(value);\n    var parser = new Parser(tokenizer.read());\n    switch (descriptor.type) {\n        case 2 /* IDENT_VALUE */:\n            var token = parser.parseComponentValue();\n            return descriptor.parse(context, isIdentToken(token) ? token.value : descriptor.initialValue);\n        case 0 /* VALUE */:\n            return descriptor.parse(context, parser.parseComponentValue());\n        case 1 /* LIST */:\n            return descriptor.parse(context, parser.parseComponentValues());\n        case 4 /* TOKEN_VALUE */:\n            return parser.parseComponentValue();\n        case 3 /* TYPE_VALUE */:\n            switch (descriptor.format) {\n                case 'angle':\n                    return angle.parse(context, parser.parseComponentValue());\n                case 'color':\n                    return color$1.parse(context, parser.parseComponentValue());\n                case 'image':\n                    return image$1.parse(context, parser.parseComponentValue());\n                case 'length':\n                    var length_1 = parser.parseComponentValue();\n                    return isLength(length_1) ? length_1 : ZERO_LENGTH;\n                case 'length-percentage':\n                    var value_1 = parser.parseComponentValue();\n                    return isLengthPercentage(value_1) ? value_1 : ZERO_LENGTH;\n                case 'time':\n                    return time.parse(context, parser.parseComponentValue());\n            }\n            break;\n    }\n};\n\nvar elementDebuggerAttribute = 'data-html2canvas-debug';\nvar getElementDebugType = function (element) {\n    var attribute = element.getAttribute(elementDebuggerAttribute);\n    switch (attribute) {\n        case 'all':\n            return 1 /* ALL */;\n        case 'clone':\n            return 2 /* CLONE */;\n        case 'parse':\n            return 3 /* PARSE */;\n        case 'render':\n            return 4 /* RENDER */;\n        default:\n            return 0 /* NONE */;\n    }\n};\nvar isDebugging = function (element, type) {\n    var elementType = getElementDebugType(element);\n    return elementType === 1 /* ALL */ || type === elementType;\n};\n\nvar ElementContainer = /** @class */ (function () {\n    function ElementContainer(context, element) {\n        this.context = context;\n        this.textNodes = [];\n        this.elements = [];\n        this.flags = 0;\n        if (isDebugging(element, 3 /* PARSE */)) {\n            debugger;\n        }\n        this.styles = new CSSParsedDeclaration(context, window.getComputedStyle(element, null));\n        if (isHTMLElementNode(element)) {\n            if (this.styles.animationDuration.some(function (duration) { return duration > 0; })) {\n                element.style.animationDuration = '0s';\n            }\n            if (this.styles.transform !== null) {\n                // getBoundingClientRect takes transforms into account\n                element.style.transform = 'none';\n            }\n        }\n        this.bounds = parseBounds(this.context, element);\n        if (isDebugging(element, 4 /* RENDER */)) {\n            this.flags |= 16 /* DEBUG_RENDER */;\n        }\n    }\n    return ElementContainer;\n}());\n\n/*\n * text-segmentation 1.0.3 <https://github.com/niklasvh/text-segmentation>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar base64 = 'AAAAAAAAAAAAEA4AGBkAAFAaAAACAAAAAAAIABAAGAAwADgACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAAQABIAEQATAAIABAACAAQAAgAEAAIABAAVABcAAgAEAAIABAACAAQAGAAaABwAHgAgACIAI4AlgAIABAAmwCjAKgAsAC2AL4AvQDFAMoA0gBPAVYBWgEIAAgACACMANoAYgFkAWwBdAF8AX0BhQGNAZUBlgGeAaMBlQGWAasBswF8AbsBwwF0AcsBYwHTAQgA2wG/AOMBdAF8AekB8QF0AfkB+wHiAHQBfAEIAAMC5gQIAAsCEgIIAAgAFgIeAggAIgIpAggAMQI5AkACygEIAAgASAJQAlgCYAIIAAgACAAKBQoFCgUTBRMFGQUrBSsFCAAIAAgACAAIAAgACAAIAAgACABdAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABoAmgCrwGvAQgAbgJ2AggAHgEIAAgACADnAXsCCAAIAAgAgwIIAAgACAAIAAgACACKAggAkQKZAggAPADJAAgAoQKkAqwCsgK6AsICCADJAggA0AIIAAgACAAIANYC3gIIAAgACAAIAAgACABAAOYCCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAkASoB+QIEAAgACAA8AEMCCABCBQgACABJBVAFCAAIAAgACAAIAAgACAAIAAgACABTBVoFCAAIAFoFCABfBWUFCAAIAAgACAAIAAgAbQUIAAgACAAIAAgACABzBXsFfQWFBYoFigWKBZEFigWKBYoFmAWfBaYFrgWxBbkFCAAIAAgACAAIAAgACAAIAAgACAAIAMEFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAMgFCADQBQgACAAIAAgACAAIAAgACAAIAAgACAAIAO4CCAAIAAgAiQAIAAgACABAAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAD0AggACAD8AggACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIANYFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAMDvwAIAAgAJAIIAAgACAAIAAgACAAIAAgACwMTAwgACAB9BOsEGwMjAwgAKwMyAwsFYgE3A/MEPwMIAEUDTQNRAwgAWQOsAGEDCAAIAAgACAAIAAgACABpAzQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFIQUoBSwFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABtAwgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABMAEwACAAIAAgACAAIABgACAAIAAgACAC/AAgACAAyAQgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACAAIAAwAAgACAAIAAgACAAIAAgACAAIAAAARABIAAgACAAIABQASAAIAAgAIABwAEAAjgCIABsAqAC2AL0AigDQAtwC+IJIQqVAZUBWQqVAZUBlQGVAZUBlQGrC5UBlQGVAZUBlQGVAZUBlQGVAXsKlQGVAbAK6wsrDGUMpQzlDJUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAfAKAAuZA64AtwCJALoC6ADwAAgAuACgA/oEpgO6AqsD+AAIAAgAswMIAAgACAAIAIkAuwP5AfsBwwPLAwgACAAIAAgACADRA9kDCAAIAOED6QMIAAgACAAIAAgACADuA/YDCAAIAP4DyQAIAAgABgQIAAgAXQAOBAgACAAIAAgACAAIABMECAAIAAgACAAIAAgACAD8AAQBCAAIAAgAGgQiBCoECAExBAgAEAEIAAgACAAIAAgACAAIAAgACAAIAAgACAA4BAgACABABEYECAAIAAgATAQYAQgAVAQIAAgACAAIAAgACAAIAAgACAAIAFoECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAOQEIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAB+BAcACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAEABhgSMBAgACAAIAAgAlAQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAwAEAAQABAADAAMAAwADAAQABAAEAAQABAAEAAQABHATAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAdQMIAAgACAAIAAgACAAIAMkACAAIAAgAfQMIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACFA4kDCAAIAAgACAAIAOcBCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAIcDCAAIAAgACAAIAAgACAAIAAgACAAIAJEDCAAIAAgACADFAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABgBAgAZgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAbAQCBXIECAAIAHkECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABAAJwEQACjBKoEsgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAC6BMIECAAIAAgACAAIAAgACABmBAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAxwQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAGYECAAIAAgAzgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBd0FXwUIAOIF6gXxBYoF3gT5BQAGCAaKBYoFigWKBYoFigWKBYoFigWKBYoFigXWBIoFigWKBYoFigWKBYoFigWKBYsFEAaKBYoFigWKBYoFigWKBRQGCACKBYoFigWKBQgACAAIANEECAAIABgGigUgBggAJgYIAC4GMwaKBYoF0wQ3Bj4GigWKBYoFigWKBYoFigWKBYoFigWKBYoFigUIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWLBf///////wQABAAEAAQABAAEAAQABAAEAAQAAwAEAAQAAgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAQADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUAAAAFAAUAAAAFAAUAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAQAAAAUABQAFAAUABQAFAAAAAAAFAAUAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAFAAUAAQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAAABwAHAAcAAAAHAAcABwAFAAEAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAcABwAFAAUAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAQABAAAAAAAAAAAAAAAFAAUABQAFAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAHAAcAAAAHAAcAAAAAAAUABQAHAAUAAQAHAAEABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwABAAUABQAFAAUAAAAAAAAAAAAAAAEAAQABAAEAAQABAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABQANAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAABQAHAAUABQAFAAAAAAAAAAcABQAFAAUABQAFAAQABAAEAAQABAAEAAQABAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUAAAAFAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAUAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAcABwAFAAcABwAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUABwAHAAUABQAFAAUAAAAAAAcABwAAAAAABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAAAAAAAAAAABQAFAAAAAAAFAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAFAAUABQAFAAUAAAAFAAUABwAAAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABwAFAAUABQAFAAAAAAAHAAcAAAAAAAcABwAFAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAAAAAAAAAHAAcABwAAAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAUABQAFAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAHAAcABQAHAAcAAAAFAAcABwAAAAcABwAFAAUAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAFAAcABwAFAAUABQAAAAUAAAAHAAcABwAHAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAHAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUAAAAFAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAUAAAAFAAUAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABwAFAAUABQAFAAUABQAAAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABQAFAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAFAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAHAAUABQAFAAUABQAFAAUABwAHAAcABwAHAAcABwAHAAUABwAHAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABwAHAAcABwAFAAUABwAHAAcAAAAAAAAAAAAHAAcABQAHAAcABwAHAAcABwAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAUABQAFAAUABQAFAAUAAAAFAAAABQAAAAAABQAFAAUABQAFAAUABQAFAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAUABQAFAAUABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABwAFAAcABwAHAAcABwAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAUABQAFAAUABwAHAAUABQAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABQAFAAcABwAHAAUABwAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAcABQAFAAUABQAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAAAAAABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAAAAAAAAAFAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAUABQAHAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAFAAUABQAFAAcABwAFAAUABwAHAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAcABwAFAAUABwAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABQAAAAAABQAFAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAcABwAAAAAAAAAAAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAcABwAFAAcABwAAAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAFAAUABQAAAAUABQAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABwAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAHAAcABQAHAAUABQAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAAABwAHAAAAAAAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAFAAUABwAFAAcABwAFAAcABQAFAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAAAAAABwAHAAcABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAFAAcABwAFAAUABQAFAAUABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAUABQAFAAcABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABQAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAAAAAAFAAUABwAHAAcABwAFAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAHAAUABQAFAAUABQAFAAUABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAABQAAAAUABQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAHAAcAAAAFAAUAAAAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABQAFAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAABQAFAAUABQAFAAUABQAAAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAFAAUABQAFAAUADgAOAA4ADgAOAA4ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAMAAwADAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAAAAAAAAAAAAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAAAAAAAAAAAAsADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwACwAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAADgAOAA4AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAAAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4AAAAOAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAAAAAAAAAAAA4AAAAOAAAAAAAAAAAADgAOAA4AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAA=';\n\n/*\n * utrie 1.0.2 <https://github.com/niklasvh/utrie>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar chars$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup$1 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i$1 = 0; i$1 < chars$1.length; i$1++) {\n    lookup$1[chars$1.charCodeAt(i$1)] = i$1;\n}\nvar decode = function (base64) {\n    var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;\n    if (base64[base64.length - 1] === '=') {\n        bufferLength--;\n        if (base64[base64.length - 2] === '=') {\n            bufferLength--;\n        }\n    }\n    var buffer = typeof ArrayBuffer !== 'undefined' &&\n        typeof Uint8Array !== 'undefined' &&\n        typeof Uint8Array.prototype.slice !== 'undefined'\n        ? new ArrayBuffer(bufferLength)\n        : new Array(bufferLength);\n    var bytes = Array.isArray(buffer) ? buffer : new Uint8Array(buffer);\n    for (i = 0; i < len; i += 4) {\n        encoded1 = lookup$1[base64.charCodeAt(i)];\n        encoded2 = lookup$1[base64.charCodeAt(i + 1)];\n        encoded3 = lookup$1[base64.charCodeAt(i + 2)];\n        encoded4 = lookup$1[base64.charCodeAt(i + 3)];\n        bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n        bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n        bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n    }\n    return buffer;\n};\nvar polyUint16Array = function (buffer) {\n    var length = buffer.length;\n    var bytes = [];\n    for (var i = 0; i < length; i += 2) {\n        bytes.push((buffer[i + 1] << 8) | buffer[i]);\n    }\n    return bytes;\n};\nvar polyUint32Array = function (buffer) {\n    var length = buffer.length;\n    var bytes = [];\n    for (var i = 0; i < length; i += 4) {\n        bytes.push((buffer[i + 3] << 24) | (buffer[i + 2] << 16) | (buffer[i + 1] << 8) | buffer[i]);\n    }\n    return bytes;\n};\n\n/** Shift size for getting the index-2 table offset. */\nvar UTRIE2_SHIFT_2 = 5;\n/** Shift size for getting the index-1 table offset. */\nvar UTRIE2_SHIFT_1 = 6 + 5;\n/**\n * Shift size for shifting left the index array values.\n * Increases possible data size with 16-bit index values at the cost\n * of compactability.\n * This requires data blocks to be aligned by UTRIE2_DATA_GRANULARITY.\n */\nvar UTRIE2_INDEX_SHIFT = 2;\n/**\n * Difference between the two shift sizes,\n * for getting an index-1 offset from an index-2 offset. 6=11-5\n */\nvar UTRIE2_SHIFT_1_2 = UTRIE2_SHIFT_1 - UTRIE2_SHIFT_2;\n/**\n * The part of the index-2 table for U+D800..U+DBFF stores values for\n * lead surrogate code _units_ not code _points_.\n * Values for lead surrogate code _points_ are indexed with this portion of the table.\n * Length=32=0x20=0x400>>UTRIE2_SHIFT_2. (There are 1024=0x400 lead surrogates.)\n */\nvar UTRIE2_LSCP_INDEX_2_OFFSET = 0x10000 >> UTRIE2_SHIFT_2;\n/** Number of entries in a data block. 32=0x20 */\nvar UTRIE2_DATA_BLOCK_LENGTH = 1 << UTRIE2_SHIFT_2;\n/** Mask for getting the lower bits for the in-data-block offset. */\nvar UTRIE2_DATA_MASK = UTRIE2_DATA_BLOCK_LENGTH - 1;\nvar UTRIE2_LSCP_INDEX_2_LENGTH = 0x400 >> UTRIE2_SHIFT_2;\n/** Count the lengths of both BMP pieces. 2080=0x820 */\nvar UTRIE2_INDEX_2_BMP_LENGTH = UTRIE2_LSCP_INDEX_2_OFFSET + UTRIE2_LSCP_INDEX_2_LENGTH;\n/**\n * The 2-byte UTF-8 version of the index-2 table follows at offset 2080=0x820.\n * Length 32=0x20 for lead bytes C0..DF, regardless of UTRIE2_SHIFT_2.\n */\nvar UTRIE2_UTF8_2B_INDEX_2_OFFSET = UTRIE2_INDEX_2_BMP_LENGTH;\nvar UTRIE2_UTF8_2B_INDEX_2_LENGTH = 0x800 >> 6; /* U+0800 is the first code point after 2-byte UTF-8 */\n/**\n * The index-1 table, only used for supplementary code points, at offset 2112=0x840.\n * Variable length, for code points up to highStart, where the last single-value range starts.\n * Maximum length 512=0x200=0x100000>>UTRIE2_SHIFT_1.\n * (For 0x100000 supplementary code points U+10000..U+10ffff.)\n *\n * The part of the index-2 table for supplementary code points starts\n * after this index-1 table.\n *\n * Both the index-1 table and the following part of the index-2 table\n * are omitted completely if there is only BMP data.\n */\nvar UTRIE2_INDEX_1_OFFSET = UTRIE2_UTF8_2B_INDEX_2_OFFSET + UTRIE2_UTF8_2B_INDEX_2_LENGTH;\n/**\n * Number of index-1 entries for the BMP. 32=0x20\n * This part of the index-1 table is omitted from the serialized form.\n */\nvar UTRIE2_OMITTED_BMP_INDEX_1_LENGTH = 0x10000 >> UTRIE2_SHIFT_1;\n/** Number of entries in an index-2 block. 64=0x40 */\nvar UTRIE2_INDEX_2_BLOCK_LENGTH = 1 << UTRIE2_SHIFT_1_2;\n/** Mask for getting the lower bits for the in-index-2-block offset. */\nvar UTRIE2_INDEX_2_MASK = UTRIE2_INDEX_2_BLOCK_LENGTH - 1;\nvar slice16 = function (view, start, end) {\n    if (view.slice) {\n        return view.slice(start, end);\n    }\n    return new Uint16Array(Array.prototype.slice.call(view, start, end));\n};\nvar slice32 = function (view, start, end) {\n    if (view.slice) {\n        return view.slice(start, end);\n    }\n    return new Uint32Array(Array.prototype.slice.call(view, start, end));\n};\nvar createTrieFromBase64 = function (base64, _byteLength) {\n    var buffer = decode(base64);\n    var view32 = Array.isArray(buffer) ? polyUint32Array(buffer) : new Uint32Array(buffer);\n    var view16 = Array.isArray(buffer) ? polyUint16Array(buffer) : new Uint16Array(buffer);\n    var headerLength = 24;\n    var index = slice16(view16, headerLength / 2, view32[4] / 2);\n    var data = view32[5] === 2\n        ? slice16(view16, (headerLength + view32[4]) / 2)\n        : slice32(view32, Math.ceil((headerLength + view32[4]) / 4));\n    return new Trie(view32[0], view32[1], view32[2], view32[3], index, data);\n};\nvar Trie = /** @class */ (function () {\n    function Trie(initialValue, errorValue, highStart, highValueIndex, index, data) {\n        this.initialValue = initialValue;\n        this.errorValue = errorValue;\n        this.highStart = highStart;\n        this.highValueIndex = highValueIndex;\n        this.index = index;\n        this.data = data;\n    }\n    /**\n     * Get the value for a code point as stored in the Trie.\n     *\n     * @param codePoint the code point\n     * @return the value\n     */\n    Trie.prototype.get = function (codePoint) {\n        var ix;\n        if (codePoint >= 0) {\n            if (codePoint < 0x0d800 || (codePoint > 0x0dbff && codePoint <= 0x0ffff)) {\n                // Ordinary BMP code point, excluding leading surrogates.\n                // BMP uses a single level lookup.  BMP index starts at offset 0 in the Trie2 index.\n                // 16 bit data is stored in the index array itself.\n                ix = this.index[codePoint >> UTRIE2_SHIFT_2];\n                ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);\n                return this.data[ix];\n            }\n            if (codePoint <= 0xffff) {\n                // Lead Surrogate Code Point.  A Separate index section is stored for\n                // lead surrogate code units and code points.\n                //   The main index has the code unit data.\n                //   For this function, we need the code point data.\n                // Note: this expression could be refactored for slightly improved efficiency, but\n                //       surrogate code points will be so rare in practice that it's not worth it.\n                ix = this.index[UTRIE2_LSCP_INDEX_2_OFFSET + ((codePoint - 0xd800) >> UTRIE2_SHIFT_2)];\n                ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);\n                return this.data[ix];\n            }\n            if (codePoint < this.highStart) {\n                // Supplemental code point, use two-level lookup.\n                ix = UTRIE2_INDEX_1_OFFSET - UTRIE2_OMITTED_BMP_INDEX_1_LENGTH + (codePoint >> UTRIE2_SHIFT_1);\n                ix = this.index[ix];\n                ix += (codePoint >> UTRIE2_SHIFT_2) & UTRIE2_INDEX_2_MASK;\n                ix = this.index[ix];\n                ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);\n                return this.data[ix];\n            }\n            if (codePoint <= 0x10ffff) {\n                return this.data[this.highValueIndex];\n            }\n        }\n        // Fall through.  The code point is outside of the legal range of 0..0x10ffff.\n        return this.errorValue;\n    };\n    return Trie;\n}());\n\n/*\n * base64-arraybuffer 1.0.2 <https://github.com/niklasvh/base64-arraybuffer>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i = 0; i < chars.length; i++) {\n    lookup[chars.charCodeAt(i)] = i;\n}\n\nvar Prepend = 1;\nvar CR = 2;\nvar LF = 3;\nvar Control = 4;\nvar Extend = 5;\nvar SpacingMark = 7;\nvar L = 8;\nvar V = 9;\nvar T = 10;\nvar LV = 11;\nvar LVT = 12;\nvar ZWJ = 13;\nvar Extended_Pictographic = 14;\nvar RI = 15;\nvar toCodePoints = function (str) {\n    var codePoints = [];\n    var i = 0;\n    var length = str.length;\n    while (i < length) {\n        var value = str.charCodeAt(i++);\n        if (value >= 0xd800 && value <= 0xdbff && i < length) {\n            var extra = str.charCodeAt(i++);\n            if ((extra & 0xfc00) === 0xdc00) {\n                codePoints.push(((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000);\n            }\n            else {\n                codePoints.push(value);\n                i--;\n            }\n        }\n        else {\n            codePoints.push(value);\n        }\n    }\n    return codePoints;\n};\nvar fromCodePoint = function () {\n    var codePoints = [];\n    for (var _i = 0; _i < arguments.length; _i++) {\n        codePoints[_i] = arguments[_i];\n    }\n    if (String.fromCodePoint) {\n        return String.fromCodePoint.apply(String, codePoints);\n    }\n    var length = codePoints.length;\n    if (!length) {\n        return '';\n    }\n    var codeUnits = [];\n    var index = -1;\n    var result = '';\n    while (++index < length) {\n        var codePoint = codePoints[index];\n        if (codePoint <= 0xffff) {\n            codeUnits.push(codePoint);\n        }\n        else {\n            codePoint -= 0x10000;\n            codeUnits.push((codePoint >> 10) + 0xd800, (codePoint % 0x400) + 0xdc00);\n        }\n        if (index + 1 === length || codeUnits.length > 0x4000) {\n            result += String.fromCharCode.apply(String, codeUnits);\n            codeUnits.length = 0;\n        }\n    }\n    return result;\n};\nvar UnicodeTrie = createTrieFromBase64(base64);\nvar BREAK_NOT_ALLOWED = '×';\nvar BREAK_ALLOWED = '÷';\nvar codePointToClass = function (codePoint) { return UnicodeTrie.get(codePoint); };\nvar _graphemeBreakAtIndex = function (_codePoints, classTypes, index) {\n    var prevIndex = index - 2;\n    var prev = classTypes[prevIndex];\n    var current = classTypes[index - 1];\n    var next = classTypes[index];\n    // GB3 Do not break between a CR and LF\n    if (current === CR && next === LF) {\n        return BREAK_NOT_ALLOWED;\n    }\n    // GB4 Otherwise, break before and after controls.\n    if (current === CR || current === LF || current === Control) {\n        return BREAK_ALLOWED;\n    }\n    // GB5\n    if (next === CR || next === LF || next === Control) {\n        return BREAK_ALLOWED;\n    }\n    // Do not break Hangul syllable sequences.\n    // GB6\n    if (current === L && [L, V, LV, LVT].indexOf(next) !== -1) {\n        return BREAK_NOT_ALLOWED;\n    }\n    // GB7\n    if ((current === LV || current === V) && (next === V || next === T)) {\n        return BREAK_NOT_ALLOWED;\n    }\n    // GB8\n    if ((current === LVT || current === T) && next === T) {\n        return BREAK_NOT_ALLOWED;\n    }\n    // GB9 Do not break before extending characters or ZWJ.\n    if (next === ZWJ || next === Extend) {\n        return BREAK_NOT_ALLOWED;\n    }\n    // Do not break before SpacingMarks, or after Prepend characters.\n    // GB9a\n    if (next === SpacingMark) {\n        return BREAK_NOT_ALLOWED;\n    }\n    // GB9a\n    if (current === Prepend) {\n        return BREAK_NOT_ALLOWED;\n    }\n    // GB11 Do not break within emoji modifier sequences or emoji zwj sequences.\n    if (current === ZWJ && next === Extended_Pictographic) {\n        while (prev === Extend) {\n            prev = classTypes[--prevIndex];\n        }\n        if (prev === Extended_Pictographic) {\n            return BREAK_NOT_ALLOWED;\n        }\n    }\n    // GB12 Do not break within emoji flag sequences.\n    // That is, do not break between regional indicator (RI) symbols\n    // if there is an odd number of RI characters before the break point.\n    if (current === RI && next === RI) {\n        var countRI = 0;\n        while (prev === RI) {\n            countRI++;\n            prev = classTypes[--prevIndex];\n        }\n        if (countRI % 2 === 0) {\n            return BREAK_NOT_ALLOWED;\n        }\n    }\n    return BREAK_ALLOWED;\n};\nvar GraphemeBreaker = function (str) {\n    var codePoints = toCodePoints(str);\n    var length = codePoints.length;\n    var index = 0;\n    var lastEnd = 0;\n    var classTypes = codePoints.map(codePointToClass);\n    return {\n        next: function () {\n            if (index >= length) {\n                return { done: true, value: null };\n            }\n            var graphemeBreak = BREAK_NOT_ALLOWED;\n            while (index < length &&\n                (graphemeBreak = _graphemeBreakAtIndex(codePoints, classTypes, ++index)) === BREAK_NOT_ALLOWED) { }\n            if (graphemeBreak !== BREAK_NOT_ALLOWED || index === length) {\n                var value = fromCodePoint.apply(null, codePoints.slice(lastEnd, index));\n                lastEnd = index;\n                return { value: value, done: false };\n            }\n            return { done: true, value: null };\n        },\n    };\n};\nvar splitGraphemes = function (str) {\n    var breaker = GraphemeBreaker(str);\n    var graphemes = [];\n    var bk;\n    while (!(bk = breaker.next()).done) {\n        if (bk.value) {\n            graphemes.push(bk.value.slice());\n        }\n    }\n    return graphemes;\n};\n\nvar testRangeBounds = function (document) {\n    var TEST_HEIGHT = 123;\n    if (document.createRange) {\n        var range = document.createRange();\n        if (range.getBoundingClientRect) {\n            var testElement = document.createElement('boundtest');\n            testElement.style.height = TEST_HEIGHT + \"px\";\n            testElement.style.display = 'block';\n            document.body.appendChild(testElement);\n            range.selectNode(testElement);\n            var rangeBounds = range.getBoundingClientRect();\n            var rangeHeight = Math.round(rangeBounds.height);\n            document.body.removeChild(testElement);\n            if (rangeHeight === TEST_HEIGHT) {\n                return true;\n            }\n        }\n    }\n    return false;\n};\nvar testIOSLineBreak = function (document) {\n    var testElement = document.createElement('boundtest');\n    testElement.style.width = '50px';\n    testElement.style.display = 'block';\n    testElement.style.fontSize = '12px';\n    testElement.style.letterSpacing = '0px';\n    testElement.style.wordSpacing = '0px';\n    document.body.appendChild(testElement);\n    var range = document.createRange();\n    testElement.innerHTML = typeof ''.repeat === 'function' ? '&#128104;'.repeat(10) : '';\n    var node = testElement.firstChild;\n    var textList = toCodePoints$1(node.data).map(function (i) { return fromCodePoint$1(i); });\n    var offset = 0;\n    var prev = {};\n    // ios 13 does not handle range getBoundingClientRect line changes correctly #2177\n    var supports = textList.every(function (text, i) {\n        range.setStart(node, offset);\n        range.setEnd(node, offset + text.length);\n        var rect = range.getBoundingClientRect();\n        offset += text.length;\n        var boundAhead = rect.x > prev.x || rect.y > prev.y;\n        prev = rect;\n        if (i === 0) {\n            return true;\n        }\n        return boundAhead;\n    });\n    document.body.removeChild(testElement);\n    return supports;\n};\nvar testCORS = function () { return typeof new Image().crossOrigin !== 'undefined'; };\nvar testResponseType = function () { return typeof new XMLHttpRequest().responseType === 'string'; };\nvar testSVG = function (document) {\n    var img = new Image();\n    var canvas = document.createElement('canvas');\n    var ctx = canvas.getContext('2d');\n    if (!ctx) {\n        return false;\n    }\n    img.src = \"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>\";\n    try {\n        ctx.drawImage(img, 0, 0);\n        canvas.toDataURL();\n    }\n    catch (e) {\n        return false;\n    }\n    return true;\n};\nvar isGreenPixel = function (data) {\n    return data[0] === 0 && data[1] === 255 && data[2] === 0 && data[3] === 255;\n};\nvar testForeignObject = function (document) {\n    var canvas = document.createElement('canvas');\n    var size = 100;\n    canvas.width = size;\n    canvas.height = size;\n    var ctx = canvas.getContext('2d');\n    if (!ctx) {\n        return Promise.reject(false);\n    }\n    ctx.fillStyle = 'rgb(0, 255, 0)';\n    ctx.fillRect(0, 0, size, size);\n    var img = new Image();\n    var greenImageSrc = canvas.toDataURL();\n    img.src = greenImageSrc;\n    var svg = createForeignObjectSVG(size, size, 0, 0, img);\n    ctx.fillStyle = 'red';\n    ctx.fillRect(0, 0, size, size);\n    return loadSerializedSVG$1(svg)\n        .then(function (img) {\n        ctx.drawImage(img, 0, 0);\n        var data = ctx.getImageData(0, 0, size, size).data;\n        ctx.fillStyle = 'red';\n        ctx.fillRect(0, 0, size, size);\n        var node = document.createElement('div');\n        node.style.backgroundImage = \"url(\" + greenImageSrc + \")\";\n        node.style.height = size + \"px\";\n        // Firefox 55 does not render inline <img /> tags\n        return isGreenPixel(data)\n            ? loadSerializedSVG$1(createForeignObjectSVG(size, size, 0, 0, node))\n            : Promise.reject(false);\n    })\n        .then(function (img) {\n        ctx.drawImage(img, 0, 0);\n        // Edge does not render background-images\n        return isGreenPixel(ctx.getImageData(0, 0, size, size).data);\n    })\n        .catch(function () { return false; });\n};\nvar createForeignObjectSVG = function (width, height, x, y, node) {\n    var xmlns = 'http://www.w3.org/2000/svg';\n    var svg = document.createElementNS(xmlns, 'svg');\n    var foreignObject = document.createElementNS(xmlns, 'foreignObject');\n    svg.setAttributeNS(null, 'width', width.toString());\n    svg.setAttributeNS(null, 'height', height.toString());\n    foreignObject.setAttributeNS(null, 'width', '100%');\n    foreignObject.setAttributeNS(null, 'height', '100%');\n    foreignObject.setAttributeNS(null, 'x', x.toString());\n    foreignObject.setAttributeNS(null, 'y', y.toString());\n    foreignObject.setAttributeNS(null, 'externalResourcesRequired', 'true');\n    svg.appendChild(foreignObject);\n    foreignObject.appendChild(node);\n    return svg;\n};\nvar loadSerializedSVG$1 = function (svg) {\n    return new Promise(function (resolve, reject) {\n        var img = new Image();\n        img.onload = function () { return resolve(img); };\n        img.onerror = reject;\n        img.src = \"data:image/svg+xml;charset=utf-8,\" + encodeURIComponent(new XMLSerializer().serializeToString(svg));\n    });\n};\nvar FEATURES = {\n    get SUPPORT_RANGE_BOUNDS() {\n        var value = testRangeBounds(document);\n        Object.defineProperty(FEATURES, 'SUPPORT_RANGE_BOUNDS', { value: value });\n        return value;\n    },\n    get SUPPORT_WORD_BREAKING() {\n        var value = FEATURES.SUPPORT_RANGE_BOUNDS && testIOSLineBreak(document);\n        Object.defineProperty(FEATURES, 'SUPPORT_WORD_BREAKING', { value: value });\n        return value;\n    },\n    get SUPPORT_SVG_DRAWING() {\n        var value = testSVG(document);\n        Object.defineProperty(FEATURES, 'SUPPORT_SVG_DRAWING', { value: value });\n        return value;\n    },\n    get SUPPORT_FOREIGNOBJECT_DRAWING() {\n        var value = typeof Array.from === 'function' && typeof window.fetch === 'function'\n            ? testForeignObject(document)\n            : Promise.resolve(false);\n        Object.defineProperty(FEATURES, 'SUPPORT_FOREIGNOBJECT_DRAWING', { value: value });\n        return value;\n    },\n    get SUPPORT_CORS_IMAGES() {\n        var value = testCORS();\n        Object.defineProperty(FEATURES, 'SUPPORT_CORS_IMAGES', { value: value });\n        return value;\n    },\n    get SUPPORT_RESPONSE_TYPE() {\n        var value = testResponseType();\n        Object.defineProperty(FEATURES, 'SUPPORT_RESPONSE_TYPE', { value: value });\n        return value;\n    },\n    get SUPPORT_CORS_XHR() {\n        var value = 'withCredentials' in new XMLHttpRequest();\n        Object.defineProperty(FEATURES, 'SUPPORT_CORS_XHR', { value: value });\n        return value;\n    },\n    get SUPPORT_NATIVE_TEXT_SEGMENTATION() {\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        var value = !!(typeof Intl !== 'undefined' && Intl.Segmenter);\n        Object.defineProperty(FEATURES, 'SUPPORT_NATIVE_TEXT_SEGMENTATION', { value: value });\n        return value;\n    }\n};\n\nvar TextBounds = /** @class */ (function () {\n    function TextBounds(text, bounds) {\n        this.text = text;\n        this.bounds = bounds;\n    }\n    return TextBounds;\n}());\nvar parseTextBounds = function (context, value, styles, node) {\n    var textList = breakText(value, styles);\n    var textBounds = [];\n    var offset = 0;\n    textList.forEach(function (text) {\n        if (styles.textDecorationLine.length || text.trim().length > 0) {\n            if (FEATURES.SUPPORT_RANGE_BOUNDS) {\n                var clientRects = createRange(node, offset, text.length).getClientRects();\n                if (clientRects.length > 1) {\n                    var subSegments = segmentGraphemes(text);\n                    var subOffset_1 = 0;\n                    subSegments.forEach(function (subSegment) {\n                        textBounds.push(new TextBounds(subSegment, Bounds.fromDOMRectList(context, createRange(node, subOffset_1 + offset, subSegment.length).getClientRects())));\n                        subOffset_1 += subSegment.length;\n                    });\n                }\n                else {\n                    textBounds.push(new TextBounds(text, Bounds.fromDOMRectList(context, clientRects)));\n                }\n            }\n            else {\n                var replacementNode = node.splitText(text.length);\n                textBounds.push(new TextBounds(text, getWrapperBounds(context, node)));\n                node = replacementNode;\n            }\n        }\n        else if (!FEATURES.SUPPORT_RANGE_BOUNDS) {\n            node = node.splitText(text.length);\n        }\n        offset += text.length;\n    });\n    return textBounds;\n};\nvar getWrapperBounds = function (context, node) {\n    var ownerDocument = node.ownerDocument;\n    if (ownerDocument) {\n        var wrapper = ownerDocument.createElement('html2canvaswrapper');\n        wrapper.appendChild(node.cloneNode(true));\n        var parentNode = node.parentNode;\n        if (parentNode) {\n            parentNode.replaceChild(wrapper, node);\n            var bounds = parseBounds(context, wrapper);\n            if (wrapper.firstChild) {\n                parentNode.replaceChild(wrapper.firstChild, wrapper);\n            }\n            return bounds;\n        }\n    }\n    return Bounds.EMPTY;\n};\nvar createRange = function (node, offset, length) {\n    var ownerDocument = node.ownerDocument;\n    if (!ownerDocument) {\n        throw new Error('Node has no owner document');\n    }\n    var range = ownerDocument.createRange();\n    range.setStart(node, offset);\n    range.setEnd(node, offset + length);\n    return range;\n};\nvar segmentGraphemes = function (value) {\n    if (FEATURES.SUPPORT_NATIVE_TEXT_SEGMENTATION) {\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        var segmenter = new Intl.Segmenter(void 0, { granularity: 'grapheme' });\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        return Array.from(segmenter.segment(value)).map(function (segment) { return segment.segment; });\n    }\n    return splitGraphemes(value);\n};\nvar segmentWords = function (value, styles) {\n    if (FEATURES.SUPPORT_NATIVE_TEXT_SEGMENTATION) {\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        var segmenter = new Intl.Segmenter(void 0, {\n            granularity: 'word'\n        });\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        return Array.from(segmenter.segment(value)).map(function (segment) { return segment.segment; });\n    }\n    return breakWords(value, styles);\n};\nvar breakText = function (value, styles) {\n    return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value, styles);\n};\n// https://drafts.csswg.org/css-text/#word-separator\nvar wordSeparators = [0x0020, 0x00a0, 0x1361, 0x10100, 0x10101, 0x1039, 0x1091];\nvar breakWords = function (str, styles) {\n    var breaker = LineBreaker(str, {\n        lineBreak: styles.lineBreak,\n        wordBreak: styles.overflowWrap === \"break-word\" /* BREAK_WORD */ ? 'break-word' : styles.wordBreak\n    });\n    var words = [];\n    var bk;\n    var _loop_1 = function () {\n        if (bk.value) {\n            var value = bk.value.slice();\n            var codePoints = toCodePoints$1(value);\n            var word_1 = '';\n            codePoints.forEach(function (codePoint) {\n                if (wordSeparators.indexOf(codePoint) === -1) {\n                    word_1 += fromCodePoint$1(codePoint);\n                }\n                else {\n                    if (word_1.length) {\n                        words.push(word_1);\n                    }\n                    words.push(fromCodePoint$1(codePoint));\n                    word_1 = '';\n                }\n            });\n            if (word_1.length) {\n                words.push(word_1);\n            }\n        }\n    };\n    while (!(bk = breaker.next()).done) {\n        _loop_1();\n    }\n    return words;\n};\n\nvar TextContainer = /** @class */ (function () {\n    function TextContainer(context, node, styles) {\n        this.text = transform(node.data, styles.textTransform);\n        this.textBounds = parseTextBounds(context, this.text, styles, node);\n    }\n    return TextContainer;\n}());\nvar transform = function (text, transform) {\n    switch (transform) {\n        case 1 /* LOWERCASE */:\n            return text.toLowerCase();\n        case 3 /* CAPITALIZE */:\n            return text.replace(CAPITALIZE, capitalize);\n        case 2 /* UPPERCASE */:\n            return text.toUpperCase();\n        default:\n            return text;\n    }\n};\nvar CAPITALIZE = /(^|\\s|:|-|\\(|\\))([a-z])/g;\nvar capitalize = function (m, p1, p2) {\n    if (m.length > 0) {\n        return p1 + p2.toUpperCase();\n    }\n    return m;\n};\n\nvar ImageElementContainer = /** @class */ (function (_super) {\n    __extends(ImageElementContainer, _super);\n    function ImageElementContainer(context, img) {\n        var _this = _super.call(this, context, img) || this;\n        _this.src = img.currentSrc || img.src;\n        _this.intrinsicWidth = img.naturalWidth;\n        _this.intrinsicHeight = img.naturalHeight;\n        _this.context.cache.addImage(_this.src);\n        return _this;\n    }\n    return ImageElementContainer;\n}(ElementContainer));\n\nvar CanvasElementContainer = /** @class */ (function (_super) {\n    __extends(CanvasElementContainer, _super);\n    function CanvasElementContainer(context, canvas) {\n        var _this = _super.call(this, context, canvas) || this;\n        _this.canvas = canvas;\n        _this.intrinsicWidth = canvas.width;\n        _this.intrinsicHeight = canvas.height;\n        return _this;\n    }\n    return CanvasElementContainer;\n}(ElementContainer));\n\nvar SVGElementContainer = /** @class */ (function (_super) {\n    __extends(SVGElementContainer, _super);\n    function SVGElementContainer(context, img) {\n        var _this = _super.call(this, context, img) || this;\n        var s = new XMLSerializer();\n        var bounds = parseBounds(context, img);\n        img.setAttribute('width', bounds.width + \"px\");\n        img.setAttribute('height', bounds.height + \"px\");\n        _this.svg = \"data:image/svg+xml,\" + encodeURIComponent(s.serializeToString(img));\n        _this.intrinsicWidth = img.width.baseVal.value;\n        _this.intrinsicHeight = img.height.baseVal.value;\n        _this.context.cache.addImage(_this.svg);\n        return _this;\n    }\n    return SVGElementContainer;\n}(ElementContainer));\n\nvar LIElementContainer = /** @class */ (function (_super) {\n    __extends(LIElementContainer, _super);\n    function LIElementContainer(context, element) {\n        var _this = _super.call(this, context, element) || this;\n        _this.value = element.value;\n        return _this;\n    }\n    return LIElementContainer;\n}(ElementContainer));\n\nvar OLElementContainer = /** @class */ (function (_super) {\n    __extends(OLElementContainer, _super);\n    function OLElementContainer(context, element) {\n        var _this = _super.call(this, context, element) || this;\n        _this.start = element.start;\n        _this.reversed = typeof element.reversed === 'boolean' && element.reversed === true;\n        return _this;\n    }\n    return OLElementContainer;\n}(ElementContainer));\n\nvar CHECKBOX_BORDER_RADIUS = [\n    {\n        type: 15 /* DIMENSION_TOKEN */,\n        flags: 0,\n        unit: 'px',\n        number: 3\n    }\n];\nvar RADIO_BORDER_RADIUS = [\n    {\n        type: 16 /* PERCENTAGE_TOKEN */,\n        flags: 0,\n        number: 50\n    }\n];\nvar reformatInputBounds = function (bounds) {\n    if (bounds.width > bounds.height) {\n        return new Bounds(bounds.left + (bounds.width - bounds.height) / 2, bounds.top, bounds.height, bounds.height);\n    }\n    else if (bounds.width < bounds.height) {\n        return new Bounds(bounds.left, bounds.top + (bounds.height - bounds.width) / 2, bounds.width, bounds.width);\n    }\n    return bounds;\n};\nvar getInputValue = function (node) {\n    var value = node.type === PASSWORD ? new Array(node.value.length + 1).join('\\u2022') : node.value;\n    return value.length === 0 ? node.placeholder || '' : value;\n};\nvar CHECKBOX = 'checkbox';\nvar RADIO = 'radio';\nvar PASSWORD = 'password';\nvar INPUT_COLOR = 0x2a2a2aff;\nvar InputElementContainer = /** @class */ (function (_super) {\n    __extends(InputElementContainer, _super);\n    function InputElementContainer(context, input) {\n        var _this = _super.call(this, context, input) || this;\n        _this.type = input.type.toLowerCase();\n        _this.checked = input.checked;\n        _this.value = getInputValue(input);\n        if (_this.type === CHECKBOX || _this.type === RADIO) {\n            _this.styles.backgroundColor = 0xdededeff;\n            _this.styles.borderTopColor =\n                _this.styles.borderRightColor =\n                    _this.styles.borderBottomColor =\n                        _this.styles.borderLeftColor =\n                            0xa5a5a5ff;\n            _this.styles.borderTopWidth =\n                _this.styles.borderRightWidth =\n                    _this.styles.borderBottomWidth =\n                        _this.styles.borderLeftWidth =\n                            1;\n            _this.styles.borderTopStyle =\n                _this.styles.borderRightStyle =\n                    _this.styles.borderBottomStyle =\n                        _this.styles.borderLeftStyle =\n                            1 /* SOLID */;\n            _this.styles.backgroundClip = [0 /* BORDER_BOX */];\n            _this.styles.backgroundOrigin = [0 /* BORDER_BOX */];\n            _this.bounds = reformatInputBounds(_this.bounds);\n        }\n        switch (_this.type) {\n            case CHECKBOX:\n                _this.styles.borderTopRightRadius =\n                    _this.styles.borderTopLeftRadius =\n                        _this.styles.borderBottomRightRadius =\n                            _this.styles.borderBottomLeftRadius =\n                                CHECKBOX_BORDER_RADIUS;\n                break;\n            case RADIO:\n                _this.styles.borderTopRightRadius =\n                    _this.styles.borderTopLeftRadius =\n                        _this.styles.borderBottomRightRadius =\n                            _this.styles.borderBottomLeftRadius =\n                                RADIO_BORDER_RADIUS;\n                break;\n        }\n        return _this;\n    }\n    return InputElementContainer;\n}(ElementContainer));\n\nvar SelectElementContainer = /** @class */ (function (_super) {\n    __extends(SelectElementContainer, _super);\n    function SelectElementContainer(context, element) {\n        var _this = _super.call(this, context, element) || this;\n        var option = element.options[element.selectedIndex || 0];\n        _this.value = option ? option.text || '' : '';\n        return _this;\n    }\n    return SelectElementContainer;\n}(ElementContainer));\n\nvar TextareaElementContainer = /** @class */ (function (_super) {\n    __extends(TextareaElementContainer, _super);\n    function TextareaElementContainer(context, element) {\n        var _this = _super.call(this, context, element) || this;\n        _this.value = element.value;\n        return _this;\n    }\n    return TextareaElementContainer;\n}(ElementContainer));\n\nvar IFrameElementContainer = /** @class */ (function (_super) {\n    __extends(IFrameElementContainer, _super);\n    function IFrameElementContainer(context, iframe) {\n        var _this = _super.call(this, context, iframe) || this;\n        _this.src = iframe.src;\n        _this.width = parseInt(iframe.width, 10) || 0;\n        _this.height = parseInt(iframe.height, 10) || 0;\n        _this.backgroundColor = _this.styles.backgroundColor;\n        try {\n            if (iframe.contentWindow &&\n                iframe.contentWindow.document &&\n                iframe.contentWindow.document.documentElement) {\n                _this.tree = parseTree(context, iframe.contentWindow.document.documentElement);\n                // http://www.w3.org/TR/css3-background/#special-backgrounds\n                var documentBackgroundColor = iframe.contentWindow.document.documentElement\n                    ? parseColor(context, getComputedStyle(iframe.contentWindow.document.documentElement).backgroundColor)\n                    : COLORS.TRANSPARENT;\n                var bodyBackgroundColor = iframe.contentWindow.document.body\n                    ? parseColor(context, getComputedStyle(iframe.contentWindow.document.body).backgroundColor)\n                    : COLORS.TRANSPARENT;\n                _this.backgroundColor = isTransparent(documentBackgroundColor)\n                    ? isTransparent(bodyBackgroundColor)\n                        ? _this.styles.backgroundColor\n                        : bodyBackgroundColor\n                    : documentBackgroundColor;\n            }\n        }\n        catch (e) { }\n        return _this;\n    }\n    return IFrameElementContainer;\n}(ElementContainer));\n\nvar LIST_OWNERS = ['OL', 'UL', 'MENU'];\nvar parseNodeTree = function (context, node, parent, root) {\n    for (var childNode = node.firstChild, nextNode = void 0; childNode; childNode = nextNode) {\n        nextNode = childNode.nextSibling;\n        if (isTextNode(childNode) && childNode.data.trim().length > 0) {\n            parent.textNodes.push(new TextContainer(context, childNode, parent.styles));\n        }\n        else if (isElementNode(childNode)) {\n            if (isSlotElement(childNode) && childNode.assignedNodes) {\n                childNode.assignedNodes().forEach(function (childNode) { return parseNodeTree(context, childNode, parent, root); });\n            }\n            else {\n                var container = createContainer(context, childNode);\n                if (container.styles.isVisible()) {\n                    if (createsRealStackingContext(childNode, container, root)) {\n                        container.flags |= 4 /* CREATES_REAL_STACKING_CONTEXT */;\n                    }\n                    else if (createsStackingContext(container.styles)) {\n                        container.flags |= 2 /* CREATES_STACKING_CONTEXT */;\n                    }\n                    if (LIST_OWNERS.indexOf(childNode.tagName) !== -1) {\n                        container.flags |= 8 /* IS_LIST_OWNER */;\n                    }\n                    parent.elements.push(container);\n                    childNode.slot;\n                    if (childNode.shadowRoot) {\n                        parseNodeTree(context, childNode.shadowRoot, container, root);\n                    }\n                    else if (!isTextareaElement(childNode) &&\n                        !isSVGElement(childNode) &&\n                        !isSelectElement(childNode)) {\n                        parseNodeTree(context, childNode, container, root);\n                    }\n                }\n            }\n        }\n    }\n};\nvar createContainer = function (context, element) {\n    if (isImageElement(element)) {\n        return new ImageElementContainer(context, element);\n    }\n    if (isCanvasElement(element)) {\n        return new CanvasElementContainer(context, element);\n    }\n    if (isSVGElement(element)) {\n        return new SVGElementContainer(context, element);\n    }\n    if (isLIElement(element)) {\n        return new LIElementContainer(context, element);\n    }\n    if (isOLElement(element)) {\n        return new OLElementContainer(context, element);\n    }\n    if (isInputElement(element)) {\n        return new InputElementContainer(context, element);\n    }\n    if (isSelectElement(element)) {\n        return new SelectElementContainer(context, element);\n    }\n    if (isTextareaElement(element)) {\n        return new TextareaElementContainer(context, element);\n    }\n    if (isIFrameElement(element)) {\n        return new IFrameElementContainer(context, element);\n    }\n    return new ElementContainer(context, element);\n};\nvar parseTree = function (context, element) {\n    var container = createContainer(context, element);\n    container.flags |= 4 /* CREATES_REAL_STACKING_CONTEXT */;\n    parseNodeTree(context, element, container, container);\n    return container;\n};\nvar createsRealStackingContext = function (node, container, root) {\n    return (container.styles.isPositionedWithZIndex() ||\n        container.styles.opacity < 1 ||\n        container.styles.isTransformed() ||\n        (isBodyElement(node) && root.styles.isTransparent()));\n};\nvar createsStackingContext = function (styles) { return styles.isPositioned() || styles.isFloating(); };\nvar isTextNode = function (node) { return node.nodeType === Node.TEXT_NODE; };\nvar isElementNode = function (node) { return node.nodeType === Node.ELEMENT_NODE; };\nvar isHTMLElementNode = function (node) {\n    return isElementNode(node) && typeof node.style !== 'undefined' && !isSVGElementNode(node);\n};\nvar isSVGElementNode = function (element) {\n    return typeof element.className === 'object';\n};\nvar isLIElement = function (node) { return node.tagName === 'LI'; };\nvar isOLElement = function (node) { return node.tagName === 'OL'; };\nvar isInputElement = function (node) { return node.tagName === 'INPUT'; };\nvar isHTMLElement = function (node) { return node.tagName === 'HTML'; };\nvar isSVGElement = function (node) { return node.tagName === 'svg'; };\nvar isBodyElement = function (node) { return node.tagName === 'BODY'; };\nvar isCanvasElement = function (node) { return node.tagName === 'CANVAS'; };\nvar isVideoElement = function (node) { return node.tagName === 'VIDEO'; };\nvar isImageElement = function (node) { return node.tagName === 'IMG'; };\nvar isIFrameElement = function (node) { return node.tagName === 'IFRAME'; };\nvar isStyleElement = function (node) { return node.tagName === 'STYLE'; };\nvar isScriptElement = function (node) { return node.tagName === 'SCRIPT'; };\nvar isTextareaElement = function (node) { return node.tagName === 'TEXTAREA'; };\nvar isSelectElement = function (node) { return node.tagName === 'SELECT'; };\nvar isSlotElement = function (node) { return node.tagName === 'SLOT'; };\n// https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name\nvar isCustomElement = function (node) { return node.tagName.indexOf('-') > 0; };\n\nvar CounterState = /** @class */ (function () {\n    function CounterState() {\n        this.counters = {};\n    }\n    CounterState.prototype.getCounterValue = function (name) {\n        var counter = this.counters[name];\n        if (counter && counter.length) {\n            return counter[counter.length - 1];\n        }\n        return 1;\n    };\n    CounterState.prototype.getCounterValues = function (name) {\n        var counter = this.counters[name];\n        return counter ? counter : [];\n    };\n    CounterState.prototype.pop = function (counters) {\n        var _this = this;\n        counters.forEach(function (counter) { return _this.counters[counter].pop(); });\n    };\n    CounterState.prototype.parse = function (style) {\n        var _this = this;\n        var counterIncrement = style.counterIncrement;\n        var counterReset = style.counterReset;\n        var canReset = true;\n        if (counterIncrement !== null) {\n            counterIncrement.forEach(function (entry) {\n                var counter = _this.counters[entry.counter];\n                if (counter && entry.increment !== 0) {\n                    canReset = false;\n                    if (!counter.length) {\n                        counter.push(1);\n                    }\n                    counter[Math.max(0, counter.length - 1)] += entry.increment;\n                }\n            });\n        }\n        var counterNames = [];\n        if (canReset) {\n            counterReset.forEach(function (entry) {\n                var counter = _this.counters[entry.counter];\n                counterNames.push(entry.counter);\n                if (!counter) {\n                    counter = _this.counters[entry.counter] = [];\n                }\n                counter.push(entry.reset);\n            });\n        }\n        return counterNames;\n    };\n    return CounterState;\n}());\nvar ROMAN_UPPER = {\n    integers: [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1],\n    values: ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']\n};\nvar ARMENIAN = {\n    integers: [\n        9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70,\n        60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1\n    ],\n    values: [\n        'Ք',\n        'Փ',\n        'Ւ',\n        'Ց',\n        'Ր',\n        'Տ',\n        'Վ',\n        'Ս',\n        'Ռ',\n        'Ջ',\n        'Պ',\n        'Չ',\n        'Ո',\n        'Շ',\n        'Ն',\n        'Յ',\n        'Մ',\n        'Ճ',\n        'Ղ',\n        'Ձ',\n        'Հ',\n        'Կ',\n        'Ծ',\n        'Խ',\n        'Լ',\n        'Ի',\n        'Ժ',\n        'Թ',\n        'Ը',\n        'Է',\n        'Զ',\n        'Ե',\n        'Դ',\n        'Գ',\n        'Բ',\n        'Ա'\n    ]\n};\nvar HEBREW = {\n    integers: [\n        10000, 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20,\n        19, 18, 17, 16, 15, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1\n    ],\n    values: [\n        'י׳',\n        'ט׳',\n        'ח׳',\n        'ז׳',\n        'ו׳',\n        'ה׳',\n        'ד׳',\n        'ג׳',\n        'ב׳',\n        'א׳',\n        'ת',\n        'ש',\n        'ר',\n        'ק',\n        'צ',\n        'פ',\n        'ע',\n        'ס',\n        'נ',\n        'מ',\n        'ל',\n        'כ',\n        'יט',\n        'יח',\n        'יז',\n        'טז',\n        'טו',\n        'י',\n        'ט',\n        'ח',\n        'ז',\n        'ו',\n        'ה',\n        'ד',\n        'ג',\n        'ב',\n        'א'\n    ]\n};\nvar GEORGIAN = {\n    integers: [\n        10000, 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90,\n        80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1\n    ],\n    values: [\n        'ჵ',\n        'ჰ',\n        'ჯ',\n        'ჴ',\n        'ხ',\n        'ჭ',\n        'წ',\n        'ძ',\n        'ც',\n        'ჩ',\n        'შ',\n        'ყ',\n        'ღ',\n        'ქ',\n        'ფ',\n        'ჳ',\n        'ტ',\n        'ს',\n        'რ',\n        'ჟ',\n        'პ',\n        'ო',\n        'ჲ',\n        'ნ',\n        'მ',\n        'ლ',\n        'კ',\n        'ი',\n        'თ',\n        'ჱ',\n        'ზ',\n        'ვ',\n        'ე',\n        'დ',\n        'გ',\n        'ბ',\n        'ა'\n    ]\n};\nvar createAdditiveCounter = function (value, min, max, symbols, fallback, suffix) {\n    if (value < min || value > max) {\n        return createCounterText(value, fallback, suffix.length > 0);\n    }\n    return (symbols.integers.reduce(function (string, integer, index) {\n        while (value >= integer) {\n            value -= integer;\n            string += symbols.values[index];\n        }\n        return string;\n    }, '') + suffix);\n};\nvar createCounterStyleWithSymbolResolver = function (value, codePointRangeLength, isNumeric, resolver) {\n    var string = '';\n    do {\n        if (!isNumeric) {\n            value--;\n        }\n        string = resolver(value) + string;\n        value /= codePointRangeLength;\n    } while (value * codePointRangeLength >= codePointRangeLength);\n    return string;\n};\nvar createCounterStyleFromRange = function (value, codePointRangeStart, codePointRangeEnd, isNumeric, suffix) {\n    var codePointRangeLength = codePointRangeEnd - codePointRangeStart + 1;\n    return ((value < 0 ? '-' : '') +\n        (createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, isNumeric, function (codePoint) {\n            return fromCodePoint$1(Math.floor(codePoint % codePointRangeLength) + codePointRangeStart);\n        }) +\n            suffix));\n};\nvar createCounterStyleFromSymbols = function (value, symbols, suffix) {\n    if (suffix === void 0) { suffix = '. '; }\n    var codePointRangeLength = symbols.length;\n    return (createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, false, function (codePoint) { return symbols[Math.floor(codePoint % codePointRangeLength)]; }) + suffix);\n};\nvar CJK_ZEROS = 1 << 0;\nvar CJK_TEN_COEFFICIENTS = 1 << 1;\nvar CJK_TEN_HIGH_COEFFICIENTS = 1 << 2;\nvar CJK_HUNDRED_COEFFICIENTS = 1 << 3;\nvar createCJKCounter = function (value, numbers, multipliers, negativeSign, suffix, flags) {\n    if (value < -9999 || value > 9999) {\n        return createCounterText(value, 4 /* CJK_DECIMAL */, suffix.length > 0);\n    }\n    var tmp = Math.abs(value);\n    var string = suffix;\n    if (tmp === 0) {\n        return numbers[0] + string;\n    }\n    for (var digit = 0; tmp > 0 && digit <= 4; digit++) {\n        var coefficient = tmp % 10;\n        if (coefficient === 0 && contains(flags, CJK_ZEROS) && string !== '') {\n            string = numbers[coefficient] + string;\n        }\n        else if (coefficient > 1 ||\n            (coefficient === 1 && digit === 0) ||\n            (coefficient === 1 && digit === 1 && contains(flags, CJK_TEN_COEFFICIENTS)) ||\n            (coefficient === 1 && digit === 1 && contains(flags, CJK_TEN_HIGH_COEFFICIENTS) && value > 100) ||\n            (coefficient === 1 && digit > 1 && contains(flags, CJK_HUNDRED_COEFFICIENTS))) {\n            string = numbers[coefficient] + (digit > 0 ? multipliers[digit - 1] : '') + string;\n        }\n        else if (coefficient === 1 && digit > 0) {\n            string = multipliers[digit - 1] + string;\n        }\n        tmp = Math.floor(tmp / 10);\n    }\n    return (value < 0 ? negativeSign : '') + string;\n};\nvar CHINESE_INFORMAL_MULTIPLIERS = '十百千萬';\nvar CHINESE_FORMAL_MULTIPLIERS = '拾佰仟萬';\nvar JAPANESE_NEGATIVE = 'マイナス';\nvar KOREAN_NEGATIVE = '마이너스';\nvar createCounterText = function (value, type, appendSuffix) {\n    var defaultSuffix = appendSuffix ? '. ' : '';\n    var cjkSuffix = appendSuffix ? '、' : '';\n    var koreanSuffix = appendSuffix ? ', ' : '';\n    var spaceSuffix = appendSuffix ? ' ' : '';\n    switch (type) {\n        case 0 /* DISC */:\n            return '•' + spaceSuffix;\n        case 1 /* CIRCLE */:\n            return '◦' + spaceSuffix;\n        case 2 /* SQUARE */:\n            return '◾' + spaceSuffix;\n        case 5 /* DECIMAL_LEADING_ZERO */:\n            var string = createCounterStyleFromRange(value, 48, 57, true, defaultSuffix);\n            return string.length < 4 ? \"0\" + string : string;\n        case 4 /* CJK_DECIMAL */:\n            return createCounterStyleFromSymbols(value, '〇一二三四五六七八九', cjkSuffix);\n        case 6 /* LOWER_ROMAN */:\n            return createAdditiveCounter(value, 1, 3999, ROMAN_UPPER, 3 /* DECIMAL */, defaultSuffix).toLowerCase();\n        case 7 /* UPPER_ROMAN */:\n            return createAdditiveCounter(value, 1, 3999, ROMAN_UPPER, 3 /* DECIMAL */, defaultSuffix);\n        case 8 /* LOWER_GREEK */:\n            return createCounterStyleFromRange(value, 945, 969, false, defaultSuffix);\n        case 9 /* LOWER_ALPHA */:\n            return createCounterStyleFromRange(value, 97, 122, false, defaultSuffix);\n        case 10 /* UPPER_ALPHA */:\n            return createCounterStyleFromRange(value, 65, 90, false, defaultSuffix);\n        case 11 /* ARABIC_INDIC */:\n            return createCounterStyleFromRange(value, 1632, 1641, true, defaultSuffix);\n        case 12 /* ARMENIAN */:\n        case 49 /* UPPER_ARMENIAN */:\n            return createAdditiveCounter(value, 1, 9999, ARMENIAN, 3 /* DECIMAL */, defaultSuffix);\n        case 35 /* LOWER_ARMENIAN */:\n            return createAdditiveCounter(value, 1, 9999, ARMENIAN, 3 /* DECIMAL */, defaultSuffix).toLowerCase();\n        case 13 /* BENGALI */:\n            return createCounterStyleFromRange(value, 2534, 2543, true, defaultSuffix);\n        case 14 /* CAMBODIAN */:\n        case 30 /* KHMER */:\n            return createCounterStyleFromRange(value, 6112, 6121, true, defaultSuffix);\n        case 15 /* CJK_EARTHLY_BRANCH */:\n            return createCounterStyleFromSymbols(value, '子丑寅卯辰巳午未申酉戌亥', cjkSuffix);\n        case 16 /* CJK_HEAVENLY_STEM */:\n            return createCounterStyleFromSymbols(value, '甲乙丙丁戊己庚辛壬癸', cjkSuffix);\n        case 17 /* CJK_IDEOGRAPHIC */:\n        case 48 /* TRAD_CHINESE_INFORMAL */:\n            return createCJKCounter(value, '零一二三四五六七八九', CHINESE_INFORMAL_MULTIPLIERS, '負', cjkSuffix, CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);\n        case 47 /* TRAD_CHINESE_FORMAL */:\n            return createCJKCounter(value, '零壹貳參肆伍陸柒捌玖', CHINESE_FORMAL_MULTIPLIERS, '負', cjkSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);\n        case 42 /* SIMP_CHINESE_INFORMAL */:\n            return createCJKCounter(value, '零一二三四五六七八九', CHINESE_INFORMAL_MULTIPLIERS, '负', cjkSuffix, CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);\n        case 41 /* SIMP_CHINESE_FORMAL */:\n            return createCJKCounter(value, '零壹贰叁肆伍陆柒捌玖', CHINESE_FORMAL_MULTIPLIERS, '负', cjkSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS | CJK_HUNDRED_COEFFICIENTS);\n        case 26 /* JAPANESE_INFORMAL */:\n            return createCJKCounter(value, '〇一二三四五六七八九', '十百千万', JAPANESE_NEGATIVE, cjkSuffix, 0);\n        case 25 /* JAPANESE_FORMAL */:\n            return createCJKCounter(value, '零壱弐参四伍六七八九', '拾百千万', JAPANESE_NEGATIVE, cjkSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS);\n        case 31 /* KOREAN_HANGUL_FORMAL */:\n            return createCJKCounter(value, '영일이삼사오육칠팔구', '십백천만', KOREAN_NEGATIVE, koreanSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS);\n        case 33 /* KOREAN_HANJA_INFORMAL */:\n            return createCJKCounter(value, '零一二三四五六七八九', '十百千萬', KOREAN_NEGATIVE, koreanSuffix, 0);\n        case 32 /* KOREAN_HANJA_FORMAL */:\n            return createCJKCounter(value, '零壹貳參四五六七八九', '拾百千', KOREAN_NEGATIVE, koreanSuffix, CJK_ZEROS | CJK_TEN_COEFFICIENTS | CJK_TEN_HIGH_COEFFICIENTS);\n        case 18 /* DEVANAGARI */:\n            return createCounterStyleFromRange(value, 0x966, 0x96f, true, defaultSuffix);\n        case 20 /* GEORGIAN */:\n            return createAdditiveCounter(value, 1, 19999, GEORGIAN, 3 /* DECIMAL */, defaultSuffix);\n        case 21 /* GUJARATI */:\n            return createCounterStyleFromRange(value, 0xae6, 0xaef, true, defaultSuffix);\n        case 22 /* GURMUKHI */:\n            return createCounterStyleFromRange(value, 0xa66, 0xa6f, true, defaultSuffix);\n        case 22 /* HEBREW */:\n            return createAdditiveCounter(value, 1, 10999, HEBREW, 3 /* DECIMAL */, defaultSuffix);\n        case 23 /* HIRAGANA */:\n            return createCounterStyleFromSymbols(value, 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわゐゑをん');\n        case 24 /* HIRAGANA_IROHA */:\n            return createCounterStyleFromSymbols(value, 'いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす');\n        case 27 /* KANNADA */:\n            return createCounterStyleFromRange(value, 0xce6, 0xcef, true, defaultSuffix);\n        case 28 /* KATAKANA */:\n            return createCounterStyleFromSymbols(value, 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヰヱヲン', cjkSuffix);\n        case 29 /* KATAKANA_IROHA */:\n            return createCounterStyleFromSymbols(value, 'イロハニホヘトチリヌルヲワカヨタレソツネナラムウヰノオクヤマケフコエテアサキユメミシヱヒモセス', cjkSuffix);\n        case 34 /* LAO */:\n            return createCounterStyleFromRange(value, 0xed0, 0xed9, true, defaultSuffix);\n        case 37 /* MONGOLIAN */:\n            return createCounterStyleFromRange(value, 0x1810, 0x1819, true, defaultSuffix);\n        case 38 /* MYANMAR */:\n            return createCounterStyleFromRange(value, 0x1040, 0x1049, true, defaultSuffix);\n        case 39 /* ORIYA */:\n            return createCounterStyleFromRange(value, 0xb66, 0xb6f, true, defaultSuffix);\n        case 40 /* PERSIAN */:\n            return createCounterStyleFromRange(value, 0x6f0, 0x6f9, true, defaultSuffix);\n        case 43 /* TAMIL */:\n            return createCounterStyleFromRange(value, 0xbe6, 0xbef, true, defaultSuffix);\n        case 44 /* TELUGU */:\n            return createCounterStyleFromRange(value, 0xc66, 0xc6f, true, defaultSuffix);\n        case 45 /* THAI */:\n            return createCounterStyleFromRange(value, 0xe50, 0xe59, true, defaultSuffix);\n        case 46 /* TIBETAN */:\n            return createCounterStyleFromRange(value, 0xf20, 0xf29, true, defaultSuffix);\n        case 3 /* DECIMAL */:\n        default:\n            return createCounterStyleFromRange(value, 48, 57, true, defaultSuffix);\n    }\n};\n\nvar IGNORE_ATTRIBUTE = 'data-html2canvas-ignore';\nvar DocumentCloner = /** @class */ (function () {\n    function DocumentCloner(context, element, options) {\n        this.context = context;\n        this.options = options;\n        this.scrolledElements = [];\n        this.referenceElement = element;\n        this.counters = new CounterState();\n        this.quoteDepth = 0;\n        if (!element.ownerDocument) {\n            throw new Error('Cloned element does not have an owner document');\n        }\n        this.documentElement = this.cloneNode(element.ownerDocument.documentElement, false);\n    }\n    DocumentCloner.prototype.toIFrame = function (ownerDocument, windowSize) {\n        var _this = this;\n        var iframe = createIFrameContainer(ownerDocument, windowSize);\n        if (!iframe.contentWindow) {\n            return Promise.reject(\"Unable to find iframe window\");\n        }\n        var scrollX = ownerDocument.defaultView.pageXOffset;\n        var scrollY = ownerDocument.defaultView.pageYOffset;\n        var cloneWindow = iframe.contentWindow;\n        var documentClone = cloneWindow.document;\n        /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle\n         if window url is about:blank, we can assign the url to current by writing onto the document\n         */\n        var iframeLoad = iframeLoader(iframe).then(function () { return __awaiter(_this, void 0, void 0, function () {\n            var onclone, referenceElement;\n            return __generator(this, function (_a) {\n                switch (_a.label) {\n                    case 0:\n                        this.scrolledElements.forEach(restoreNodeScroll);\n                        if (cloneWindow) {\n                            cloneWindow.scrollTo(windowSize.left, windowSize.top);\n                            if (/(iPad|iPhone|iPod)/g.test(navigator.userAgent) &&\n                                (cloneWindow.scrollY !== windowSize.top || cloneWindow.scrollX !== windowSize.left)) {\n                                this.context.logger.warn('Unable to restore scroll position for cloned document');\n                                this.context.windowBounds = this.context.windowBounds.add(cloneWindow.scrollX - windowSize.left, cloneWindow.scrollY - windowSize.top, 0, 0);\n                            }\n                        }\n                        onclone = this.options.onclone;\n                        referenceElement = this.clonedReferenceElement;\n                        if (typeof referenceElement === 'undefined') {\n                            return [2 /*return*/, Promise.reject(\"Error finding the \" + this.referenceElement.nodeName + \" in the cloned document\")];\n                        }\n                        if (!(documentClone.fonts && documentClone.fonts.ready)) return [3 /*break*/, 2];\n                        return [4 /*yield*/, documentClone.fonts.ready];\n                    case 1:\n                        _a.sent();\n                        _a.label = 2;\n                    case 2:\n                        if (!/(AppleWebKit)/g.test(navigator.userAgent)) return [3 /*break*/, 4];\n                        return [4 /*yield*/, imagesReady(documentClone)];\n                    case 3:\n                        _a.sent();\n                        _a.label = 4;\n                    case 4:\n                        if (typeof onclone === 'function') {\n                            return [2 /*return*/, Promise.resolve()\n                                    .then(function () { return onclone(documentClone, referenceElement); })\n                                    .then(function () { return iframe; })];\n                        }\n                        return [2 /*return*/, iframe];\n                }\n            });\n        }); });\n        documentClone.open();\n        documentClone.write(serializeDoctype(document.doctype) + \"<html></html>\");\n        // Chrome scrolls the parent document for some reason after the write to the cloned window???\n        restoreOwnerScroll(this.referenceElement.ownerDocument, scrollX, scrollY);\n        documentClone.replaceChild(documentClone.adoptNode(this.documentElement), documentClone.documentElement);\n        documentClone.close();\n        return iframeLoad;\n    };\n    DocumentCloner.prototype.createElementClone = function (node) {\n        if (isDebugging(node, 2 /* CLONE */)) {\n            debugger;\n        }\n        if (isCanvasElement(node)) {\n            return this.createCanvasClone(node);\n        }\n        if (isVideoElement(node)) {\n            return this.createVideoClone(node);\n        }\n        if (isStyleElement(node)) {\n            return this.createStyleClone(node);\n        }\n        var clone = node.cloneNode(false);\n        if (isImageElement(clone)) {\n            if (isImageElement(node) && node.currentSrc && node.currentSrc !== node.src) {\n                clone.src = node.currentSrc;\n                clone.srcset = '';\n            }\n            if (clone.loading === 'lazy') {\n                clone.loading = 'eager';\n            }\n        }\n        if (isCustomElement(clone)) {\n            return this.createCustomElementClone(clone);\n        }\n        return clone;\n    };\n    DocumentCloner.prototype.createCustomElementClone = function (node) {\n        var clone = document.createElement('html2canvascustomelement');\n        copyCSSStyles(node.style, clone);\n        return clone;\n    };\n    DocumentCloner.prototype.createStyleClone = function (node) {\n        try {\n            var sheet = node.sheet;\n            if (sheet && sheet.cssRules) {\n                var css = [].slice.call(sheet.cssRules, 0).reduce(function (css, rule) {\n                    if (rule && typeof rule.cssText === 'string') {\n                        return css + rule.cssText;\n                    }\n                    return css;\n                }, '');\n                var style = node.cloneNode(false);\n                style.textContent = css;\n                return style;\n            }\n        }\n        catch (e) {\n            // accessing node.sheet.cssRules throws a DOMException\n            this.context.logger.error('Unable to access cssRules property', e);\n            if (e.name !== 'SecurityError') {\n                throw e;\n            }\n        }\n        return node.cloneNode(false);\n    };\n    DocumentCloner.prototype.createCanvasClone = function (canvas) {\n        var _a;\n        if (this.options.inlineImages && canvas.ownerDocument) {\n            var img = canvas.ownerDocument.createElement('img');\n            try {\n                img.src = canvas.toDataURL();\n                return img;\n            }\n            catch (e) {\n                this.context.logger.info(\"Unable to inline canvas contents, canvas is tainted\", canvas);\n            }\n        }\n        var clonedCanvas = canvas.cloneNode(false);\n        try {\n            clonedCanvas.width = canvas.width;\n            clonedCanvas.height = canvas.height;\n            var ctx = canvas.getContext('2d');\n            var clonedCtx = clonedCanvas.getContext('2d');\n            if (clonedCtx) {\n                if (!this.options.allowTaint && ctx) {\n                    clonedCtx.putImageData(ctx.getImageData(0, 0, canvas.width, canvas.height), 0, 0);\n                }\n                else {\n                    var gl = (_a = canvas.getContext('webgl2')) !== null && _a !== void 0 ? _a : canvas.getContext('webgl');\n                    if (gl) {\n                        var attribs = gl.getContextAttributes();\n                        if ((attribs === null || attribs === void 0 ? void 0 : attribs.preserveDrawingBuffer) === false) {\n                            this.context.logger.warn('Unable to clone WebGL context as it has preserveDrawingBuffer=false', canvas);\n                        }\n                    }\n                    clonedCtx.drawImage(canvas, 0, 0);\n                }\n            }\n            return clonedCanvas;\n        }\n        catch (e) {\n            this.context.logger.info(\"Unable to clone canvas as it is tainted\", canvas);\n        }\n        return clonedCanvas;\n    };\n    DocumentCloner.prototype.createVideoClone = function (video) {\n        var canvas = video.ownerDocument.createElement('canvas');\n        canvas.width = video.offsetWidth;\n        canvas.height = video.offsetHeight;\n        var ctx = canvas.getContext('2d');\n        try {\n            if (ctx) {\n                ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\n                if (!this.options.allowTaint) {\n                    ctx.getImageData(0, 0, canvas.width, canvas.height);\n                }\n            }\n            return canvas;\n        }\n        catch (e) {\n            this.context.logger.info(\"Unable to clone video as it is tainted\", video);\n        }\n        var blankCanvas = video.ownerDocument.createElement('canvas');\n        blankCanvas.width = video.offsetWidth;\n        blankCanvas.height = video.offsetHeight;\n        return blankCanvas;\n    };\n    DocumentCloner.prototype.appendChildNode = function (clone, child, copyStyles) {\n        if (!isElementNode(child) ||\n            (!isScriptElement(child) &&\n                !child.hasAttribute(IGNORE_ATTRIBUTE) &&\n                (typeof this.options.ignoreElements !== 'function' || !this.options.ignoreElements(child)))) {\n            if (!this.options.copyStyles || !isElementNode(child) || !isStyleElement(child)) {\n                clone.appendChild(this.cloneNode(child, copyStyles));\n            }\n        }\n    };\n    DocumentCloner.prototype.cloneChildNodes = function (node, clone, copyStyles) {\n        var _this = this;\n        for (var child = node.shadowRoot ? node.shadowRoot.firstChild : node.firstChild; child; child = child.nextSibling) {\n            if (isElementNode(child) && isSlotElement(child) && typeof child.assignedNodes === 'function') {\n                var assignedNodes = child.assignedNodes();\n                if (assignedNodes.length) {\n                    assignedNodes.forEach(function (assignedNode) { return _this.appendChildNode(clone, assignedNode, copyStyles); });\n                }\n            }\n            else {\n                this.appendChildNode(clone, child, copyStyles);\n            }\n        }\n    };\n    DocumentCloner.prototype.cloneNode = function (node, copyStyles) {\n        if (isTextNode(node)) {\n            return document.createTextNode(node.data);\n        }\n        if (!node.ownerDocument) {\n            return node.cloneNode(false);\n        }\n        var window = node.ownerDocument.defaultView;\n        if (window && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {\n            var clone = this.createElementClone(node);\n            clone.style.transitionProperty = 'none';\n            var style = window.getComputedStyle(node);\n            var styleBefore = window.getComputedStyle(node, ':before');\n            var styleAfter = window.getComputedStyle(node, ':after');\n            if (this.referenceElement === node && isHTMLElementNode(clone)) {\n                this.clonedReferenceElement = clone;\n            }\n            if (isBodyElement(clone)) {\n                createPseudoHideStyles(clone);\n            }\n            var counters = this.counters.parse(new CSSParsedCounterDeclaration(this.context, style));\n            var before = this.resolvePseudoContent(node, clone, styleBefore, PseudoElementType.BEFORE);\n            if (isCustomElement(node)) {\n                copyStyles = true;\n            }\n            if (!isVideoElement(node)) {\n                this.cloneChildNodes(node, clone, copyStyles);\n            }\n            if (before) {\n                clone.insertBefore(before, clone.firstChild);\n            }\n            var after = this.resolvePseudoContent(node, clone, styleAfter, PseudoElementType.AFTER);\n            if (after) {\n                clone.appendChild(after);\n            }\n            this.counters.pop(counters);\n            if ((style && (this.options.copyStyles || isSVGElementNode(node)) && !isIFrameElement(node)) ||\n                copyStyles) {\n                copyCSSStyles(style, clone);\n            }\n            if (node.scrollTop !== 0 || node.scrollLeft !== 0) {\n                this.scrolledElements.push([clone, node.scrollLeft, node.scrollTop]);\n            }\n            if ((isTextareaElement(node) || isSelectElement(node)) &&\n                (isTextareaElement(clone) || isSelectElement(clone))) {\n                clone.value = node.value;\n            }\n            return clone;\n        }\n        return node.cloneNode(false);\n    };\n    DocumentCloner.prototype.resolvePseudoContent = function (node, clone, style, pseudoElt) {\n        var _this = this;\n        if (!style) {\n            return;\n        }\n        var value = style.content;\n        var document = clone.ownerDocument;\n        if (!document || !value || value === 'none' || value === '-moz-alt-content' || style.display === 'none') {\n            return;\n        }\n        this.counters.parse(new CSSParsedCounterDeclaration(this.context, style));\n        var declaration = new CSSParsedPseudoDeclaration(this.context, style);\n        var anonymousReplacedElement = document.createElement('html2canvaspseudoelement');\n        copyCSSStyles(style, anonymousReplacedElement);\n        declaration.content.forEach(function (token) {\n            if (token.type === 0 /* STRING_TOKEN */) {\n                anonymousReplacedElement.appendChild(document.createTextNode(token.value));\n            }\n            else if (token.type === 22 /* URL_TOKEN */) {\n                var img = document.createElement('img');\n                img.src = token.value;\n                img.style.opacity = '1';\n                anonymousReplacedElement.appendChild(img);\n            }\n            else if (token.type === 18 /* FUNCTION */) {\n                if (token.name === 'attr') {\n                    var attr = token.values.filter(isIdentToken);\n                    if (attr.length) {\n                        anonymousReplacedElement.appendChild(document.createTextNode(node.getAttribute(attr[0].value) || ''));\n                    }\n                }\n                else if (token.name === 'counter') {\n                    var _a = token.values.filter(nonFunctionArgSeparator), counter = _a[0], counterStyle = _a[1];\n                    if (counter && isIdentToken(counter)) {\n                        var counterState = _this.counters.getCounterValue(counter.value);\n                        var counterType = counterStyle && isIdentToken(counterStyle)\n                            ? listStyleType.parse(_this.context, counterStyle.value)\n                            : 3 /* DECIMAL */;\n                        anonymousReplacedElement.appendChild(document.createTextNode(createCounterText(counterState, counterType, false)));\n                    }\n                }\n                else if (token.name === 'counters') {\n                    var _b = token.values.filter(nonFunctionArgSeparator), counter = _b[0], delim = _b[1], counterStyle = _b[2];\n                    if (counter && isIdentToken(counter)) {\n                        var counterStates = _this.counters.getCounterValues(counter.value);\n                        var counterType_1 = counterStyle && isIdentToken(counterStyle)\n                            ? listStyleType.parse(_this.context, counterStyle.value)\n                            : 3 /* DECIMAL */;\n                        var separator = delim && delim.type === 0 /* STRING_TOKEN */ ? delim.value : '';\n                        var text = counterStates\n                            .map(function (value) { return createCounterText(value, counterType_1, false); })\n                            .join(separator);\n                        anonymousReplacedElement.appendChild(document.createTextNode(text));\n                    }\n                }\n                else ;\n            }\n            else if (token.type === 20 /* IDENT_TOKEN */) {\n                switch (token.value) {\n                    case 'open-quote':\n                        anonymousReplacedElement.appendChild(document.createTextNode(getQuote(declaration.quotes, _this.quoteDepth++, true)));\n                        break;\n                    case 'close-quote':\n                        anonymousReplacedElement.appendChild(document.createTextNode(getQuote(declaration.quotes, --_this.quoteDepth, false)));\n                        break;\n                    default:\n                        // safari doesn't parse string tokens correctly because of lack of quotes\n                        anonymousReplacedElement.appendChild(document.createTextNode(token.value));\n                }\n            }\n        });\n        anonymousReplacedElement.className = PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + \" \" + PSEUDO_HIDE_ELEMENT_CLASS_AFTER;\n        var newClassName = pseudoElt === PseudoElementType.BEFORE\n            ? \" \" + PSEUDO_HIDE_ELEMENT_CLASS_BEFORE\n            : \" \" + PSEUDO_HIDE_ELEMENT_CLASS_AFTER;\n        if (isSVGElementNode(clone)) {\n            clone.className.baseValue += newClassName;\n        }\n        else {\n            clone.className += newClassName;\n        }\n        return anonymousReplacedElement;\n    };\n    DocumentCloner.destroy = function (container) {\n        if (container.parentNode) {\n            container.parentNode.removeChild(container);\n            return true;\n        }\n        return false;\n    };\n    return DocumentCloner;\n}());\nvar PseudoElementType;\n(function (PseudoElementType) {\n    PseudoElementType[PseudoElementType[\"BEFORE\"] = 0] = \"BEFORE\";\n    PseudoElementType[PseudoElementType[\"AFTER\"] = 1] = \"AFTER\";\n})(PseudoElementType || (PseudoElementType = {}));\nvar createIFrameContainer = function (ownerDocument, bounds) {\n    var cloneIframeContainer = ownerDocument.createElement('iframe');\n    cloneIframeContainer.className = 'html2canvas-container';\n    cloneIframeContainer.style.visibility = 'hidden';\n    cloneIframeContainer.style.position = 'fixed';\n    cloneIframeContainer.style.left = '-10000px';\n    cloneIframeContainer.style.top = '0px';\n    cloneIframeContainer.style.border = '0';\n    cloneIframeContainer.width = bounds.width.toString();\n    cloneIframeContainer.height = bounds.height.toString();\n    cloneIframeContainer.scrolling = 'no'; // ios won't scroll without it\n    cloneIframeContainer.setAttribute(IGNORE_ATTRIBUTE, 'true');\n    ownerDocument.body.appendChild(cloneIframeContainer);\n    return cloneIframeContainer;\n};\nvar imageReady = function (img) {\n    return new Promise(function (resolve) {\n        if (img.complete) {\n            resolve();\n            return;\n        }\n        if (!img.src) {\n            resolve();\n            return;\n        }\n        img.onload = resolve;\n        img.onerror = resolve;\n    });\n};\nvar imagesReady = function (document) {\n    return Promise.all([].slice.call(document.images, 0).map(imageReady));\n};\nvar iframeLoader = function (iframe) {\n    return new Promise(function (resolve, reject) {\n        var cloneWindow = iframe.contentWindow;\n        if (!cloneWindow) {\n            return reject(\"No window assigned for iframe\");\n        }\n        var documentClone = cloneWindow.document;\n        cloneWindow.onload = iframe.onload = function () {\n            cloneWindow.onload = iframe.onload = null;\n            var interval = setInterval(function () {\n                if (documentClone.body.childNodes.length > 0 && documentClone.readyState === 'complete') {\n                    clearInterval(interval);\n                    resolve(iframe);\n                }\n            }, 50);\n        };\n    });\n};\nvar ignoredStyleProperties = [\n    'all',\n    'd',\n    'content' // Safari shows pseudoelements if content is set\n];\nvar copyCSSStyles = function (style, target) {\n    // Edge does not provide value for cssText\n    for (var i = style.length - 1; i >= 0; i--) {\n        var property = style.item(i);\n        if (ignoredStyleProperties.indexOf(property) === -1) {\n            target.style.setProperty(property, style.getPropertyValue(property));\n        }\n    }\n    return target;\n};\nvar serializeDoctype = function (doctype) {\n    var str = '';\n    if (doctype) {\n        str += '<!DOCTYPE ';\n        if (doctype.name) {\n            str += doctype.name;\n        }\n        if (doctype.internalSubset) {\n            str += doctype.internalSubset;\n        }\n        if (doctype.publicId) {\n            str += \"\\\"\" + doctype.publicId + \"\\\"\";\n        }\n        if (doctype.systemId) {\n            str += \"\\\"\" + doctype.systemId + \"\\\"\";\n        }\n        str += '>';\n    }\n    return str;\n};\nvar restoreOwnerScroll = function (ownerDocument, x, y) {\n    if (ownerDocument &&\n        ownerDocument.defaultView &&\n        (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {\n        ownerDocument.defaultView.scrollTo(x, y);\n    }\n};\nvar restoreNodeScroll = function (_a) {\n    var element = _a[0], x = _a[1], y = _a[2];\n    element.scrollLeft = x;\n    element.scrollTop = y;\n};\nvar PSEUDO_BEFORE = ':before';\nvar PSEUDO_AFTER = ':after';\nvar PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = '___html2canvas___pseudoelement_before';\nvar PSEUDO_HIDE_ELEMENT_CLASS_AFTER = '___html2canvas___pseudoelement_after';\nvar PSEUDO_HIDE_ELEMENT_STYLE = \"{\\n    content: \\\"\\\" !important;\\n    display: none !important;\\n}\";\nvar createPseudoHideStyles = function (body) {\n    createStyles(body, \".\" + PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + PSEUDO_BEFORE + PSEUDO_HIDE_ELEMENT_STYLE + \"\\n         .\" + PSEUDO_HIDE_ELEMENT_CLASS_AFTER + PSEUDO_AFTER + PSEUDO_HIDE_ELEMENT_STYLE);\n};\nvar createStyles = function (body, styles) {\n    var document = body.ownerDocument;\n    if (document) {\n        var style = document.createElement('style');\n        style.textContent = styles;\n        body.appendChild(style);\n    }\n};\n\nvar CacheStorage = /** @class */ (function () {\n    function CacheStorage() {\n    }\n    CacheStorage.getOrigin = function (url) {\n        var link = CacheStorage._link;\n        if (!link) {\n            return 'about:blank';\n        }\n        link.href = url;\n        link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/\n        return link.protocol + link.hostname + link.port;\n    };\n    CacheStorage.isSameOrigin = function (src) {\n        return CacheStorage.getOrigin(src) === CacheStorage._origin;\n    };\n    CacheStorage.setContext = function (window) {\n        CacheStorage._link = window.document.createElement('a');\n        CacheStorage._origin = CacheStorage.getOrigin(window.location.href);\n    };\n    CacheStorage._origin = 'about:blank';\n    return CacheStorage;\n}());\nvar Cache = /** @class */ (function () {\n    function Cache(context, _options) {\n        this.context = context;\n        this._options = _options;\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        this._cache = {};\n    }\n    Cache.prototype.addImage = function (src) {\n        var result = Promise.resolve();\n        if (this.has(src)) {\n            return result;\n        }\n        if (isBlobImage(src) || isRenderable(src)) {\n            (this._cache[src] = this.loadImage(src)).catch(function () {\n                // prevent unhandled rejection\n            });\n            return result;\n        }\n        return result;\n    };\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    Cache.prototype.match = function (src) {\n        return this._cache[src];\n    };\n    Cache.prototype.loadImage = function (key) {\n        return __awaiter(this, void 0, void 0, function () {\n            var isSameOrigin, useCORS, useProxy, src;\n            var _this = this;\n            return __generator(this, function (_a) {\n                switch (_a.label) {\n                    case 0:\n                        isSameOrigin = CacheStorage.isSameOrigin(key);\n                        useCORS = !isInlineImage(key) && this._options.useCORS === true && FEATURES.SUPPORT_CORS_IMAGES && !isSameOrigin;\n                        useProxy = !isInlineImage(key) &&\n                            !isSameOrigin &&\n                            !isBlobImage(key) &&\n                            typeof this._options.proxy === 'string' &&\n                            FEATURES.SUPPORT_CORS_XHR &&\n                            !useCORS;\n                        if (!isSameOrigin &&\n                            this._options.allowTaint === false &&\n                            !isInlineImage(key) &&\n                            !isBlobImage(key) &&\n                            !useProxy &&\n                            !useCORS) {\n                            return [2 /*return*/];\n                        }\n                        src = key;\n                        if (!useProxy) return [3 /*break*/, 2];\n                        return [4 /*yield*/, this.proxy(src)];\n                    case 1:\n                        src = _a.sent();\n                        _a.label = 2;\n                    case 2:\n                        this.context.logger.debug(\"Added image \" + key.substring(0, 256));\n                        return [4 /*yield*/, new Promise(function (resolve, reject) {\n                                var img = new Image();\n                                img.onload = function () { return resolve(img); };\n                                img.onerror = reject;\n                                //ios safari 10.3 taints canvas with data urls unless crossOrigin is set to anonymous\n                                if (isInlineBase64Image(src) || useCORS) {\n                                    img.crossOrigin = 'anonymous';\n                                }\n                                img.src = src;\n                                if (img.complete === true) {\n                                    // Inline XML images may fail to parse, throwing an Error later on\n                                    setTimeout(function () { return resolve(img); }, 500);\n                                }\n                                if (_this._options.imageTimeout > 0) {\n                                    setTimeout(function () { return reject(\"Timed out (\" + _this._options.imageTimeout + \"ms) loading image\"); }, _this._options.imageTimeout);\n                                }\n                            })];\n                    case 3: return [2 /*return*/, _a.sent()];\n                }\n            });\n        });\n    };\n    Cache.prototype.has = function (key) {\n        return typeof this._cache[key] !== 'undefined';\n    };\n    Cache.prototype.keys = function () {\n        return Promise.resolve(Object.keys(this._cache));\n    };\n    Cache.prototype.proxy = function (src) {\n        var _this = this;\n        var proxy = this._options.proxy;\n        if (!proxy) {\n            throw new Error('No proxy defined');\n        }\n        var key = src.substring(0, 256);\n        return new Promise(function (resolve, reject) {\n            var responseType = FEATURES.SUPPORT_RESPONSE_TYPE ? 'blob' : 'text';\n            var xhr = new XMLHttpRequest();\n            xhr.onload = function () {\n                if (xhr.status === 200) {\n                    if (responseType === 'text') {\n                        resolve(xhr.response);\n                    }\n                    else {\n                        var reader_1 = new FileReader();\n                        reader_1.addEventListener('load', function () { return resolve(reader_1.result); }, false);\n                        reader_1.addEventListener('error', function (e) { return reject(e); }, false);\n                        reader_1.readAsDataURL(xhr.response);\n                    }\n                }\n                else {\n                    reject(\"Failed to proxy resource \" + key + \" with status code \" + xhr.status);\n                }\n            };\n            xhr.onerror = reject;\n            var queryString = proxy.indexOf('?') > -1 ? '&' : '?';\n            xhr.open('GET', \"\" + proxy + queryString + \"url=\" + encodeURIComponent(src) + \"&responseType=\" + responseType);\n            if (responseType !== 'text' && xhr instanceof XMLHttpRequest) {\n                xhr.responseType = responseType;\n            }\n            if (_this._options.imageTimeout) {\n                var timeout_1 = _this._options.imageTimeout;\n                xhr.timeout = timeout_1;\n                xhr.ontimeout = function () { return reject(\"Timed out (\" + timeout_1 + \"ms) proxying \" + key); };\n            }\n            xhr.send();\n        });\n    };\n    return Cache;\n}());\nvar INLINE_SVG = /^data:image\\/svg\\+xml/i;\nvar INLINE_BASE64 = /^data:image\\/.*;base64,/i;\nvar INLINE_IMG = /^data:image\\/.*/i;\nvar isRenderable = function (src) { return FEATURES.SUPPORT_SVG_DRAWING || !isSVG(src); };\nvar isInlineImage = function (src) { return INLINE_IMG.test(src); };\nvar isInlineBase64Image = function (src) { return INLINE_BASE64.test(src); };\nvar isBlobImage = function (src) { return src.substr(0, 4) === 'blob'; };\nvar isSVG = function (src) { return src.substr(-3).toLowerCase() === 'svg' || INLINE_SVG.test(src); };\n\nvar Vector = /** @class */ (function () {\n    function Vector(x, y) {\n        this.type = 0 /* VECTOR */;\n        this.x = x;\n        this.y = y;\n    }\n    Vector.prototype.add = function (deltaX, deltaY) {\n        return new Vector(this.x + deltaX, this.y + deltaY);\n    };\n    return Vector;\n}());\n\nvar lerp = function (a, b, t) {\n    return new Vector(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);\n};\nvar BezierCurve = /** @class */ (function () {\n    function BezierCurve(start, startControl, endControl, end) {\n        this.type = 1 /* BEZIER_CURVE */;\n        this.start = start;\n        this.startControl = startControl;\n        this.endControl = endControl;\n        this.end = end;\n    }\n    BezierCurve.prototype.subdivide = function (t, firstHalf) {\n        var ab = lerp(this.start, this.startControl, t);\n        var bc = lerp(this.startControl, this.endControl, t);\n        var cd = lerp(this.endControl, this.end, t);\n        var abbc = lerp(ab, bc, t);\n        var bccd = lerp(bc, cd, t);\n        var dest = lerp(abbc, bccd, t);\n        return firstHalf ? new BezierCurve(this.start, ab, abbc, dest) : new BezierCurve(dest, bccd, cd, this.end);\n    };\n    BezierCurve.prototype.add = function (deltaX, deltaY) {\n        return new BezierCurve(this.start.add(deltaX, deltaY), this.startControl.add(deltaX, deltaY), this.endControl.add(deltaX, deltaY), this.end.add(deltaX, deltaY));\n    };\n    BezierCurve.prototype.reverse = function () {\n        return new BezierCurve(this.end, this.endControl, this.startControl, this.start);\n    };\n    return BezierCurve;\n}());\nvar isBezierCurve = function (path) { return path.type === 1 /* BEZIER_CURVE */; };\n\nvar BoundCurves = /** @class */ (function () {\n    function BoundCurves(element) {\n        var styles = element.styles;\n        var bounds = element.bounds;\n        var _a = getAbsoluteValueForTuple(styles.borderTopLeftRadius, bounds.width, bounds.height), tlh = _a[0], tlv = _a[1];\n        var _b = getAbsoluteValueForTuple(styles.borderTopRightRadius, bounds.width, bounds.height), trh = _b[0], trv = _b[1];\n        var _c = getAbsoluteValueForTuple(styles.borderBottomRightRadius, bounds.width, bounds.height), brh = _c[0], brv = _c[1];\n        var _d = getAbsoluteValueForTuple(styles.borderBottomLeftRadius, bounds.width, bounds.height), blh = _d[0], blv = _d[1];\n        var factors = [];\n        factors.push((tlh + trh) / bounds.width);\n        factors.push((blh + brh) / bounds.width);\n        factors.push((tlv + blv) / bounds.height);\n        factors.push((trv + brv) / bounds.height);\n        var maxFactor = Math.max.apply(Math, factors);\n        if (maxFactor > 1) {\n            tlh /= maxFactor;\n            tlv /= maxFactor;\n            trh /= maxFactor;\n            trv /= maxFactor;\n            brh /= maxFactor;\n            brv /= maxFactor;\n            blh /= maxFactor;\n            blv /= maxFactor;\n        }\n        var topWidth = bounds.width - trh;\n        var rightHeight = bounds.height - brv;\n        var bottomWidth = bounds.width - brh;\n        var leftHeight = bounds.height - blv;\n        var borderTopWidth = styles.borderTopWidth;\n        var borderRightWidth = styles.borderRightWidth;\n        var borderBottomWidth = styles.borderBottomWidth;\n        var borderLeftWidth = styles.borderLeftWidth;\n        var paddingTop = getAbsoluteValue(styles.paddingTop, element.bounds.width);\n        var paddingRight = getAbsoluteValue(styles.paddingRight, element.bounds.width);\n        var paddingBottom = getAbsoluteValue(styles.paddingBottom, element.bounds.width);\n        var paddingLeft = getAbsoluteValue(styles.paddingLeft, element.bounds.width);\n        this.topLeftBorderDoubleOuterBox =\n            tlh > 0 || tlv > 0\n                ? getCurvePoints(bounds.left + borderLeftWidth / 3, bounds.top + borderTopWidth / 3, tlh - borderLeftWidth / 3, tlv - borderTopWidth / 3, CORNER.TOP_LEFT)\n                : new Vector(bounds.left + borderLeftWidth / 3, bounds.top + borderTopWidth / 3);\n        this.topRightBorderDoubleOuterBox =\n            tlh > 0 || tlv > 0\n                ? getCurvePoints(bounds.left + topWidth, bounds.top + borderTopWidth / 3, trh - borderRightWidth / 3, trv - borderTopWidth / 3, CORNER.TOP_RIGHT)\n                : new Vector(bounds.left + bounds.width - borderRightWidth / 3, bounds.top + borderTopWidth / 3);\n        this.bottomRightBorderDoubleOuterBox =\n            brh > 0 || brv > 0\n                ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh - borderRightWidth / 3, brv - borderBottomWidth / 3, CORNER.BOTTOM_RIGHT)\n                : new Vector(bounds.left + bounds.width - borderRightWidth / 3, bounds.top + bounds.height - borderBottomWidth / 3);\n        this.bottomLeftBorderDoubleOuterBox =\n            blh > 0 || blv > 0\n                ? getCurvePoints(bounds.left + borderLeftWidth / 3, bounds.top + leftHeight, blh - borderLeftWidth / 3, blv - borderBottomWidth / 3, CORNER.BOTTOM_LEFT)\n                : new Vector(bounds.left + borderLeftWidth / 3, bounds.top + bounds.height - borderBottomWidth / 3);\n        this.topLeftBorderDoubleInnerBox =\n            tlh > 0 || tlv > 0\n                ? getCurvePoints(bounds.left + (borderLeftWidth * 2) / 3, bounds.top + (borderTopWidth * 2) / 3, tlh - (borderLeftWidth * 2) / 3, tlv - (borderTopWidth * 2) / 3, CORNER.TOP_LEFT)\n                : new Vector(bounds.left + (borderLeftWidth * 2) / 3, bounds.top + (borderTopWidth * 2) / 3);\n        this.topRightBorderDoubleInnerBox =\n            tlh > 0 || tlv > 0\n                ? getCurvePoints(bounds.left + topWidth, bounds.top + (borderTopWidth * 2) / 3, trh - (borderRightWidth * 2) / 3, trv - (borderTopWidth * 2) / 3, CORNER.TOP_RIGHT)\n                : new Vector(bounds.left + bounds.width - (borderRightWidth * 2) / 3, bounds.top + (borderTopWidth * 2) / 3);\n        this.bottomRightBorderDoubleInnerBox =\n            brh > 0 || brv > 0\n                ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh - (borderRightWidth * 2) / 3, brv - (borderBottomWidth * 2) / 3, CORNER.BOTTOM_RIGHT)\n                : new Vector(bounds.left + bounds.width - (borderRightWidth * 2) / 3, bounds.top + bounds.height - (borderBottomWidth * 2) / 3);\n        this.bottomLeftBorderDoubleInnerBox =\n            blh > 0 || blv > 0\n                ? getCurvePoints(bounds.left + (borderLeftWidth * 2) / 3, bounds.top + leftHeight, blh - (borderLeftWidth * 2) / 3, blv - (borderBottomWidth * 2) / 3, CORNER.BOTTOM_LEFT)\n                : new Vector(bounds.left + (borderLeftWidth * 2) / 3, bounds.top + bounds.height - (borderBottomWidth * 2) / 3);\n        this.topLeftBorderStroke =\n            tlh > 0 || tlv > 0\n                ? getCurvePoints(bounds.left + borderLeftWidth / 2, bounds.top + borderTopWidth / 2, tlh - borderLeftWidth / 2, tlv - borderTopWidth / 2, CORNER.TOP_LEFT)\n                : new Vector(bounds.left + borderLeftWidth / 2, bounds.top + borderTopWidth / 2);\n        this.topRightBorderStroke =\n            tlh > 0 || tlv > 0\n                ? getCurvePoints(bounds.left + topWidth, bounds.top + borderTopWidth / 2, trh - borderRightWidth / 2, trv - borderTopWidth / 2, CORNER.TOP_RIGHT)\n                : new Vector(bounds.left + bounds.width - borderRightWidth / 2, bounds.top + borderTopWidth / 2);\n        this.bottomRightBorderStroke =\n            brh > 0 || brv > 0\n                ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh - borderRightWidth / 2, brv - borderBottomWidth / 2, CORNER.BOTTOM_RIGHT)\n                : new Vector(bounds.left + bounds.width - borderRightWidth / 2, bounds.top + bounds.height - borderBottomWidth / 2);\n        this.bottomLeftBorderStroke =\n            blh > 0 || blv > 0\n                ? getCurvePoints(bounds.left + borderLeftWidth / 2, bounds.top + leftHeight, blh - borderLeftWidth / 2, blv - borderBottomWidth / 2, CORNER.BOTTOM_LEFT)\n                : new Vector(bounds.left + borderLeftWidth / 2, bounds.top + bounds.height - borderBottomWidth / 2);\n        this.topLeftBorderBox =\n            tlh > 0 || tlv > 0\n                ? getCurvePoints(bounds.left, bounds.top, tlh, tlv, CORNER.TOP_LEFT)\n                : new Vector(bounds.left, bounds.top);\n        this.topRightBorderBox =\n            trh > 0 || trv > 0\n                ? getCurvePoints(bounds.left + topWidth, bounds.top, trh, trv, CORNER.TOP_RIGHT)\n                : new Vector(bounds.left + bounds.width, bounds.top);\n        this.bottomRightBorderBox =\n            brh > 0 || brv > 0\n                ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh, brv, CORNER.BOTTOM_RIGHT)\n                : new Vector(bounds.left + bounds.width, bounds.top + bounds.height);\n        this.bottomLeftBorderBox =\n            blh > 0 || blv > 0\n                ? getCurvePoints(bounds.left, bounds.top + leftHeight, blh, blv, CORNER.BOTTOM_LEFT)\n                : new Vector(bounds.left, bounds.top + bounds.height);\n        this.topLeftPaddingBox =\n            tlh > 0 || tlv > 0\n                ? getCurvePoints(bounds.left + borderLeftWidth, bounds.top + borderTopWidth, Math.max(0, tlh - borderLeftWidth), Math.max(0, tlv - borderTopWidth), CORNER.TOP_LEFT)\n                : new Vector(bounds.left + borderLeftWidth, bounds.top + borderTopWidth);\n        this.topRightPaddingBox =\n            trh > 0 || trv > 0\n                ? getCurvePoints(bounds.left + Math.min(topWidth, bounds.width - borderRightWidth), bounds.top + borderTopWidth, topWidth > bounds.width + borderRightWidth ? 0 : Math.max(0, trh - borderRightWidth), Math.max(0, trv - borderTopWidth), CORNER.TOP_RIGHT)\n                : new Vector(bounds.left + bounds.width - borderRightWidth, bounds.top + borderTopWidth);\n        this.bottomRightPaddingBox =\n            brh > 0 || brv > 0\n                ? getCurvePoints(bounds.left + Math.min(bottomWidth, bounds.width - borderLeftWidth), bounds.top + Math.min(rightHeight, bounds.height - borderBottomWidth), Math.max(0, brh - borderRightWidth), Math.max(0, brv - borderBottomWidth), CORNER.BOTTOM_RIGHT)\n                : new Vector(bounds.left + bounds.width - borderRightWidth, bounds.top + bounds.height - borderBottomWidth);\n        this.bottomLeftPaddingBox =\n            blh > 0 || blv > 0\n                ? getCurvePoints(bounds.left + borderLeftWidth, bounds.top + Math.min(leftHeight, bounds.height - borderBottomWidth), Math.max(0, blh - borderLeftWidth), Math.max(0, blv - borderBottomWidth), CORNER.BOTTOM_LEFT)\n                : new Vector(bounds.left + borderLeftWidth, bounds.top + bounds.height - borderBottomWidth);\n        this.topLeftContentBox =\n            tlh > 0 || tlv > 0\n                ? getCurvePoints(bounds.left + borderLeftWidth + paddingLeft, bounds.top + borderTopWidth + paddingTop, Math.max(0, tlh - (borderLeftWidth + paddingLeft)), Math.max(0, tlv - (borderTopWidth + paddingTop)), CORNER.TOP_LEFT)\n                : new Vector(bounds.left + borderLeftWidth + paddingLeft, bounds.top + borderTopWidth + paddingTop);\n        this.topRightContentBox =\n            trh > 0 || trv > 0\n                ? getCurvePoints(bounds.left + Math.min(topWidth, bounds.width + borderLeftWidth + paddingLeft), bounds.top + borderTopWidth + paddingTop, topWidth > bounds.width + borderLeftWidth + paddingLeft ? 0 : trh - borderLeftWidth + paddingLeft, trv - (borderTopWidth + paddingTop), CORNER.TOP_RIGHT)\n                : new Vector(bounds.left + bounds.width - (borderRightWidth + paddingRight), bounds.top + borderTopWidth + paddingTop);\n        this.bottomRightContentBox =\n            brh > 0 || brv > 0\n                ? getCurvePoints(bounds.left + Math.min(bottomWidth, bounds.width - (borderLeftWidth + paddingLeft)), bounds.top + Math.min(rightHeight, bounds.height + borderTopWidth + paddingTop), Math.max(0, brh - (borderRightWidth + paddingRight)), brv - (borderBottomWidth + paddingBottom), CORNER.BOTTOM_RIGHT)\n                : new Vector(bounds.left + bounds.width - (borderRightWidth + paddingRight), bounds.top + bounds.height - (borderBottomWidth + paddingBottom));\n        this.bottomLeftContentBox =\n            blh > 0 || blv > 0\n                ? getCurvePoints(bounds.left + borderLeftWidth + paddingLeft, bounds.top + leftHeight, Math.max(0, blh - (borderLeftWidth + paddingLeft)), blv - (borderBottomWidth + paddingBottom), CORNER.BOTTOM_LEFT)\n                : new Vector(bounds.left + borderLeftWidth + paddingLeft, bounds.top + bounds.height - (borderBottomWidth + paddingBottom));\n    }\n    return BoundCurves;\n}());\nvar CORNER;\n(function (CORNER) {\n    CORNER[CORNER[\"TOP_LEFT\"] = 0] = \"TOP_LEFT\";\n    CORNER[CORNER[\"TOP_RIGHT\"] = 1] = \"TOP_RIGHT\";\n    CORNER[CORNER[\"BOTTOM_RIGHT\"] = 2] = \"BOTTOM_RIGHT\";\n    CORNER[CORNER[\"BOTTOM_LEFT\"] = 3] = \"BOTTOM_LEFT\";\n})(CORNER || (CORNER = {}));\nvar getCurvePoints = function (x, y, r1, r2, position) {\n    var kappa = 4 * ((Math.sqrt(2) - 1) / 3);\n    var ox = r1 * kappa; // control point offset horizontal\n    var oy = r2 * kappa; // control point offset vertical\n    var xm = x + r1; // x-middle\n    var ym = y + r2; // y-middle\n    switch (position) {\n        case CORNER.TOP_LEFT:\n            return new BezierCurve(new Vector(x, ym), new Vector(x, ym - oy), new Vector(xm - ox, y), new Vector(xm, y));\n        case CORNER.TOP_RIGHT:\n            return new BezierCurve(new Vector(x, y), new Vector(x + ox, y), new Vector(xm, ym - oy), new Vector(xm, ym));\n        case CORNER.BOTTOM_RIGHT:\n            return new BezierCurve(new Vector(xm, y), new Vector(xm, y + oy), new Vector(x + ox, ym), new Vector(x, ym));\n        case CORNER.BOTTOM_LEFT:\n        default:\n            return new BezierCurve(new Vector(xm, ym), new Vector(xm - ox, ym), new Vector(x, y + oy), new Vector(x, y));\n    }\n};\nvar calculateBorderBoxPath = function (curves) {\n    return [curves.topLeftBorderBox, curves.topRightBorderBox, curves.bottomRightBorderBox, curves.bottomLeftBorderBox];\n};\nvar calculateContentBoxPath = function (curves) {\n    return [\n        curves.topLeftContentBox,\n        curves.topRightContentBox,\n        curves.bottomRightContentBox,\n        curves.bottomLeftContentBox\n    ];\n};\nvar calculatePaddingBoxPath = function (curves) {\n    return [\n        curves.topLeftPaddingBox,\n        curves.topRightPaddingBox,\n        curves.bottomRightPaddingBox,\n        curves.bottomLeftPaddingBox\n    ];\n};\n\nvar TransformEffect = /** @class */ (function () {\n    function TransformEffect(offsetX, offsetY, matrix) {\n        this.offsetX = offsetX;\n        this.offsetY = offsetY;\n        this.matrix = matrix;\n        this.type = 0 /* TRANSFORM */;\n        this.target = 2 /* BACKGROUND_BORDERS */ | 4 /* CONTENT */;\n    }\n    return TransformEffect;\n}());\nvar ClipEffect = /** @class */ (function () {\n    function ClipEffect(path, target) {\n        this.path = path;\n        this.target = target;\n        this.type = 1 /* CLIP */;\n    }\n    return ClipEffect;\n}());\nvar OpacityEffect = /** @class */ (function () {\n    function OpacityEffect(opacity) {\n        this.opacity = opacity;\n        this.type = 2 /* OPACITY */;\n        this.target = 2 /* BACKGROUND_BORDERS */ | 4 /* CONTENT */;\n    }\n    return OpacityEffect;\n}());\nvar isTransformEffect = function (effect) {\n    return effect.type === 0 /* TRANSFORM */;\n};\nvar isClipEffect = function (effect) { return effect.type === 1 /* CLIP */; };\nvar isOpacityEffect = function (effect) { return effect.type === 2 /* OPACITY */; };\n\nvar equalPath = function (a, b) {\n    if (a.length === b.length) {\n        return a.some(function (v, i) { return v === b[i]; });\n    }\n    return false;\n};\nvar transformPath = function (path, deltaX, deltaY, deltaW, deltaH) {\n    return path.map(function (point, index) {\n        switch (index) {\n            case 0:\n                return point.add(deltaX, deltaY);\n            case 1:\n                return point.add(deltaX + deltaW, deltaY);\n            case 2:\n                return point.add(deltaX + deltaW, deltaY + deltaH);\n            case 3:\n                return point.add(deltaX, deltaY + deltaH);\n        }\n        return point;\n    });\n};\n\nvar StackingContext = /** @class */ (function () {\n    function StackingContext(container) {\n        this.element = container;\n        this.inlineLevel = [];\n        this.nonInlineLevel = [];\n        this.negativeZIndex = [];\n        this.zeroOrAutoZIndexOrTransformedOrOpacity = [];\n        this.positiveZIndex = [];\n        this.nonPositionedFloats = [];\n        this.nonPositionedInlineLevel = [];\n    }\n    return StackingContext;\n}());\nvar ElementPaint = /** @class */ (function () {\n    function ElementPaint(container, parent) {\n        this.container = container;\n        this.parent = parent;\n        this.effects = [];\n        this.curves = new BoundCurves(this.container);\n        if (this.container.styles.opacity < 1) {\n            this.effects.push(new OpacityEffect(this.container.styles.opacity));\n        }\n        if (this.container.styles.transform !== null) {\n            var offsetX = this.container.bounds.left + this.container.styles.transformOrigin[0].number;\n            var offsetY = this.container.bounds.top + this.container.styles.transformOrigin[1].number;\n            var matrix = this.container.styles.transform;\n            this.effects.push(new TransformEffect(offsetX, offsetY, matrix));\n        }\n        if (this.container.styles.overflowX !== 0 /* VISIBLE */) {\n            var borderBox = calculateBorderBoxPath(this.curves);\n            var paddingBox = calculatePaddingBoxPath(this.curves);\n            if (equalPath(borderBox, paddingBox)) {\n                this.effects.push(new ClipEffect(borderBox, 2 /* BACKGROUND_BORDERS */ | 4 /* CONTENT */));\n            }\n            else {\n                this.effects.push(new ClipEffect(borderBox, 2 /* BACKGROUND_BORDERS */));\n                this.effects.push(new ClipEffect(paddingBox, 4 /* CONTENT */));\n            }\n        }\n    }\n    ElementPaint.prototype.getEffects = function (target) {\n        var inFlow = [2 /* ABSOLUTE */, 3 /* FIXED */].indexOf(this.container.styles.position) === -1;\n        var parent = this.parent;\n        var effects = this.effects.slice(0);\n        while (parent) {\n            var croplessEffects = parent.effects.filter(function (effect) { return !isClipEffect(effect); });\n            if (inFlow || parent.container.styles.position !== 0 /* STATIC */ || !parent.parent) {\n                effects.unshift.apply(effects, croplessEffects);\n                inFlow = [2 /* ABSOLUTE */, 3 /* FIXED */].indexOf(parent.container.styles.position) === -1;\n                if (parent.container.styles.overflowX !== 0 /* VISIBLE */) {\n                    var borderBox = calculateBorderBoxPath(parent.curves);\n                    var paddingBox = calculatePaddingBoxPath(parent.curves);\n                    if (!equalPath(borderBox, paddingBox)) {\n                        effects.unshift(new ClipEffect(paddingBox, 2 /* BACKGROUND_BORDERS */ | 4 /* CONTENT */));\n                    }\n                }\n            }\n            else {\n                effects.unshift.apply(effects, croplessEffects);\n            }\n            parent = parent.parent;\n        }\n        return effects.filter(function (effect) { return contains(effect.target, target); });\n    };\n    return ElementPaint;\n}());\nvar parseStackTree = function (parent, stackingContext, realStackingContext, listItems) {\n    parent.container.elements.forEach(function (child) {\n        var treatAsRealStackingContext = contains(child.flags, 4 /* CREATES_REAL_STACKING_CONTEXT */);\n        var createsStackingContext = contains(child.flags, 2 /* CREATES_STACKING_CONTEXT */);\n        var paintContainer = new ElementPaint(child, parent);\n        if (contains(child.styles.display, 2048 /* LIST_ITEM */)) {\n            listItems.push(paintContainer);\n        }\n        var listOwnerItems = contains(child.flags, 8 /* IS_LIST_OWNER */) ? [] : listItems;\n        if (treatAsRealStackingContext || createsStackingContext) {\n            var parentStack = treatAsRealStackingContext || child.styles.isPositioned() ? realStackingContext : stackingContext;\n            var stack = new StackingContext(paintContainer);\n            if (child.styles.isPositioned() || child.styles.opacity < 1 || child.styles.isTransformed()) {\n                var order_1 = child.styles.zIndex.order;\n                if (order_1 < 0) {\n                    var index_1 = 0;\n                    parentStack.negativeZIndex.some(function (current, i) {\n                        if (order_1 > current.element.container.styles.zIndex.order) {\n                            index_1 = i;\n                            return false;\n                        }\n                        else if (index_1 > 0) {\n                            return true;\n                        }\n                        return false;\n                    });\n                    parentStack.negativeZIndex.splice(index_1, 0, stack);\n                }\n                else if (order_1 > 0) {\n                    var index_2 = 0;\n                    parentStack.positiveZIndex.some(function (current, i) {\n                        if (order_1 >= current.element.container.styles.zIndex.order) {\n                            index_2 = i + 1;\n                            return false;\n                        }\n                        else if (index_2 > 0) {\n                            return true;\n                        }\n                        return false;\n                    });\n                    parentStack.positiveZIndex.splice(index_2, 0, stack);\n                }\n                else {\n                    parentStack.zeroOrAutoZIndexOrTransformedOrOpacity.push(stack);\n                }\n            }\n            else {\n                if (child.styles.isFloating()) {\n                    parentStack.nonPositionedFloats.push(stack);\n                }\n                else {\n                    parentStack.nonPositionedInlineLevel.push(stack);\n                }\n            }\n            parseStackTree(paintContainer, stack, treatAsRealStackingContext ? stack : realStackingContext, listOwnerItems);\n        }\n        else {\n            if (child.styles.isInlineLevel()) {\n                stackingContext.inlineLevel.push(paintContainer);\n            }\n            else {\n                stackingContext.nonInlineLevel.push(paintContainer);\n            }\n            parseStackTree(paintContainer, stackingContext, realStackingContext, listOwnerItems);\n        }\n        if (contains(child.flags, 8 /* IS_LIST_OWNER */)) {\n            processListItems(child, listOwnerItems);\n        }\n    });\n};\nvar processListItems = function (owner, elements) {\n    var numbering = owner instanceof OLElementContainer ? owner.start : 1;\n    var reversed = owner instanceof OLElementContainer ? owner.reversed : false;\n    for (var i = 0; i < elements.length; i++) {\n        var item = elements[i];\n        if (item.container instanceof LIElementContainer &&\n            typeof item.container.value === 'number' &&\n            item.container.value !== 0) {\n            numbering = item.container.value;\n        }\n        item.listValue = createCounterText(numbering, item.container.styles.listStyleType, true);\n        numbering += reversed ? -1 : 1;\n    }\n};\nvar parseStackingContexts = function (container) {\n    var paintContainer = new ElementPaint(container, null);\n    var root = new StackingContext(paintContainer);\n    var listItems = [];\n    parseStackTree(paintContainer, root, root, listItems);\n    processListItems(paintContainer.container, listItems);\n    return root;\n};\n\nvar parsePathForBorder = function (curves, borderSide) {\n    switch (borderSide) {\n        case 0:\n            return createPathFromCurves(curves.topLeftBorderBox, curves.topLeftPaddingBox, curves.topRightBorderBox, curves.topRightPaddingBox);\n        case 1:\n            return createPathFromCurves(curves.topRightBorderBox, curves.topRightPaddingBox, curves.bottomRightBorderBox, curves.bottomRightPaddingBox);\n        case 2:\n            return createPathFromCurves(curves.bottomRightBorderBox, curves.bottomRightPaddingBox, curves.bottomLeftBorderBox, curves.bottomLeftPaddingBox);\n        case 3:\n        default:\n            return createPathFromCurves(curves.bottomLeftBorderBox, curves.bottomLeftPaddingBox, curves.topLeftBorderBox, curves.topLeftPaddingBox);\n    }\n};\nvar parsePathForBorderDoubleOuter = function (curves, borderSide) {\n    switch (borderSide) {\n        case 0:\n            return createPathFromCurves(curves.topLeftBorderBox, curves.topLeftBorderDoubleOuterBox, curves.topRightBorderBox, curves.topRightBorderDoubleOuterBox);\n        case 1:\n            return createPathFromCurves(curves.topRightBorderBox, curves.topRightBorderDoubleOuterBox, curves.bottomRightBorderBox, curves.bottomRightBorderDoubleOuterBox);\n        case 2:\n            return createPathFromCurves(curves.bottomRightBorderBox, curves.bottomRightBorderDoubleOuterBox, curves.bottomLeftBorderBox, curves.bottomLeftBorderDoubleOuterBox);\n        case 3:\n        default:\n            return createPathFromCurves(curves.bottomLeftBorderBox, curves.bottomLeftBorderDoubleOuterBox, curves.topLeftBorderBox, curves.topLeftBorderDoubleOuterBox);\n    }\n};\nvar parsePathForBorderDoubleInner = function (curves, borderSide) {\n    switch (borderSide) {\n        case 0:\n            return createPathFromCurves(curves.topLeftBorderDoubleInnerBox, curves.topLeftPaddingBox, curves.topRightBorderDoubleInnerBox, curves.topRightPaddingBox);\n        case 1:\n            return createPathFromCurves(curves.topRightBorderDoubleInnerBox, curves.topRightPaddingBox, curves.bottomRightBorderDoubleInnerBox, curves.bottomRightPaddingBox);\n        case 2:\n            return createPathFromCurves(curves.bottomRightBorderDoubleInnerBox, curves.bottomRightPaddingBox, curves.bottomLeftBorderDoubleInnerBox, curves.bottomLeftPaddingBox);\n        case 3:\n        default:\n            return createPathFromCurves(curves.bottomLeftBorderDoubleInnerBox, curves.bottomLeftPaddingBox, curves.topLeftBorderDoubleInnerBox, curves.topLeftPaddingBox);\n    }\n};\nvar parsePathForBorderStroke = function (curves, borderSide) {\n    switch (borderSide) {\n        case 0:\n            return createStrokePathFromCurves(curves.topLeftBorderStroke, curves.topRightBorderStroke);\n        case 1:\n            return createStrokePathFromCurves(curves.topRightBorderStroke, curves.bottomRightBorderStroke);\n        case 2:\n            return createStrokePathFromCurves(curves.bottomRightBorderStroke, curves.bottomLeftBorderStroke);\n        case 3:\n        default:\n            return createStrokePathFromCurves(curves.bottomLeftBorderStroke, curves.topLeftBorderStroke);\n    }\n};\nvar createStrokePathFromCurves = function (outer1, outer2) {\n    var path = [];\n    if (isBezierCurve(outer1)) {\n        path.push(outer1.subdivide(0.5, false));\n    }\n    else {\n        path.push(outer1);\n    }\n    if (isBezierCurve(outer2)) {\n        path.push(outer2.subdivide(0.5, true));\n    }\n    else {\n        path.push(outer2);\n    }\n    return path;\n};\nvar createPathFromCurves = function (outer1, inner1, outer2, inner2) {\n    var path = [];\n    if (isBezierCurve(outer1)) {\n        path.push(outer1.subdivide(0.5, false));\n    }\n    else {\n        path.push(outer1);\n    }\n    if (isBezierCurve(outer2)) {\n        path.push(outer2.subdivide(0.5, true));\n    }\n    else {\n        path.push(outer2);\n    }\n    if (isBezierCurve(inner2)) {\n        path.push(inner2.subdivide(0.5, true).reverse());\n    }\n    else {\n        path.push(inner2);\n    }\n    if (isBezierCurve(inner1)) {\n        path.push(inner1.subdivide(0.5, false).reverse());\n    }\n    else {\n        path.push(inner1);\n    }\n    return path;\n};\n\nvar paddingBox = function (element) {\n    var bounds = element.bounds;\n    var styles = element.styles;\n    return bounds.add(styles.borderLeftWidth, styles.borderTopWidth, -(styles.borderRightWidth + styles.borderLeftWidth), -(styles.borderTopWidth + styles.borderBottomWidth));\n};\nvar contentBox = function (element) {\n    var styles = element.styles;\n    var bounds = element.bounds;\n    var paddingLeft = getAbsoluteValue(styles.paddingLeft, bounds.width);\n    var paddingRight = getAbsoluteValue(styles.paddingRight, bounds.width);\n    var paddingTop = getAbsoluteValue(styles.paddingTop, bounds.width);\n    var paddingBottom = getAbsoluteValue(styles.paddingBottom, bounds.width);\n    return bounds.add(paddingLeft + styles.borderLeftWidth, paddingTop + styles.borderTopWidth, -(styles.borderRightWidth + styles.borderLeftWidth + paddingLeft + paddingRight), -(styles.borderTopWidth + styles.borderBottomWidth + paddingTop + paddingBottom));\n};\n\nvar calculateBackgroundPositioningArea = function (backgroundOrigin, element) {\n    if (backgroundOrigin === 0 /* BORDER_BOX */) {\n        return element.bounds;\n    }\n    if (backgroundOrigin === 2 /* CONTENT_BOX */) {\n        return contentBox(element);\n    }\n    return paddingBox(element);\n};\nvar calculateBackgroundPaintingArea = function (backgroundClip, element) {\n    if (backgroundClip === 0 /* BORDER_BOX */) {\n        return element.bounds;\n    }\n    if (backgroundClip === 2 /* CONTENT_BOX */) {\n        return contentBox(element);\n    }\n    return paddingBox(element);\n};\nvar calculateBackgroundRendering = function (container, index, intrinsicSize) {\n    var backgroundPositioningArea = calculateBackgroundPositioningArea(getBackgroundValueForIndex(container.styles.backgroundOrigin, index), container);\n    var backgroundPaintingArea = calculateBackgroundPaintingArea(getBackgroundValueForIndex(container.styles.backgroundClip, index), container);\n    var backgroundImageSize = calculateBackgroundSize(getBackgroundValueForIndex(container.styles.backgroundSize, index), intrinsicSize, backgroundPositioningArea);\n    var sizeWidth = backgroundImageSize[0], sizeHeight = backgroundImageSize[1];\n    var position = getAbsoluteValueForTuple(getBackgroundValueForIndex(container.styles.backgroundPosition, index), backgroundPositioningArea.width - sizeWidth, backgroundPositioningArea.height - sizeHeight);\n    var path = calculateBackgroundRepeatPath(getBackgroundValueForIndex(container.styles.backgroundRepeat, index), position, backgroundImageSize, backgroundPositioningArea, backgroundPaintingArea);\n    var offsetX = Math.round(backgroundPositioningArea.left + position[0]);\n    var offsetY = Math.round(backgroundPositioningArea.top + position[1]);\n    return [path, offsetX, offsetY, sizeWidth, sizeHeight];\n};\nvar isAuto = function (token) { return isIdentToken(token) && token.value === BACKGROUND_SIZE.AUTO; };\nvar hasIntrinsicValue = function (value) { return typeof value === 'number'; };\nvar calculateBackgroundSize = function (size, _a, bounds) {\n    var intrinsicWidth = _a[0], intrinsicHeight = _a[1], intrinsicProportion = _a[2];\n    var first = size[0], second = size[1];\n    if (!first) {\n        return [0, 0];\n    }\n    if (isLengthPercentage(first) && second && isLengthPercentage(second)) {\n        return [getAbsoluteValue(first, bounds.width), getAbsoluteValue(second, bounds.height)];\n    }\n    var hasIntrinsicProportion = hasIntrinsicValue(intrinsicProportion);\n    if (isIdentToken(first) && (first.value === BACKGROUND_SIZE.CONTAIN || first.value === BACKGROUND_SIZE.COVER)) {\n        if (hasIntrinsicValue(intrinsicProportion)) {\n            var targetRatio = bounds.width / bounds.height;\n            return targetRatio < intrinsicProportion !== (first.value === BACKGROUND_SIZE.COVER)\n                ? [bounds.width, bounds.width / intrinsicProportion]\n                : [bounds.height * intrinsicProportion, bounds.height];\n        }\n        return [bounds.width, bounds.height];\n    }\n    var hasIntrinsicWidth = hasIntrinsicValue(intrinsicWidth);\n    var hasIntrinsicHeight = hasIntrinsicValue(intrinsicHeight);\n    var hasIntrinsicDimensions = hasIntrinsicWidth || hasIntrinsicHeight;\n    // If the background-size is auto or auto auto:\n    if (isAuto(first) && (!second || isAuto(second))) {\n        // If the image has both horizontal and vertical intrinsic dimensions, it's rendered at that size.\n        if (hasIntrinsicWidth && hasIntrinsicHeight) {\n            return [intrinsicWidth, intrinsicHeight];\n        }\n        // If the image has no intrinsic dimensions and has no intrinsic proportions,\n        // it's rendered at the size of the background positioning area.\n        if (!hasIntrinsicProportion && !hasIntrinsicDimensions) {\n            return [bounds.width, bounds.height];\n        }\n        // TODO If the image has no intrinsic dimensions but has intrinsic proportions, it's rendered as if contain had been specified instead.\n        // If the image has only one intrinsic dimension and has intrinsic proportions, it's rendered at the size corresponding to that one dimension.\n        // The other dimension is computed using the specified dimension and the intrinsic proportions.\n        if (hasIntrinsicDimensions && hasIntrinsicProportion) {\n            var width_1 = hasIntrinsicWidth\n                ? intrinsicWidth\n                : intrinsicHeight * intrinsicProportion;\n            var height_1 = hasIntrinsicHeight\n                ? intrinsicHeight\n                : intrinsicWidth / intrinsicProportion;\n            return [width_1, height_1];\n        }\n        // If the image has only one intrinsic dimension but has no intrinsic proportions,\n        // it's rendered using the specified dimension and the other dimension of the background positioning area.\n        var width_2 = hasIntrinsicWidth ? intrinsicWidth : bounds.width;\n        var height_2 = hasIntrinsicHeight ? intrinsicHeight : bounds.height;\n        return [width_2, height_2];\n    }\n    // If the image has intrinsic proportions, it's stretched to the specified dimension.\n    // The unspecified dimension is computed using the specified dimension and the intrinsic proportions.\n    if (hasIntrinsicProportion) {\n        var width_3 = 0;\n        var height_3 = 0;\n        if (isLengthPercentage(first)) {\n            width_3 = getAbsoluteValue(first, bounds.width);\n        }\n        else if (isLengthPercentage(second)) {\n            height_3 = getAbsoluteValue(second, bounds.height);\n        }\n        if (isAuto(first)) {\n            width_3 = height_3 * intrinsicProportion;\n        }\n        else if (!second || isAuto(second)) {\n            height_3 = width_3 / intrinsicProportion;\n        }\n        return [width_3, height_3];\n    }\n    // If the image has no intrinsic proportions, it's stretched to the specified dimension.\n    // The unspecified dimension is computed using the image's corresponding intrinsic dimension,\n    // if there is one. If there is no such intrinsic dimension,\n    // it becomes the corresponding dimension of the background positioning area.\n    var width = null;\n    var height = null;\n    if (isLengthPercentage(first)) {\n        width = getAbsoluteValue(first, bounds.width);\n    }\n    else if (second && isLengthPercentage(second)) {\n        height = getAbsoluteValue(second, bounds.height);\n    }\n    if (width !== null && (!second || isAuto(second))) {\n        height =\n            hasIntrinsicWidth && hasIntrinsicHeight\n                ? (width / intrinsicWidth) * intrinsicHeight\n                : bounds.height;\n    }\n    if (height !== null && isAuto(first)) {\n        width =\n            hasIntrinsicWidth && hasIntrinsicHeight\n                ? (height / intrinsicHeight) * intrinsicWidth\n                : bounds.width;\n    }\n    if (width !== null && height !== null) {\n        return [width, height];\n    }\n    throw new Error(\"Unable to calculate background-size for element\");\n};\nvar getBackgroundValueForIndex = function (values, index) {\n    var value = values[index];\n    if (typeof value === 'undefined') {\n        return values[0];\n    }\n    return value;\n};\nvar calculateBackgroundRepeatPath = function (repeat, _a, _b, backgroundPositioningArea, backgroundPaintingArea) {\n    var x = _a[0], y = _a[1];\n    var width = _b[0], height = _b[1];\n    switch (repeat) {\n        case 2 /* REPEAT_X */:\n            return [\n                new Vector(Math.round(backgroundPositioningArea.left), Math.round(backgroundPositioningArea.top + y)),\n                new Vector(Math.round(backgroundPositioningArea.left + backgroundPositioningArea.width), Math.round(backgroundPositioningArea.top + y)),\n                new Vector(Math.round(backgroundPositioningArea.left + backgroundPositioningArea.width), Math.round(height + backgroundPositioningArea.top + y)),\n                new Vector(Math.round(backgroundPositioningArea.left), Math.round(height + backgroundPositioningArea.top + y))\n            ];\n        case 3 /* REPEAT_Y */:\n            return [\n                new Vector(Math.round(backgroundPositioningArea.left + x), Math.round(backgroundPositioningArea.top)),\n                new Vector(Math.round(backgroundPositioningArea.left + x + width), Math.round(backgroundPositioningArea.top)),\n                new Vector(Math.round(backgroundPositioningArea.left + x + width), Math.round(backgroundPositioningArea.height + backgroundPositioningArea.top)),\n                new Vector(Math.round(backgroundPositioningArea.left + x), Math.round(backgroundPositioningArea.height + backgroundPositioningArea.top))\n            ];\n        case 1 /* NO_REPEAT */:\n            return [\n                new Vector(Math.round(backgroundPositioningArea.left + x), Math.round(backgroundPositioningArea.top + y)),\n                new Vector(Math.round(backgroundPositioningArea.left + x + width), Math.round(backgroundPositioningArea.top + y)),\n                new Vector(Math.round(backgroundPositioningArea.left + x + width), Math.round(backgroundPositioningArea.top + y + height)),\n                new Vector(Math.round(backgroundPositioningArea.left + x), Math.round(backgroundPositioningArea.top + y + height))\n            ];\n        default:\n            return [\n                new Vector(Math.round(backgroundPaintingArea.left), Math.round(backgroundPaintingArea.top)),\n                new Vector(Math.round(backgroundPaintingArea.left + backgroundPaintingArea.width), Math.round(backgroundPaintingArea.top)),\n                new Vector(Math.round(backgroundPaintingArea.left + backgroundPaintingArea.width), Math.round(backgroundPaintingArea.height + backgroundPaintingArea.top)),\n                new Vector(Math.round(backgroundPaintingArea.left), Math.round(backgroundPaintingArea.height + backgroundPaintingArea.top))\n            ];\n    }\n};\n\nvar SMALL_IMAGE = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';\n\nvar SAMPLE_TEXT = 'Hidden Text';\nvar FontMetrics = /** @class */ (function () {\n    function FontMetrics(document) {\n        this._data = {};\n        this._document = document;\n    }\n    FontMetrics.prototype.parseMetrics = function (fontFamily, fontSize) {\n        var container = this._document.createElement('div');\n        var img = this._document.createElement('img');\n        var span = this._document.createElement('span');\n        var body = this._document.body;\n        container.style.visibility = 'hidden';\n        container.style.fontFamily = fontFamily;\n        container.style.fontSize = fontSize;\n        container.style.margin = '0';\n        container.style.padding = '0';\n        container.style.whiteSpace = 'nowrap';\n        body.appendChild(container);\n        img.src = SMALL_IMAGE;\n        img.width = 1;\n        img.height = 1;\n        img.style.margin = '0';\n        img.style.padding = '0';\n        img.style.verticalAlign = 'baseline';\n        span.style.fontFamily = fontFamily;\n        span.style.fontSize = fontSize;\n        span.style.margin = '0';\n        span.style.padding = '0';\n        span.appendChild(this._document.createTextNode(SAMPLE_TEXT));\n        container.appendChild(span);\n        container.appendChild(img);\n        var baseline = img.offsetTop - span.offsetTop + 2;\n        container.removeChild(span);\n        container.appendChild(this._document.createTextNode(SAMPLE_TEXT));\n        container.style.lineHeight = 'normal';\n        img.style.verticalAlign = 'super';\n        var middle = img.offsetTop - container.offsetTop + 2;\n        body.removeChild(container);\n        return { baseline: baseline, middle: middle };\n    };\n    FontMetrics.prototype.getMetrics = function (fontFamily, fontSize) {\n        var key = fontFamily + \" \" + fontSize;\n        if (typeof this._data[key] === 'undefined') {\n            this._data[key] = this.parseMetrics(fontFamily, fontSize);\n        }\n        return this._data[key];\n    };\n    return FontMetrics;\n}());\n\nvar Renderer = /** @class */ (function () {\n    function Renderer(context, options) {\n        this.context = context;\n        this.options = options;\n    }\n    return Renderer;\n}());\n\nvar MASK_OFFSET = 10000;\nvar CanvasRenderer = /** @class */ (function (_super) {\n    __extends(CanvasRenderer, _super);\n    function CanvasRenderer(context, options) {\n        var _this = _super.call(this, context, options) || this;\n        _this._activeEffects = [];\n        _this.canvas = options.canvas ? options.canvas : document.createElement('canvas');\n        _this.ctx = _this.canvas.getContext('2d');\n        if (!options.canvas) {\n            _this.canvas.width = Math.floor(options.width * options.scale);\n            _this.canvas.height = Math.floor(options.height * options.scale);\n            _this.canvas.style.width = options.width + \"px\";\n            _this.canvas.style.height = options.height + \"px\";\n        }\n        _this.fontMetrics = new FontMetrics(document);\n        _this.ctx.scale(_this.options.scale, _this.options.scale);\n        _this.ctx.translate(-options.x, -options.y);\n        _this.ctx.textBaseline = 'bottom';\n        _this._activeEffects = [];\n        _this.context.logger.debug(\"Canvas renderer initialized (\" + options.width + \"x\" + options.height + \") with scale \" + options.scale);\n        return _this;\n    }\n    CanvasRenderer.prototype.applyEffects = function (effects) {\n        var _this = this;\n        while (this._activeEffects.length) {\n            this.popEffect();\n        }\n        effects.forEach(function (effect) { return _this.applyEffect(effect); });\n    };\n    CanvasRenderer.prototype.applyEffect = function (effect) {\n        this.ctx.save();\n        if (isOpacityEffect(effect)) {\n            this.ctx.globalAlpha = effect.opacity;\n        }\n        if (isTransformEffect(effect)) {\n            this.ctx.translate(effect.offsetX, effect.offsetY);\n            this.ctx.transform(effect.matrix[0], effect.matrix[1], effect.matrix[2], effect.matrix[3], effect.matrix[4], effect.matrix[5]);\n            this.ctx.translate(-effect.offsetX, -effect.offsetY);\n        }\n        if (isClipEffect(effect)) {\n            this.path(effect.path);\n            this.ctx.clip();\n        }\n        this._activeEffects.push(effect);\n    };\n    CanvasRenderer.prototype.popEffect = function () {\n        this._activeEffects.pop();\n        this.ctx.restore();\n    };\n    CanvasRenderer.prototype.renderStack = function (stack) {\n        return __awaiter(this, void 0, void 0, function () {\n            var styles;\n            return __generator(this, function (_a) {\n                switch (_a.label) {\n                    case 0:\n                        styles = stack.element.container.styles;\n                        if (!styles.isVisible()) return [3 /*break*/, 2];\n                        return [4 /*yield*/, this.renderStackContent(stack)];\n                    case 1:\n                        _a.sent();\n                        _a.label = 2;\n                    case 2: return [2 /*return*/];\n                }\n            });\n        });\n    };\n    CanvasRenderer.prototype.renderNode = function (paint) {\n        return __awaiter(this, void 0, void 0, function () {\n            return __generator(this, function (_a) {\n                switch (_a.label) {\n                    case 0:\n                        if (contains(paint.container.flags, 16 /* DEBUG_RENDER */)) {\n                            debugger;\n                        }\n                        if (!paint.container.styles.isVisible()) return [3 /*break*/, 3];\n                        return [4 /*yield*/, this.renderNodeBackgroundAndBorders(paint)];\n                    case 1:\n                        _a.sent();\n                        return [4 /*yield*/, this.renderNodeContent(paint)];\n                    case 2:\n                        _a.sent();\n                        _a.label = 3;\n                    case 3: return [2 /*return*/];\n                }\n            });\n        });\n    };\n    CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing, baseline) {\n        var _this = this;\n        if (letterSpacing === 0) {\n            this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline);\n        }\n        else {\n            var letters = segmentGraphemes(text.text);\n            letters.reduce(function (left, letter) {\n                _this.ctx.fillText(letter, left, text.bounds.top + baseline);\n                return left + _this.ctx.measureText(letter).width;\n            }, text.bounds.left);\n        }\n    };\n    CanvasRenderer.prototype.createFontStyle = function (styles) {\n        var fontVariant = styles.fontVariant\n            .filter(function (variant) { return variant === 'normal' || variant === 'small-caps'; })\n            .join('');\n        var fontFamily = fixIOSSystemFonts(styles.fontFamily).join(', ');\n        var fontSize = isDimensionToken(styles.fontSize)\n            ? \"\" + styles.fontSize.number + styles.fontSize.unit\n            : styles.fontSize.number + \"px\";\n        return [\n            [styles.fontStyle, fontVariant, styles.fontWeight, fontSize, fontFamily].join(' '),\n            fontFamily,\n            fontSize\n        ];\n    };\n    CanvasRenderer.prototype.renderTextNode = function (text, styles) {\n        return __awaiter(this, void 0, void 0, function () {\n            var _a, font, fontFamily, fontSize, _b, baseline, middle, paintOrder;\n            var _this = this;\n            return __generator(this, function (_c) {\n                _a = this.createFontStyle(styles), font = _a[0], fontFamily = _a[1], fontSize = _a[2];\n                this.ctx.font = font;\n                this.ctx.direction = styles.direction === 1 /* RTL */ ? 'rtl' : 'ltr';\n                this.ctx.textAlign = 'left';\n                this.ctx.textBaseline = 'alphabetic';\n                _b = this.fontMetrics.getMetrics(fontFamily, fontSize), baseline = _b.baseline, middle = _b.middle;\n                paintOrder = styles.paintOrder;\n                text.textBounds.forEach(function (text) {\n                    paintOrder.forEach(function (paintOrderLayer) {\n                        switch (paintOrderLayer) {\n                            case 0 /* FILL */:\n                                _this.ctx.fillStyle = asString(styles.color);\n                                _this.renderTextWithLetterSpacing(text, styles.letterSpacing, baseline);\n                                var textShadows = styles.textShadow;\n                                if (textShadows.length && text.text.trim().length) {\n                                    textShadows\n                                        .slice(0)\n                                        .reverse()\n                                        .forEach(function (textShadow) {\n                                        _this.ctx.shadowColor = asString(textShadow.color);\n                                        _this.ctx.shadowOffsetX = textShadow.offsetX.number * _this.options.scale;\n                                        _this.ctx.shadowOffsetY = textShadow.offsetY.number * _this.options.scale;\n                                        _this.ctx.shadowBlur = textShadow.blur.number;\n                                        _this.renderTextWithLetterSpacing(text, styles.letterSpacing, baseline);\n                                    });\n                                    _this.ctx.shadowColor = '';\n                                    _this.ctx.shadowOffsetX = 0;\n                                    _this.ctx.shadowOffsetY = 0;\n                                    _this.ctx.shadowBlur = 0;\n                                }\n                                if (styles.textDecorationLine.length) {\n                                    _this.ctx.fillStyle = asString(styles.textDecorationColor || styles.color);\n                                    styles.textDecorationLine.forEach(function (textDecorationLine) {\n                                        switch (textDecorationLine) {\n                                            case 1 /* UNDERLINE */:\n                                                // Draws a line at the baseline of the font\n                                                // TODO As some browsers display the line as more than 1px if the font-size is big,\n                                                // need to take that into account both in position and size\n                                                _this.ctx.fillRect(text.bounds.left, Math.round(text.bounds.top + baseline), text.bounds.width, 1);\n                                                break;\n                                            case 2 /* OVERLINE */:\n                                                _this.ctx.fillRect(text.bounds.left, Math.round(text.bounds.top), text.bounds.width, 1);\n                                                break;\n                                            case 3 /* LINE_THROUGH */:\n                                                // TODO try and find exact position for line-through\n                                                _this.ctx.fillRect(text.bounds.left, Math.ceil(text.bounds.top + middle), text.bounds.width, 1);\n                                                break;\n                                        }\n                                    });\n                                }\n                                break;\n                            case 1 /* STROKE */:\n                                if (styles.webkitTextStrokeWidth && text.text.trim().length) {\n                                    _this.ctx.strokeStyle = asString(styles.webkitTextStrokeColor);\n                                    _this.ctx.lineWidth = styles.webkitTextStrokeWidth;\n                                    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n                                    _this.ctx.lineJoin = !!window.chrome ? 'miter' : 'round';\n                                    _this.ctx.strokeText(text.text, text.bounds.left, text.bounds.top + baseline);\n                                }\n                                _this.ctx.strokeStyle = '';\n                                _this.ctx.lineWidth = 0;\n                                _this.ctx.lineJoin = 'miter';\n                                break;\n                        }\n                    });\n                });\n                return [2 /*return*/];\n            });\n        });\n    };\n    CanvasRenderer.prototype.renderReplacedElement = function (container, curves, image) {\n        if (image && container.intrinsicWidth > 0 && container.intrinsicHeight > 0) {\n            var box = contentBox(container);\n            var path = calculatePaddingBoxPath(curves);\n            this.path(path);\n            this.ctx.save();\n            this.ctx.clip();\n            this.ctx.drawImage(image, 0, 0, container.intrinsicWidth, container.intrinsicHeight, box.left, box.top, box.width, box.height);\n            this.ctx.restore();\n        }\n    };\n    CanvasRenderer.prototype.renderNodeContent = function (paint) {\n        return __awaiter(this, void 0, void 0, function () {\n            var container, curves, styles, _i, _a, child, image, image, iframeRenderer, canvas, size, _b, fontFamily, fontSize, baseline, bounds, x, textBounds, img, image, url, fontFamily, bounds;\n            return __generator(this, function (_c) {\n                switch (_c.label) {\n                    case 0:\n                        this.applyEffects(paint.getEffects(4 /* CONTENT */));\n                        container = paint.container;\n                        curves = paint.curves;\n                        styles = container.styles;\n                        _i = 0, _a = container.textNodes;\n                        _c.label = 1;\n                    case 1:\n                        if (!(_i < _a.length)) return [3 /*break*/, 4];\n                        child = _a[_i];\n                        return [4 /*yield*/, this.renderTextNode(child, styles)];\n                    case 2:\n                        _c.sent();\n                        _c.label = 3;\n                    case 3:\n                        _i++;\n                        return [3 /*break*/, 1];\n                    case 4:\n                        if (!(container instanceof ImageElementContainer)) return [3 /*break*/, 8];\n                        _c.label = 5;\n                    case 5:\n                        _c.trys.push([5, 7, , 8]);\n                        return [4 /*yield*/, this.context.cache.match(container.src)];\n                    case 6:\n                        image = _c.sent();\n                        this.renderReplacedElement(container, curves, image);\n                        return [3 /*break*/, 8];\n                    case 7:\n                        _c.sent();\n                        this.context.logger.error(\"Error loading image \" + container.src);\n                        return [3 /*break*/, 8];\n                    case 8:\n                        if (container instanceof CanvasElementContainer) {\n                            this.renderReplacedElement(container, curves, container.canvas);\n                        }\n                        if (!(container instanceof SVGElementContainer)) return [3 /*break*/, 12];\n                        _c.label = 9;\n                    case 9:\n                        _c.trys.push([9, 11, , 12]);\n                        return [4 /*yield*/, this.context.cache.match(container.svg)];\n                    case 10:\n                        image = _c.sent();\n                        this.renderReplacedElement(container, curves, image);\n                        return [3 /*break*/, 12];\n                    case 11:\n                        _c.sent();\n                        this.context.logger.error(\"Error loading svg \" + container.svg.substring(0, 255));\n                        return [3 /*break*/, 12];\n                    case 12:\n                        if (!(container instanceof IFrameElementContainer && container.tree)) return [3 /*break*/, 14];\n                        iframeRenderer = new CanvasRenderer(this.context, {\n                            scale: this.options.scale,\n                            backgroundColor: container.backgroundColor,\n                            x: 0,\n                            y: 0,\n                            width: container.width,\n                            height: container.height\n                        });\n                        return [4 /*yield*/, iframeRenderer.render(container.tree)];\n                    case 13:\n                        canvas = _c.sent();\n                        if (container.width && container.height) {\n                            this.ctx.drawImage(canvas, 0, 0, container.width, container.height, container.bounds.left, container.bounds.top, container.bounds.width, container.bounds.height);\n                        }\n                        _c.label = 14;\n                    case 14:\n                        if (container instanceof InputElementContainer) {\n                            size = Math.min(container.bounds.width, container.bounds.height);\n                            if (container.type === CHECKBOX) {\n                                if (container.checked) {\n                                    this.ctx.save();\n                                    this.path([\n                                        new Vector(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79),\n                                        new Vector(container.bounds.left + size * 0.16, container.bounds.top + size * 0.5549),\n                                        new Vector(container.bounds.left + size * 0.27347, container.bounds.top + size * 0.44071),\n                                        new Vector(container.bounds.left + size * 0.39694, container.bounds.top + size * 0.5649),\n                                        new Vector(container.bounds.left + size * 0.72983, container.bounds.top + size * 0.23),\n                                        new Vector(container.bounds.left + size * 0.84, container.bounds.top + size * 0.34085),\n                                        new Vector(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79)\n                                    ]);\n                                    this.ctx.fillStyle = asString(INPUT_COLOR);\n                                    this.ctx.fill();\n                                    this.ctx.restore();\n                                }\n                            }\n                            else if (container.type === RADIO) {\n                                if (container.checked) {\n                                    this.ctx.save();\n                                    this.ctx.beginPath();\n                                    this.ctx.arc(container.bounds.left + size / 2, container.bounds.top + size / 2, size / 4, 0, Math.PI * 2, true);\n                                    this.ctx.fillStyle = asString(INPUT_COLOR);\n                                    this.ctx.fill();\n                                    this.ctx.restore();\n                                }\n                            }\n                        }\n                        if (isTextInputElement(container) && container.value.length) {\n                            _b = this.createFontStyle(styles), fontFamily = _b[0], fontSize = _b[1];\n                            baseline = this.fontMetrics.getMetrics(fontFamily, fontSize).baseline;\n                            this.ctx.font = fontFamily;\n                            this.ctx.fillStyle = asString(styles.color);\n                            this.ctx.textBaseline = 'alphabetic';\n                            this.ctx.textAlign = canvasTextAlign(container.styles.textAlign);\n                            bounds = contentBox(container);\n                            x = 0;\n                            switch (container.styles.textAlign) {\n                                case 1 /* CENTER */:\n                                    x += bounds.width / 2;\n                                    break;\n                                case 2 /* RIGHT */:\n                                    x += bounds.width;\n                                    break;\n                            }\n                            textBounds = bounds.add(x, 0, 0, -bounds.height / 2 + 1);\n                            this.ctx.save();\n                            this.path([\n                                new Vector(bounds.left, bounds.top),\n                                new Vector(bounds.left + bounds.width, bounds.top),\n                                new Vector(bounds.left + bounds.width, bounds.top + bounds.height),\n                                new Vector(bounds.left, bounds.top + bounds.height)\n                            ]);\n                            this.ctx.clip();\n                            this.renderTextWithLetterSpacing(new TextBounds(container.value, textBounds), styles.letterSpacing, baseline);\n                            this.ctx.restore();\n                            this.ctx.textBaseline = 'alphabetic';\n                            this.ctx.textAlign = 'left';\n                        }\n                        if (!contains(container.styles.display, 2048 /* LIST_ITEM */)) return [3 /*break*/, 20];\n                        if (!(container.styles.listStyleImage !== null)) return [3 /*break*/, 19];\n                        img = container.styles.listStyleImage;\n                        if (!(img.type === 0 /* URL */)) return [3 /*break*/, 18];\n                        image = void 0;\n                        url = img.url;\n                        _c.label = 15;\n                    case 15:\n                        _c.trys.push([15, 17, , 18]);\n                        return [4 /*yield*/, this.context.cache.match(url)];\n                    case 16:\n                        image = _c.sent();\n                        this.ctx.drawImage(image, container.bounds.left - (image.width + 10), container.bounds.top);\n                        return [3 /*break*/, 18];\n                    case 17:\n                        _c.sent();\n                        this.context.logger.error(\"Error loading list-style-image \" + url);\n                        return [3 /*break*/, 18];\n                    case 18: return [3 /*break*/, 20];\n                    case 19:\n                        if (paint.listValue && container.styles.listStyleType !== -1 /* NONE */) {\n                            fontFamily = this.createFontStyle(styles)[0];\n                            this.ctx.font = fontFamily;\n                            this.ctx.fillStyle = asString(styles.color);\n                            this.ctx.textBaseline = 'middle';\n                            this.ctx.textAlign = 'right';\n                            bounds = new Bounds(container.bounds.left, container.bounds.top + getAbsoluteValue(container.styles.paddingTop, container.bounds.width), container.bounds.width, computeLineHeight(styles.lineHeight, styles.fontSize.number) / 2 + 1);\n                            this.renderTextWithLetterSpacing(new TextBounds(paint.listValue, bounds), styles.letterSpacing, computeLineHeight(styles.lineHeight, styles.fontSize.number) / 2 + 2);\n                            this.ctx.textBaseline = 'bottom';\n                            this.ctx.textAlign = 'left';\n                        }\n                        _c.label = 20;\n                    case 20: return [2 /*return*/];\n                }\n            });\n        });\n    };\n    CanvasRenderer.prototype.renderStackContent = function (stack) {\n        return __awaiter(this, void 0, void 0, function () {\n            var _i, _a, child, _b, _c, child, _d, _e, child, _f, _g, child, _h, _j, child, _k, _l, child, _m, _o, child;\n            return __generator(this, function (_p) {\n                switch (_p.label) {\n                    case 0:\n                        if (contains(stack.element.container.flags, 16 /* DEBUG_RENDER */)) {\n                            debugger;\n                        }\n                        // https://www.w3.org/TR/css-position-3/#painting-order\n                        // 1. the background and borders of the element forming the stacking context.\n                        return [4 /*yield*/, this.renderNodeBackgroundAndBorders(stack.element)];\n                    case 1:\n                        // https://www.w3.org/TR/css-position-3/#painting-order\n                        // 1. the background and borders of the element forming the stacking context.\n                        _p.sent();\n                        _i = 0, _a = stack.negativeZIndex;\n                        _p.label = 2;\n                    case 2:\n                        if (!(_i < _a.length)) return [3 /*break*/, 5];\n                        child = _a[_i];\n                        return [4 /*yield*/, this.renderStack(child)];\n                    case 3:\n                        _p.sent();\n                        _p.label = 4;\n                    case 4:\n                        _i++;\n                        return [3 /*break*/, 2];\n                    case 5: \n                    // 3. For all its in-flow, non-positioned, block-level descendants in tree order:\n                    return [4 /*yield*/, this.renderNodeContent(stack.element)];\n                    case 6:\n                        // 3. For all its in-flow, non-positioned, block-level descendants in tree order:\n                        _p.sent();\n                        _b = 0, _c = stack.nonInlineLevel;\n                        _p.label = 7;\n                    case 7:\n                        if (!(_b < _c.length)) return [3 /*break*/, 10];\n                        child = _c[_b];\n                        return [4 /*yield*/, this.renderNode(child)];\n                    case 8:\n                        _p.sent();\n                        _p.label = 9;\n                    case 9:\n                        _b++;\n                        return [3 /*break*/, 7];\n                    case 10:\n                        _d = 0, _e = stack.nonPositionedFloats;\n                        _p.label = 11;\n                    case 11:\n                        if (!(_d < _e.length)) return [3 /*break*/, 14];\n                        child = _e[_d];\n                        return [4 /*yield*/, this.renderStack(child)];\n                    case 12:\n                        _p.sent();\n                        _p.label = 13;\n                    case 13:\n                        _d++;\n                        return [3 /*break*/, 11];\n                    case 14:\n                        _f = 0, _g = stack.nonPositionedInlineLevel;\n                        _p.label = 15;\n                    case 15:\n                        if (!(_f < _g.length)) return [3 /*break*/, 18];\n                        child = _g[_f];\n                        return [4 /*yield*/, this.renderStack(child)];\n                    case 16:\n                        _p.sent();\n                        _p.label = 17;\n                    case 17:\n                        _f++;\n                        return [3 /*break*/, 15];\n                    case 18:\n                        _h = 0, _j = stack.inlineLevel;\n                        _p.label = 19;\n                    case 19:\n                        if (!(_h < _j.length)) return [3 /*break*/, 22];\n                        child = _j[_h];\n                        return [4 /*yield*/, this.renderNode(child)];\n                    case 20:\n                        _p.sent();\n                        _p.label = 21;\n                    case 21:\n                        _h++;\n                        return [3 /*break*/, 19];\n                    case 22:\n                        _k = 0, _l = stack.zeroOrAutoZIndexOrTransformedOrOpacity;\n                        _p.label = 23;\n                    case 23:\n                        if (!(_k < _l.length)) return [3 /*break*/, 26];\n                        child = _l[_k];\n                        return [4 /*yield*/, this.renderStack(child)];\n                    case 24:\n                        _p.sent();\n                        _p.label = 25;\n                    case 25:\n                        _k++;\n                        return [3 /*break*/, 23];\n                    case 26:\n                        _m = 0, _o = stack.positiveZIndex;\n                        _p.label = 27;\n                    case 27:\n                        if (!(_m < _o.length)) return [3 /*break*/, 30];\n                        child = _o[_m];\n                        return [4 /*yield*/, this.renderStack(child)];\n                    case 28:\n                        _p.sent();\n                        _p.label = 29;\n                    case 29:\n                        _m++;\n                        return [3 /*break*/, 27];\n                    case 30: return [2 /*return*/];\n                }\n            });\n        });\n    };\n    CanvasRenderer.prototype.mask = function (paths) {\n        this.ctx.beginPath();\n        this.ctx.moveTo(0, 0);\n        this.ctx.lineTo(this.canvas.width, 0);\n        this.ctx.lineTo(this.canvas.width, this.canvas.height);\n        this.ctx.lineTo(0, this.canvas.height);\n        this.ctx.lineTo(0, 0);\n        this.formatPath(paths.slice(0).reverse());\n        this.ctx.closePath();\n    };\n    CanvasRenderer.prototype.path = function (paths) {\n        this.ctx.beginPath();\n        this.formatPath(paths);\n        this.ctx.closePath();\n    };\n    CanvasRenderer.prototype.formatPath = function (paths) {\n        var _this = this;\n        paths.forEach(function (point, index) {\n            var start = isBezierCurve(point) ? point.start : point;\n            if (index === 0) {\n                _this.ctx.moveTo(start.x, start.y);\n            }\n            else {\n                _this.ctx.lineTo(start.x, start.y);\n            }\n            if (isBezierCurve(point)) {\n                _this.ctx.bezierCurveTo(point.startControl.x, point.startControl.y, point.endControl.x, point.endControl.y, point.end.x, point.end.y);\n            }\n        });\n    };\n    CanvasRenderer.prototype.renderRepeat = function (path, pattern, offsetX, offsetY) {\n        this.path(path);\n        this.ctx.fillStyle = pattern;\n        this.ctx.translate(offsetX, offsetY);\n        this.ctx.fill();\n        this.ctx.translate(-offsetX, -offsetY);\n    };\n    CanvasRenderer.prototype.resizeImage = function (image, width, height) {\n        var _a;\n        if (image.width === width && image.height === height) {\n            return image;\n        }\n        var ownerDocument = (_a = this.canvas.ownerDocument) !== null && _a !== void 0 ? _a : document;\n        var canvas = ownerDocument.createElement('canvas');\n        canvas.width = Math.max(1, width);\n        canvas.height = Math.max(1, height);\n        var ctx = canvas.getContext('2d');\n        ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, width, height);\n        return canvas;\n    };\n    CanvasRenderer.prototype.renderBackgroundImage = function (container) {\n        return __awaiter(this, void 0, void 0, function () {\n            var index, _loop_1, this_1, _i, _a, backgroundImage;\n            return __generator(this, function (_b) {\n                switch (_b.label) {\n                    case 0:\n                        index = container.styles.backgroundImage.length - 1;\n                        _loop_1 = function (backgroundImage) {\n                            var image, url, _c, path, x, y, width, height, pattern, _d, path, x, y, width, height, _e, lineLength, x0, x1, y0, y1, canvas, ctx, gradient_1, pattern, _f, path, left, top_1, width, height, position, x, y, _g, rx, ry, radialGradient_1, midX, midY, f, invF;\n                            return __generator(this, function (_h) {\n                                switch (_h.label) {\n                                    case 0:\n                                        if (!(backgroundImage.type === 0 /* URL */)) return [3 /*break*/, 5];\n                                        image = void 0;\n                                        url = backgroundImage.url;\n                                        _h.label = 1;\n                                    case 1:\n                                        _h.trys.push([1, 3, , 4]);\n                                        return [4 /*yield*/, this_1.context.cache.match(url)];\n                                    case 2:\n                                        image = _h.sent();\n                                        return [3 /*break*/, 4];\n                                    case 3:\n                                        _h.sent();\n                                        this_1.context.logger.error(\"Error loading background-image \" + url);\n                                        return [3 /*break*/, 4];\n                                    case 4:\n                                        if (image) {\n                                            _c = calculateBackgroundRendering(container, index, [\n                                                image.width,\n                                                image.height,\n                                                image.width / image.height\n                                            ]), path = _c[0], x = _c[1], y = _c[2], width = _c[3], height = _c[4];\n                                            pattern = this_1.ctx.createPattern(this_1.resizeImage(image, width, height), 'repeat');\n                                            this_1.renderRepeat(path, pattern, x, y);\n                                        }\n                                        return [3 /*break*/, 6];\n                                    case 5:\n                                        if (isLinearGradient(backgroundImage)) {\n                                            _d = calculateBackgroundRendering(container, index, [null, null, null]), path = _d[0], x = _d[1], y = _d[2], width = _d[3], height = _d[4];\n                                            _e = calculateGradientDirection(backgroundImage.angle, width, height), lineLength = _e[0], x0 = _e[1], x1 = _e[2], y0 = _e[3], y1 = _e[4];\n                                            canvas = document.createElement('canvas');\n                                            canvas.width = width;\n                                            canvas.height = height;\n                                            ctx = canvas.getContext('2d');\n                                            gradient_1 = ctx.createLinearGradient(x0, y0, x1, y1);\n                                            processColorStops(backgroundImage.stops, lineLength).forEach(function (colorStop) {\n                                                return gradient_1.addColorStop(colorStop.stop, asString(colorStop.color));\n                                            });\n                                            ctx.fillStyle = gradient_1;\n                                            ctx.fillRect(0, 0, width, height);\n                                            if (width > 0 && height > 0) {\n                                                pattern = this_1.ctx.createPattern(canvas, 'repeat');\n                                                this_1.renderRepeat(path, pattern, x, y);\n                                            }\n                                        }\n                                        else if (isRadialGradient(backgroundImage)) {\n                                            _f = calculateBackgroundRendering(container, index, [\n                                                null,\n                                                null,\n                                                null\n                                            ]), path = _f[0], left = _f[1], top_1 = _f[2], width = _f[3], height = _f[4];\n                                            position = backgroundImage.position.length === 0 ? [FIFTY_PERCENT] : backgroundImage.position;\n                                            x = getAbsoluteValue(position[0], width);\n                                            y = getAbsoluteValue(position[position.length - 1], height);\n                                            _g = calculateRadius(backgroundImage, x, y, width, height), rx = _g[0], ry = _g[1];\n                                            if (rx > 0 && ry > 0) {\n                                                radialGradient_1 = this_1.ctx.createRadialGradient(left + x, top_1 + y, 0, left + x, top_1 + y, rx);\n                                                processColorStops(backgroundImage.stops, rx * 2).forEach(function (colorStop) {\n                                                    return radialGradient_1.addColorStop(colorStop.stop, asString(colorStop.color));\n                                                });\n                                                this_1.path(path);\n                                                this_1.ctx.fillStyle = radialGradient_1;\n                                                if (rx !== ry) {\n                                                    midX = container.bounds.left + 0.5 * container.bounds.width;\n                                                    midY = container.bounds.top + 0.5 * container.bounds.height;\n                                                    f = ry / rx;\n                                                    invF = 1 / f;\n                                                    this_1.ctx.save();\n                                                    this_1.ctx.translate(midX, midY);\n                                                    this_1.ctx.transform(1, 0, 0, f, 0, 0);\n                                                    this_1.ctx.translate(-midX, -midY);\n                                                    this_1.ctx.fillRect(left, invF * (top_1 - midY) + midY, width, height * invF);\n                                                    this_1.ctx.restore();\n                                                }\n                                                else {\n                                                    this_1.ctx.fill();\n                                                }\n                                            }\n                                        }\n                                        _h.label = 6;\n                                    case 6:\n                                        index--;\n                                        return [2 /*return*/];\n                                }\n                            });\n                        };\n                        this_1 = this;\n                        _i = 0, _a = container.styles.backgroundImage.slice(0).reverse();\n                        _b.label = 1;\n                    case 1:\n                        if (!(_i < _a.length)) return [3 /*break*/, 4];\n                        backgroundImage = _a[_i];\n                        return [5 /*yield**/, _loop_1(backgroundImage)];\n                    case 2:\n                        _b.sent();\n                        _b.label = 3;\n                    case 3:\n                        _i++;\n                        return [3 /*break*/, 1];\n                    case 4: return [2 /*return*/];\n                }\n            });\n        });\n    };\n    CanvasRenderer.prototype.renderSolidBorder = function (color, side, curvePoints) {\n        return __awaiter(this, void 0, void 0, function () {\n            return __generator(this, function (_a) {\n                this.path(parsePathForBorder(curvePoints, side));\n                this.ctx.fillStyle = asString(color);\n                this.ctx.fill();\n                return [2 /*return*/];\n            });\n        });\n    };\n    CanvasRenderer.prototype.renderDoubleBorder = function (color, width, side, curvePoints) {\n        return __awaiter(this, void 0, void 0, function () {\n            var outerPaths, innerPaths;\n            return __generator(this, function (_a) {\n                switch (_a.label) {\n                    case 0:\n                        if (!(width < 3)) return [3 /*break*/, 2];\n                        return [4 /*yield*/, this.renderSolidBorder(color, side, curvePoints)];\n                    case 1:\n                        _a.sent();\n                        return [2 /*return*/];\n                    case 2:\n                        outerPaths = parsePathForBorderDoubleOuter(curvePoints, side);\n                        this.path(outerPaths);\n                        this.ctx.fillStyle = asString(color);\n                        this.ctx.fill();\n                        innerPaths = parsePathForBorderDoubleInner(curvePoints, side);\n                        this.path(innerPaths);\n                        this.ctx.fill();\n                        return [2 /*return*/];\n                }\n            });\n        });\n    };\n    CanvasRenderer.prototype.renderNodeBackgroundAndBorders = function (paint) {\n        return __awaiter(this, void 0, void 0, function () {\n            var styles, hasBackground, borders, backgroundPaintingArea, side, _i, borders_1, border;\n            var _this = this;\n            return __generator(this, function (_a) {\n                switch (_a.label) {\n                    case 0:\n                        this.applyEffects(paint.getEffects(2 /* BACKGROUND_BORDERS */));\n                        styles = paint.container.styles;\n                        hasBackground = !isTransparent(styles.backgroundColor) || styles.backgroundImage.length;\n                        borders = [\n                            { style: styles.borderTopStyle, color: styles.borderTopColor, width: styles.borderTopWidth },\n                            { style: styles.borderRightStyle, color: styles.borderRightColor, width: styles.borderRightWidth },\n                            { style: styles.borderBottomStyle, color: styles.borderBottomColor, width: styles.borderBottomWidth },\n                            { style: styles.borderLeftStyle, color: styles.borderLeftColor, width: styles.borderLeftWidth }\n                        ];\n                        backgroundPaintingArea = calculateBackgroundCurvedPaintingArea(getBackgroundValueForIndex(styles.backgroundClip, 0), paint.curves);\n                        if (!(hasBackground || styles.boxShadow.length)) return [3 /*break*/, 2];\n                        this.ctx.save();\n                        this.path(backgroundPaintingArea);\n                        this.ctx.clip();\n                        if (!isTransparent(styles.backgroundColor)) {\n                            this.ctx.fillStyle = asString(styles.backgroundColor);\n                            this.ctx.fill();\n                        }\n                        return [4 /*yield*/, this.renderBackgroundImage(paint.container)];\n                    case 1:\n                        _a.sent();\n                        this.ctx.restore();\n                        styles.boxShadow\n                            .slice(0)\n                            .reverse()\n                            .forEach(function (shadow) {\n                            _this.ctx.save();\n                            var borderBoxArea = calculateBorderBoxPath(paint.curves);\n                            var maskOffset = shadow.inset ? 0 : MASK_OFFSET;\n                            var shadowPaintingArea = transformPath(borderBoxArea, -maskOffset + (shadow.inset ? 1 : -1) * shadow.spread.number, (shadow.inset ? 1 : -1) * shadow.spread.number, shadow.spread.number * (shadow.inset ? -2 : 2), shadow.spread.number * (shadow.inset ? -2 : 2));\n                            if (shadow.inset) {\n                                _this.path(borderBoxArea);\n                                _this.ctx.clip();\n                                _this.mask(shadowPaintingArea);\n                            }\n                            else {\n                                _this.mask(borderBoxArea);\n                                _this.ctx.clip();\n                                _this.path(shadowPaintingArea);\n                            }\n                            _this.ctx.shadowOffsetX = shadow.offsetX.number + maskOffset;\n                            _this.ctx.shadowOffsetY = shadow.offsetY.number;\n                            _this.ctx.shadowColor = asString(shadow.color);\n                            _this.ctx.shadowBlur = shadow.blur.number;\n                            _this.ctx.fillStyle = shadow.inset ? asString(shadow.color) : 'rgba(0,0,0,1)';\n                            _this.ctx.fill();\n                            _this.ctx.restore();\n                        });\n                        _a.label = 2;\n                    case 2:\n                        side = 0;\n                        _i = 0, borders_1 = borders;\n                        _a.label = 3;\n                    case 3:\n                        if (!(_i < borders_1.length)) return [3 /*break*/, 13];\n                        border = borders_1[_i];\n                        if (!(border.style !== 0 /* NONE */ && !isTransparent(border.color) && border.width > 0)) return [3 /*break*/, 11];\n                        if (!(border.style === 2 /* DASHED */)) return [3 /*break*/, 5];\n                        return [4 /*yield*/, this.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 2 /* DASHED */)];\n                    case 4:\n                        _a.sent();\n                        return [3 /*break*/, 11];\n                    case 5:\n                        if (!(border.style === 3 /* DOTTED */)) return [3 /*break*/, 7];\n                        return [4 /*yield*/, this.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 3 /* DOTTED */)];\n                    case 6:\n                        _a.sent();\n                        return [3 /*break*/, 11];\n                    case 7:\n                        if (!(border.style === 4 /* DOUBLE */)) return [3 /*break*/, 9];\n                        return [4 /*yield*/, this.renderDoubleBorder(border.color, border.width, side, paint.curves)];\n                    case 8:\n                        _a.sent();\n                        return [3 /*break*/, 11];\n                    case 9: return [4 /*yield*/, this.renderSolidBorder(border.color, side, paint.curves)];\n                    case 10:\n                        _a.sent();\n                        _a.label = 11;\n                    case 11:\n                        side++;\n                        _a.label = 12;\n                    case 12:\n                        _i++;\n                        return [3 /*break*/, 3];\n                    case 13: return [2 /*return*/];\n                }\n            });\n        });\n    };\n    CanvasRenderer.prototype.renderDashedDottedBorder = function (color, width, side, curvePoints, style) {\n        return __awaiter(this, void 0, void 0, function () {\n            var strokePaths, boxPaths, startX, startY, endX, endY, length, dashLength, spaceLength, useLineDash, multiplier, numberOfDashes, minSpace, maxSpace, path1, path2, path1, path2;\n            return __generator(this, function (_a) {\n                this.ctx.save();\n                strokePaths = parsePathForBorderStroke(curvePoints, side);\n                boxPaths = parsePathForBorder(curvePoints, side);\n                if (style === 2 /* DASHED */) {\n                    this.path(boxPaths);\n                    this.ctx.clip();\n                }\n                if (isBezierCurve(boxPaths[0])) {\n                    startX = boxPaths[0].start.x;\n                    startY = boxPaths[0].start.y;\n                }\n                else {\n                    startX = boxPaths[0].x;\n                    startY = boxPaths[0].y;\n                }\n                if (isBezierCurve(boxPaths[1])) {\n                    endX = boxPaths[1].end.x;\n                    endY = boxPaths[1].end.y;\n                }\n                else {\n                    endX = boxPaths[1].x;\n                    endY = boxPaths[1].y;\n                }\n                if (side === 0 || side === 2) {\n                    length = Math.abs(startX - endX);\n                }\n                else {\n                    length = Math.abs(startY - endY);\n                }\n                this.ctx.beginPath();\n                if (style === 3 /* DOTTED */) {\n                    this.formatPath(strokePaths);\n                }\n                else {\n                    this.formatPath(boxPaths.slice(0, 2));\n                }\n                dashLength = width < 3 ? width * 3 : width * 2;\n                spaceLength = width < 3 ? width * 2 : width;\n                if (style === 3 /* DOTTED */) {\n                    dashLength = width;\n                    spaceLength = width;\n                }\n                useLineDash = true;\n                if (length <= dashLength * 2) {\n                    useLineDash = false;\n                }\n                else if (length <= dashLength * 2 + spaceLength) {\n                    multiplier = length / (2 * dashLength + spaceLength);\n                    dashLength *= multiplier;\n                    spaceLength *= multiplier;\n                }\n                else {\n                    numberOfDashes = Math.floor((length + spaceLength) / (dashLength + spaceLength));\n                    minSpace = (length - numberOfDashes * dashLength) / (numberOfDashes - 1);\n                    maxSpace = (length - (numberOfDashes + 1) * dashLength) / numberOfDashes;\n                    spaceLength =\n                        maxSpace <= 0 || Math.abs(spaceLength - minSpace) < Math.abs(spaceLength - maxSpace)\n                            ? minSpace\n                            : maxSpace;\n                }\n                if (useLineDash) {\n                    if (style === 3 /* DOTTED */) {\n                        this.ctx.setLineDash([0, dashLength + spaceLength]);\n                    }\n                    else {\n                        this.ctx.setLineDash([dashLength, spaceLength]);\n                    }\n                }\n                if (style === 3 /* DOTTED */) {\n                    this.ctx.lineCap = 'round';\n                    this.ctx.lineWidth = width;\n                }\n                else {\n                    this.ctx.lineWidth = width * 2 + 1.1;\n                }\n                this.ctx.strokeStyle = asString(color);\n                this.ctx.stroke();\n                this.ctx.setLineDash([]);\n                // dashed round edge gap\n                if (style === 2 /* DASHED */) {\n                    if (isBezierCurve(boxPaths[0])) {\n                        path1 = boxPaths[3];\n                        path2 = boxPaths[0];\n                        this.ctx.beginPath();\n                        this.formatPath([new Vector(path1.end.x, path1.end.y), new Vector(path2.start.x, path2.start.y)]);\n                        this.ctx.stroke();\n                    }\n                    if (isBezierCurve(boxPaths[1])) {\n                        path1 = boxPaths[1];\n                        path2 = boxPaths[2];\n                        this.ctx.beginPath();\n                        this.formatPath([new Vector(path1.end.x, path1.end.y), new Vector(path2.start.x, path2.start.y)]);\n                        this.ctx.stroke();\n                    }\n                }\n                this.ctx.restore();\n                return [2 /*return*/];\n            });\n        });\n    };\n    CanvasRenderer.prototype.render = function (element) {\n        return __awaiter(this, void 0, void 0, function () {\n            var stack;\n            return __generator(this, function (_a) {\n                switch (_a.label) {\n                    case 0:\n                        if (this.options.backgroundColor) {\n                            this.ctx.fillStyle = asString(this.options.backgroundColor);\n                            this.ctx.fillRect(this.options.x, this.options.y, this.options.width, this.options.height);\n                        }\n                        stack = parseStackingContexts(element);\n                        return [4 /*yield*/, this.renderStack(stack)];\n                    case 1:\n                        _a.sent();\n                        this.applyEffects([]);\n                        return [2 /*return*/, this.canvas];\n                }\n            });\n        });\n    };\n    return CanvasRenderer;\n}(Renderer));\nvar isTextInputElement = function (container) {\n    if (container instanceof TextareaElementContainer) {\n        return true;\n    }\n    else if (container instanceof SelectElementContainer) {\n        return true;\n    }\n    else if (container instanceof InputElementContainer && container.type !== RADIO && container.type !== CHECKBOX) {\n        return true;\n    }\n    return false;\n};\nvar calculateBackgroundCurvedPaintingArea = function (clip, curves) {\n    switch (clip) {\n        case 0 /* BORDER_BOX */:\n            return calculateBorderBoxPath(curves);\n        case 2 /* CONTENT_BOX */:\n            return calculateContentBoxPath(curves);\n        case 1 /* PADDING_BOX */:\n        default:\n            return calculatePaddingBoxPath(curves);\n    }\n};\nvar canvasTextAlign = function (textAlign) {\n    switch (textAlign) {\n        case 1 /* CENTER */:\n            return 'center';\n        case 2 /* RIGHT */:\n            return 'right';\n        case 0 /* LEFT */:\n        default:\n            return 'left';\n    }\n};\n// see https://github.com/niklasvh/html2canvas/pull/2645\nvar iOSBrokenFonts = ['-apple-system', 'system-ui'];\nvar fixIOSSystemFonts = function (fontFamilies) {\n    return /iPhone OS 15_(0|1)/.test(window.navigator.userAgent)\n        ? fontFamilies.filter(function (fontFamily) { return iOSBrokenFonts.indexOf(fontFamily) === -1; })\n        : fontFamilies;\n};\n\nvar ForeignObjectRenderer = /** @class */ (function (_super) {\n    __extends(ForeignObjectRenderer, _super);\n    function ForeignObjectRenderer(context, options) {\n        var _this = _super.call(this, context, options) || this;\n        _this.canvas = options.canvas ? options.canvas : document.createElement('canvas');\n        _this.ctx = _this.canvas.getContext('2d');\n        _this.options = options;\n        _this.canvas.width = Math.floor(options.width * options.scale);\n        _this.canvas.height = Math.floor(options.height * options.scale);\n        _this.canvas.style.width = options.width + \"px\";\n        _this.canvas.style.height = options.height + \"px\";\n        _this.ctx.scale(_this.options.scale, _this.options.scale);\n        _this.ctx.translate(-options.x, -options.y);\n        _this.context.logger.debug(\"EXPERIMENTAL ForeignObject renderer initialized (\" + options.width + \"x\" + options.height + \" at \" + options.x + \",\" + options.y + \") with scale \" + options.scale);\n        return _this;\n    }\n    ForeignObjectRenderer.prototype.render = function (element) {\n        return __awaiter(this, void 0, void 0, function () {\n            var svg, img;\n            return __generator(this, function (_a) {\n                switch (_a.label) {\n                    case 0:\n                        svg = createForeignObjectSVG(this.options.width * this.options.scale, this.options.height * this.options.scale, this.options.scale, this.options.scale, element);\n                        return [4 /*yield*/, loadSerializedSVG(svg)];\n                    case 1:\n                        img = _a.sent();\n                        if (this.options.backgroundColor) {\n                            this.ctx.fillStyle = asString(this.options.backgroundColor);\n                            this.ctx.fillRect(0, 0, this.options.width * this.options.scale, this.options.height * this.options.scale);\n                        }\n                        this.ctx.drawImage(img, -this.options.x * this.options.scale, -this.options.y * this.options.scale);\n                        return [2 /*return*/, this.canvas];\n                }\n            });\n        });\n    };\n    return ForeignObjectRenderer;\n}(Renderer));\nvar loadSerializedSVG = function (svg) {\n    return new Promise(function (resolve, reject) {\n        var img = new Image();\n        img.onload = function () {\n            resolve(img);\n        };\n        img.onerror = reject;\n        img.src = \"data:image/svg+xml;charset=utf-8,\" + encodeURIComponent(new XMLSerializer().serializeToString(svg));\n    });\n};\n\nvar Logger = /** @class */ (function () {\n    function Logger(_a) {\n        var id = _a.id, enabled = _a.enabled;\n        this.id = id;\n        this.enabled = enabled;\n        this.start = Date.now();\n    }\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    Logger.prototype.debug = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n            args[_i] = arguments[_i];\n        }\n        if (this.enabled) {\n            // eslint-disable-next-line no-console\n            if (typeof window !== 'undefined' && window.console && typeof console.debug === 'function') {\n                // eslint-disable-next-line no-console\n                console.debug.apply(console, __spreadArray([this.id, this.getTime() + \"ms\"], args));\n            }\n            else {\n                this.info.apply(this, args);\n            }\n        }\n    };\n    Logger.prototype.getTime = function () {\n        return Date.now() - this.start;\n    };\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    Logger.prototype.info = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n            args[_i] = arguments[_i];\n        }\n        if (this.enabled) {\n            // eslint-disable-next-line no-console\n            if (typeof window !== 'undefined' && window.console && typeof console.info === 'function') {\n                // eslint-disable-next-line no-console\n                console.info.apply(console, __spreadArray([this.id, this.getTime() + \"ms\"], args));\n            }\n        }\n    };\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    Logger.prototype.warn = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n            args[_i] = arguments[_i];\n        }\n        if (this.enabled) {\n            // eslint-disable-next-line no-console\n            if (typeof window !== 'undefined' && window.console && typeof console.warn === 'function') {\n                // eslint-disable-next-line no-console\n                console.warn.apply(console, __spreadArray([this.id, this.getTime() + \"ms\"], args));\n            }\n            else {\n                this.info.apply(this, args);\n            }\n        }\n    };\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    Logger.prototype.error = function () {\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n            args[_i] = arguments[_i];\n        }\n        if (this.enabled) {\n            // eslint-disable-next-line no-console\n            if (typeof window !== 'undefined' && window.console && typeof console.error === 'function') {\n                // eslint-disable-next-line no-console\n                console.error.apply(console, __spreadArray([this.id, this.getTime() + \"ms\"], args));\n            }\n            else {\n                this.info.apply(this, args);\n            }\n        }\n    };\n    Logger.instances = {};\n    return Logger;\n}());\n\nvar Context = /** @class */ (function () {\n    function Context(options, windowBounds) {\n        var _a;\n        this.windowBounds = windowBounds;\n        this.instanceName = \"#\" + Context.instanceCount++;\n        this.logger = new Logger({ id: this.instanceName, enabled: options.logging });\n        this.cache = (_a = options.cache) !== null && _a !== void 0 ? _a : new Cache(this, options);\n    }\n    Context.instanceCount = 1;\n    return Context;\n}());\n\nvar html2canvas = function (element, options) {\n    if (options === void 0) { options = {}; }\n    return renderElement(element, options);\n};\nif (typeof window !== 'undefined') {\n    CacheStorage.setContext(window);\n}\nvar renderElement = function (element, opts) { return __awaiter(void 0, void 0, void 0, function () {\n    var ownerDocument, defaultView, resourceOptions, contextOptions, windowOptions, windowBounds, context, foreignObjectRendering, cloneOptions, documentCloner, clonedElement, container, _a, width, height, left, top, backgroundColor, renderOptions, canvas, renderer, root, renderer;\n    var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;\n    return __generator(this, function (_u) {\n        switch (_u.label) {\n            case 0:\n                if (!element || typeof element !== 'object') {\n                    return [2 /*return*/, Promise.reject('Invalid element provided as first argument')];\n                }\n                ownerDocument = element.ownerDocument;\n                if (!ownerDocument) {\n                    throw new Error(\"Element is not attached to a Document\");\n                }\n                defaultView = ownerDocument.defaultView;\n                if (!defaultView) {\n                    throw new Error(\"Document is not attached to a Window\");\n                }\n                resourceOptions = {\n                    allowTaint: (_b = opts.allowTaint) !== null && _b !== void 0 ? _b : false,\n                    imageTimeout: (_c = opts.imageTimeout) !== null && _c !== void 0 ? _c : 15000,\n                    proxy: opts.proxy,\n                    useCORS: (_d = opts.useCORS) !== null && _d !== void 0 ? _d : false\n                };\n                contextOptions = __assign({ logging: (_e = opts.logging) !== null && _e !== void 0 ? _e : true, cache: opts.cache }, resourceOptions);\n                windowOptions = {\n                    windowWidth: (_f = opts.windowWidth) !== null && _f !== void 0 ? _f : defaultView.innerWidth,\n                    windowHeight: (_g = opts.windowHeight) !== null && _g !== void 0 ? _g : defaultView.innerHeight,\n                    scrollX: (_h = opts.scrollX) !== null && _h !== void 0 ? _h : defaultView.pageXOffset,\n                    scrollY: (_j = opts.scrollY) !== null && _j !== void 0 ? _j : defaultView.pageYOffset\n                };\n                windowBounds = new Bounds(windowOptions.scrollX, windowOptions.scrollY, windowOptions.windowWidth, windowOptions.windowHeight);\n                context = new Context(contextOptions, windowBounds);\n                foreignObjectRendering = (_k = opts.foreignObjectRendering) !== null && _k !== void 0 ? _k : false;\n                cloneOptions = {\n                    allowTaint: (_l = opts.allowTaint) !== null && _l !== void 0 ? _l : false,\n                    onclone: opts.onclone,\n                    ignoreElements: opts.ignoreElements,\n                    inlineImages: foreignObjectRendering,\n                    copyStyles: foreignObjectRendering\n                };\n                context.logger.debug(\"Starting document clone with size \" + windowBounds.width + \"x\" + windowBounds.height + \" scrolled to \" + -windowBounds.left + \",\" + -windowBounds.top);\n                documentCloner = new DocumentCloner(context, element, cloneOptions);\n                clonedElement = documentCloner.clonedReferenceElement;\n                if (!clonedElement) {\n                    return [2 /*return*/, Promise.reject(\"Unable to find element in cloned iframe\")];\n                }\n                return [4 /*yield*/, documentCloner.toIFrame(ownerDocument, windowBounds)];\n            case 1:\n                container = _u.sent();\n                _a = isBodyElement(clonedElement) || isHTMLElement(clonedElement)\n                    ? parseDocumentSize(clonedElement.ownerDocument)\n                    : parseBounds(context, clonedElement), width = _a.width, height = _a.height, left = _a.left, top = _a.top;\n                backgroundColor = parseBackgroundColor(context, clonedElement, opts.backgroundColor);\n                renderOptions = {\n                    canvas: opts.canvas,\n                    backgroundColor: backgroundColor,\n                    scale: (_o = (_m = opts.scale) !== null && _m !== void 0 ? _m : defaultView.devicePixelRatio) !== null && _o !== void 0 ? _o : 1,\n                    x: ((_p = opts.x) !== null && _p !== void 0 ? _p : 0) + left,\n                    y: ((_q = opts.y) !== null && _q !== void 0 ? _q : 0) + top,\n                    width: (_r = opts.width) !== null && _r !== void 0 ? _r : Math.ceil(width),\n                    height: (_s = opts.height) !== null && _s !== void 0 ? _s : Math.ceil(height)\n                };\n                if (!foreignObjectRendering) return [3 /*break*/, 3];\n                context.logger.debug(\"Document cloned, using foreign object rendering\");\n                renderer = new ForeignObjectRenderer(context, renderOptions);\n                return [4 /*yield*/, renderer.render(clonedElement)];\n            case 2:\n                canvas = _u.sent();\n                return [3 /*break*/, 5];\n            case 3:\n                context.logger.debug(\"Document cloned, element located at \" + left + \",\" + top + \" with size \" + width + \"x\" + height + \" using computed rendering\");\n                context.logger.debug(\"Starting DOM parsing\");\n                root = parseTree(context, clonedElement);\n                if (backgroundColor === root.styles.backgroundColor) {\n                    root.styles.backgroundColor = COLORS.TRANSPARENT;\n                }\n                context.logger.debug(\"Starting renderer for element at \" + renderOptions.x + \",\" + renderOptions.y + \" with size \" + renderOptions.width + \"x\" + renderOptions.height);\n                renderer = new CanvasRenderer(context, renderOptions);\n                return [4 /*yield*/, renderer.render(root)];\n            case 4:\n                canvas = _u.sent();\n                _u.label = 5;\n            case 5:\n                if ((_t = opts.removeContainer) !== null && _t !== void 0 ? _t : true) {\n                    if (!DocumentCloner.destroy(container)) {\n                        context.logger.error(\"Cannot detach cloned iframe as it is not in the DOM anymore\");\n                    }\n                }\n                context.logger.debug(\"Finished rendering\");\n                return [2 /*return*/, canvas];\n        }\n    });\n}); };\nvar parseBackgroundColor = function (context, element, backgroundColorOverride) {\n    var ownerDocument = element.ownerDocument;\n    // http://www.w3.org/TR/css3-background/#special-backgrounds\n    var documentBackgroundColor = ownerDocument.documentElement\n        ? parseColor(context, getComputedStyle(ownerDocument.documentElement).backgroundColor)\n        : COLORS.TRANSPARENT;\n    var bodyBackgroundColor = ownerDocument.body\n        ? parseColor(context, getComputedStyle(ownerDocument.body).backgroundColor)\n        : COLORS.TRANSPARENT;\n    var defaultBackgroundColor = typeof backgroundColorOverride === 'string'\n        ? parseColor(context, backgroundColorOverride)\n        : backgroundColorOverride === null\n            ? COLORS.TRANSPARENT\n            : 0xffffffff;\n    return element === ownerDocument.documentElement\n        ? isTransparent(documentBackgroundColor)\n            ? isTransparent(bodyBackgroundColor)\n                ? defaultBackgroundColor\n                : bodyBackgroundColor\n            : documentBackgroundColor\n        : defaultBackgroundColor;\n};\n\n//failCallback will be called when the press is not long enough to considered a long press\nfunction addContextMenuListener(elem, callback, failCallback = () => {}) {\n    if (!elem || !callback) return;\n\n    let timeout = null;\n    const longPressTimer = 500;\n    const MOVE_THRESHOLD = 3;\n    let startX, startY;\n\n    const touchStartHandler = (event) => {\n        event.preventDefault();\n        \n        if (timeout) {\n            clearTimeout(timeout);\n            timeout = null;\n        }\n        // If more than one finger touches the screen, cancel the timeout\n        if (event.touches.length > 1) return;\n\n        const touch = event.touches[0];\n        startX = touch.clientX;\n        startY = touch.clientY;\n\n        timeout = setTimeout(() => {\n            event.clientX = touch.clientX;\n            event.clientY = touch.clientY;\n            callback(event);\n            clearTimeout(timeout);\n            timeout = null;\n        }, longPressTimer);\n    };\n\n    const globalTouchStartHandler = (event) => {\n        // Cancel timeout if multiple touches are detected anywhere on the screen\n        if (event.touches.length > 1 && timeout) {\n            clearTimeout(timeout);\n            timeout = null;\n        }\n    };\n\n    const touchMoveHandler = (event) => {\n        if (!timeout) return;\n        const touch = event.touches[0];\n        const deltaX = Math.abs(touch.clientX - startX);\n        const deltaY = Math.abs(touch.clientY - startY);\n\n        if (deltaX > MOVE_THRESHOLD || deltaY > MOVE_THRESHOLD) {\n            clearTimeout(timeout);\n            timeout = null;\n        }\n    };\n\n    const touchEndHandler = (event) => {\n        event.preventDefault();\n        if (timeout) {\n            failCallback(event);\n            clearTimeout(timeout);\n            timeout = null;\n        }\n    };\n\n    const contextMenuHandler = (event) => {\n        callback(event);\n        event.preventDefault();\n        event.stopPropagation();\n    };\n    \n    if (os.isIphoneOrIpadSafari()) {\n        elem.addEventListener('touchstart', touchStartHandler);\n        elem.addEventListener('touchmove', touchMoveHandler);\n        elem.addEventListener('touchend', touchEndHandler);\n        window.addEventListener('touchstart', globalTouchStartHandler);\n    } else {\n        elem.addEventListener('contextmenu', contextMenuHandler);\n    }\n\n    return function removeContextMenuListener() {\n        if (os.isIphoneOrIpadSafari()) {\n            elem.removeEventListener('touchstart', touchStartHandler);\n            elem.removeEventListener('touchmove', touchMoveHandler);\n            elem.removeEventListener('touchend', touchEndHandler);\n            window.removeEventListener('touchstart', globalTouchStartHandler);\n        } else {\n            elem.removeEventListener('contextmenu', contextMenuHandler);\n        }\n    };\n}\n\n/** @private */\nclass Dot {\n\n    constructor(parentElement, cfg = {}) {\n\n        this._highlightClass = \"viewer-ruler-dot-highlighted\";\n\n        this._x = 0;\n        this._y = 0;\n\n        this._dot = document.createElement('div');\n        this._dot.className += this._dot.className ? ' viewer-ruler-dot' : 'viewer-ruler-dot';\n\n        this._dotClickable = document.createElement('div');\n        this._dotClickable.className += this._dotClickable.className ? ' viewer-ruler-dot-clickable' : 'viewer-ruler-dot-clickable';\n\n        this._visible = cfg.visible !== false;\n        this._culled = false;\n\n        var dot = this._dot;\n        var dotStyle = dot.style;\n        dotStyle[\"border-radius\"] = 25 + \"px\";\n        dotStyle.border = \"solid 2px white\";\n        dotStyle.background = \"lightgreen\";\n        dotStyle.position = \"absolute\";\n        dotStyle[\"z-index\"] = cfg.zIndex === undefined ? \"40000005\" : cfg.zIndex ;\n        dotStyle.width = 8 + \"px\";\n        dotStyle.height = 8 + \"px\";\n        dotStyle.visibility = this._visible ? \"visible\" : \"hidden\";\n        dotStyle.top = 0 + \"px\";\n        dotStyle.left = 0 + \"px\";\n        dotStyle[\"box-shadow\"] = \"0 2px 5px 0 #182A3D;\";\n        dotStyle[\"opacity\"] = 1.0;\n        dotStyle[\"pointer-events\"] = \"none\";\n        if (cfg.onContextMenu) ;\n        parentElement.appendChild(dot);\n\n        var dotClickable = this._dotClickable;\n        var dotClickableStyle = dotClickable.style;\n        dotClickableStyle[\"border-radius\"] = 35 + \"px\";\n        dotClickableStyle.border = \"solid 10px white\";\n        dotClickableStyle.position = \"absolute\";\n        dotClickableStyle[\"z-index\"] = cfg.zIndex === undefined ? \"40000007\" : (cfg.zIndex + 1);\n        dotClickableStyle.width = 8 + \"px\";\n        dotClickableStyle.height = 8 + \"px\";\n        dotClickableStyle.visibility = \"visible\";\n        dotClickableStyle.top = 0 + \"px\";\n        dotClickableStyle.left = 0 + \"px\";\n        dotClickableStyle[\"opacity\"] = 0.0;\n        dotClickableStyle[\"pointer-events\"] = \"none\";\n        if (cfg.onContextMenu) ;\n        parentElement.appendChild(dotClickable);\n\n        dotClickable.addEventListener('click', (event) => {\n            parentElement.dispatchEvent(new MouseEvent('mouseover', event));\n        });\n\n        if (cfg.onMouseOver) {\n            dotClickable.addEventListener('mouseover', (event) => {\n                cfg.onMouseOver(event, this);\n                parentElement.dispatchEvent(new MouseEvent('mouseover', event));\n            });\n        }\n\n        if (cfg.onMouseLeave) {\n            dotClickable.addEventListener('mouseleave', (event) => {\n                cfg.onMouseLeave(event, this);\n            });\n        }\n\n        if (cfg.onMouseWheel) {\n            dotClickable.addEventListener('wheel', (event) => {\n                cfg.onMouseWheel(event, this);\n            });\n        }\n\n        if (cfg.onMouseDown) {\n            dotClickable.addEventListener('mousedown', (event) => {\n                cfg.onMouseDown(event, this);\n            });\n        }\n\n        if (cfg.onMouseUp) {\n            dotClickable.addEventListener('mouseup', (event) => {\n                cfg.onMouseUp(event, this);\n            });\n        }\n\n        if (cfg.onMouseMove) {\n            dotClickable.addEventListener('mousemove', (event) => {\n                cfg.onMouseMove(event, this);\n            });\n        }\n\n        if (cfg.onTouchstart) {\n            dotClickable.addEventListener('touchstart', (event) => {\n                cfg.onTouchstart(event, this);\n            });\n        }\n\n        if (cfg.onTouchmove) {\n            dotClickable.addEventListener('touchmove', (event) => {\n                cfg.onTouchmove(event, this);\n            });\n        }\n\n        if (cfg.onTouchend) {\n            dotClickable.addEventListener('touchend', (event) => {\n                cfg.onTouchend(event, this);\n            });\n        }\n\n        if (cfg.onContextMenu) {\n            const contextMenuCallback = (event) => {\n                cfg.onContextMenu(event, this);\n            };\n            addContextMenuListener(dotClickable, contextMenuCallback);\n            \n        }\n\n        this.setPos(cfg.x || 0, cfg.y || 0);\n        this.setFillColor(cfg.fillColor);\n        this.setBorderColor(cfg.borderColor);\n    }\n\n    setPos(x, y) {\n        this._x = x;\n        this._y = y;\n        var dotStyle = this._dot.style;\n        dotStyle[\"left\"] = (Math.round(x) - 6) + 'px';\n        dotStyle[\"top\"] = (Math.round(y) - 6) + 'px';\n\n        var dotClickableStyle = this._dotClickable.style;\n        dotClickableStyle[\"left\"] = (Math.round(x) - 14) + 'px';\n        dotClickableStyle[\"top\"] = (Math.round(y) - 14) + 'px';\n    }\n\n    setFillColor(color) {\n        this._dot.style.background = color || \"lightgreen\";\n    }\n\n    setBorderColor(color) {\n        this._dot.style.border = \"solid 2px\" + (color || \"black\");\n    }\n\n    setOpacity(opacity) {\n        this._dot.style.opacity = opacity;\n    }\n\n    _updateVisibility() {\n        this._dot.style.visibility = this._dotClickable.style.visibility = this._visible && !this._culled ? \"visible\" : \"hidden\";\n    }\n\n    setVisible(visible) {\n        if (this._visible === visible) {\n            return;\n        }\n        this._visible = !!visible;\n        this._updateVisibility();\n    }\n\n    setCulled(culled) {\n        if (this._culled === culled) {\n            return;\n        }\n        this._culled = !!culled;\n        this._updateVisibility();\n    }\n\n    setClickable(clickable) {\n        this._dotClickable.style[\"pointer-events\"] = (clickable) ? \"all\" : \"none\";\n    }\n\n    setHighlighted(highlighted) {\n        if (this._highlighted === highlighted) {\n            return;\n        }\n        this._highlighted = !!highlighted;\n        if (this._highlighted) {\n            this._dot.classList.add(this._highlightClass);\n        } else {\n            this._dot.classList.remove(this._highlightClass);\n        }\n    }\n    \n    destroy() {\n        this.setVisible(false);\n        if (this._dot.parentElement) {\n            this._dot.parentElement.removeChild(this._dot);\n        }\n        if (this._dotClickable.parentElement) {\n            this._dotClickable.parentElement.removeChild(this._dotClickable);\n        }\n    }\n}\n\n/** @private */\nclass Label {\n\n    constructor(parentElement, cfg = {}) {\n\n        this._highlightClass = \"viewer-ruler-label-highlighted\";\n\n        this._prefix = cfg.prefix || \"\";\n        this._x = 0;\n        this._y = 0;\n        this._visible = true;\n        this._culled = false;\n\n        this._label = document.createElement('div');\n        this._label.className += this._label.className ? ' viewer-ruler-label' : 'viewer-ruler-label';\n        this._timeout = null;\n\n        var label = this._label;\n        var style = label.style;\n\n        style[\"border-radius\"] = 5 + \"px\";\n        style.color = \"white\";\n        style.padding = \"4px\";\n        style.border = \"solid 1px\";\n        style.background = \"lightgreen\";\n        style.position = \"absolute\";\n        style[\"z-index\"] = cfg.zIndex === undefined ? \"5000005\" : cfg.zIndex;\n        style.width = \"auto\";\n        style.height = \"auto\";\n        style.visibility = \"visible\";\n        style.top = 0 + \"px\";\n        style.left = 0 + \"px\";\n        style[\"pointer-events\"] = \"all\";\n        style[\"opacity\"] = 1.0;\n        if (cfg.onContextMenu) ;\n        label.innerText = \"\";\n\n        parentElement.appendChild(label);\n\n        this.setPos(cfg.x || 0, cfg.y || 0);\n        this.setFillColor(cfg.fillColor);\n        this.setBorderColor(cfg.fillColor);\n        this.setText(cfg.text);\n\n        if (cfg.onMouseOver) {\n            label.addEventListener('mouseover', (event) => {\n                cfg.onMouseOver(event, this);\n                event.preventDefault();\n            });\n        }\n\n        if (cfg.onMouseLeave) {\n            label.addEventListener('mouseleave', (event) => {\n                cfg.onMouseLeave(event, this);\n                event.preventDefault();\n            });\n        }\n\n        if (cfg.onMouseWheel) {\n            label.addEventListener('wheel', (event) => {\n                cfg.onMouseWheel(event, this);\n            });\n        }\n\n        if (cfg.onMouseDown) {\n            label.addEventListener('mousedown', (event) => {\n                cfg.onMouseDown(event, this);\n                event.stopPropagation();\n            });\n        }\n\n        if (cfg.onMouseUp) {\n            label.addEventListener('mouseup', (event) => {\n                cfg.onMouseUp(event, this);\n                event.stopPropagation();\n            });\n        }\n\n        if (cfg.onMouseMove) {\n            label.addEventListener('mousemove', (event) => {\n                cfg.onMouseMove(event, this);\n            });\n        }\n\n        if (cfg.onContextMenu) {\n            const contextMenuCallback = (event) => {\n                cfg.onContextMenu(event, this);\n            };\n            addContextMenuListener(label, contextMenuCallback);\n            \n        }\n    }\n\n    setPos(x, y) {\n        this._x = x;\n        this._y = y;\n        var style = this._label.style;\n        style[\"left\"] = (Math.round(x) - 20) + 'px';\n        style[\"top\"] = (Math.round(y) - 12) + 'px';\n    }\n\n    setPosOnWire(x1, y1, x2, y2) {\n        var x = x1 + ((x2 - x1) * 0.5);\n        var y = y1 + ((y2 - y1) * 0.5);\n        var style = this._label.style;\n        style[\"left\"] = (Math.round(x) - 20) + 'px';\n        style[\"top\"] = (Math.round(y) - 12) + 'px';\n    }\n\n    setPosBetweenWires(x1, y1, x2, y2, x3, y3) {\n        var x = (x1 + x2 + x3) / 3;\n        var y = (y1 + y2 + y3) / 3;\n        var style = this._label.style;\n        style[\"left\"] = (Math.round(x) - 20) + 'px';\n        style[\"top\"] = (Math.round(y) - 12) + 'px';\n    }\n\n    setText(text) {\n        this._label.innerHTML = this._prefix + (text || \"\");\n    }\n\n    setFillColor(color) {\n        this._fillColor = color || \"lightgreen\";\n        this._label.style.background =this._fillColor;\n    }\n\n    setBorderColor(color) {\n        this._borderColor = color || \"black\";\n        this._label.style.border = \"solid 1px \" + this._borderColor;\n    }\n\n    setOpacity(opacity) {\n        this._label.style.opacity = opacity;\n    }\n\n    _updateVisibility() {\n        this._label.style.visibility = this._visible && !this._culled ? \"visible\" : \"hidden\";\n    }\n\n    setVisible(visible) {\n        if (this._visible === visible) {\n            return;\n        }\n        this._visible = !!visible;\n        this._updateVisibility();\n    }\n\n    setCulled(culled) {\n        if (this._culled === culled) {\n            return;\n        }\n        this._culled = !!culled;\n        this._updateVisibility();\n    }\n\n    setHighlighted(highlighted) {\n        if (this._highlighted === highlighted) {\n            return;\n        }\n        this._highlighted = !!highlighted;\n        if (this._highlighted) {\n            this._label.classList.add(this._highlightClass);\n        } else {\n            this._label.classList.remove(this._highlightClass);\n        }\n    }\n\n    setClickable(clickable) {\n        this._label.style[\"pointer-events\"] = (clickable) ? \"all\" : \"none\";\n    }\n\n    setPrefix(prefix) {\n        if(this._prefix === prefix){\n            return;\n        }\n        this._prefix = prefix;\n    }\n\n    destroy() {\n        if (this._label.parentElement) {\n            this._label.parentElement.removeChild(this._label);\n        }\n    }\n\n    \n}\n\n/** @private */\nclass Wire {\n\n    constructor(parentElement, cfg = {}) {\n\n        this._color = cfg.color || \"black\";\n        this._highlightClass = \"viewer-ruler-wire-highlighted\";\n\n        this._wire = document.createElement('div');\n        this._wire.className += this._wire.className ? ' viewer-ruler-wire' : 'viewer-ruler-wire';\n\n        this._wireClickable = document.createElement('div');\n        this._wireClickable.className += this._wireClickable.className ? ' viewer-ruler-wire-clickable' : 'viewer-ruler-wire-clickable';\n\n        this._thickness = cfg.thickness || 1.0;\n        this._thicknessClickable = cfg.thicknessClickable || 6.0;\n\n        this._visible = true;\n        this._culled = false;\n\n        var wire = this._wire;\n        var wireStyle = wire.style;\n\n        wireStyle.border = \"solid \" + this._thickness + \"px \" + this._color;\n        wireStyle.position = \"absolute\";\n        wireStyle[\"z-index\"] = cfg.zIndex === undefined ? \"2000001\" : cfg.zIndex;\n        wireStyle.width = 0 + \"px\";\n        wireStyle.height = 0 + \"px\";\n        wireStyle.visibility = \"visible\";\n        wireStyle.top = 0 + \"px\";\n        wireStyle.left = 0 + \"px\";\n        wireStyle['-webkit-transform-origin'] = \"0 0\";\n        wireStyle['-moz-transform-origin'] = \"0 0\";\n        wireStyle['-ms-transform-origin'] = \"0 0\";\n        wireStyle['-o-transform-origin'] = \"0 0\";\n        wireStyle['transform-origin'] = \"0 0\";\n        wireStyle['-webkit-transform'] = 'rotate(0deg)';\n        wireStyle['-moz-transform'] = 'rotate(0deg)';\n        wireStyle['-ms-transform'] = 'rotate(0deg)';\n        wireStyle['-o-transform'] = 'rotate(0deg)';\n        wireStyle['transform'] = 'rotate(0deg)';\n        wireStyle[\"opacity\"] = 1.0;\n        wireStyle[\"pointer-events\"] = \"none\";\n        if (cfg.onContextMenu) ;\n\n        parentElement.appendChild(wire);\n\n        var wireClickable = this._wireClickable;\n        var wireClickableStyle = wireClickable.style;\n\n        wireClickableStyle.border = \"solid \" + this._thicknessClickable + \"px \" + this._color;\n        wireClickableStyle.position = \"absolute\";\n        wireClickableStyle[\"z-index\"] = cfg.zIndex === undefined ? \"2000002\" : (cfg.zIndex + 1);\n        wireClickableStyle.width = 0 + \"px\";\n        wireClickableStyle.height = 0 + \"px\";\n        wireClickableStyle.visibility = \"visible\";\n        wireClickableStyle.top = 0 + \"px\";\n        wireClickableStyle.left = 0 + \"px\";\n        // wireClickableStyle[\"pointer-events\"] = \"none\";\n        wireClickableStyle['-webkit-transform-origin'] = \"0 0\";\n        wireClickableStyle['-moz-transform-origin'] = \"0 0\";\n        wireClickableStyle['-ms-transform-origin'] = \"0 0\";\n        wireClickableStyle['-o-transform-origin'] = \"0 0\";\n        wireClickableStyle['transform-origin'] = \"0 0\";\n        wireClickableStyle['-webkit-transform'] = 'rotate(0deg)';\n        wireClickableStyle['-moz-transform'] = 'rotate(0deg)';\n        wireClickableStyle['-ms-transform'] = 'rotate(0deg)';\n        wireClickableStyle['-o-transform'] = 'rotate(0deg)';\n        wireClickableStyle['transform'] = 'rotate(0deg)';\n        wireClickableStyle[\"opacity\"] = 0.0;\n        wireClickableStyle[\"pointer-events\"] = \"none\";\n        if (cfg.onContextMenu) ;\n\n        parentElement.appendChild(wireClickable);\n\n        if (cfg.onMouseOver) {\n            wireClickable.addEventListener('mouseover', (event) => {\n                cfg.onMouseOver(event, this);\n            });\n        }\n\n        if (cfg.onMouseLeave) {\n            wireClickable.addEventListener('mouseleave', (event) => {\n                cfg.onMouseLeave(event, this);\n            });\n        }\n\n        if (cfg.onMouseWheel) {\n            wireClickable.addEventListener('wheel', (event) => {\n                cfg.onMouseWheel(event, this);\n            });\n        }\n\n        if (cfg.onMouseDown) {\n            wireClickable.addEventListener('mousedown', (event) => {\n                cfg.onMouseDown(event, this);\n            });\n        }\n\n        if (cfg.onMouseUp) {\n            wireClickable.addEventListener('mouseup', (event) => {\n                cfg.onMouseUp(event, this);\n            });\n        }\n\n        if (cfg.onMouseMove) {\n            wireClickable.addEventListener('mousemove', (event) => {\n                cfg.onMouseMove(event, this);\n            });\n        }\n\n        if (cfg.onContextMenu) {\n            const contextMenuCallback = (event) => {\n                cfg.onContextMenu(event, this);\n            };\n            addContextMenuListener(wireClickable, contextMenuCallback);\n            \n        }\n\n        this._x1 = 0;\n        this._y1 = 0;\n        this._x2 = 0;\n        this._y2 = 0;\n\n        this._update();\n    }\n\n    get visible() {\n        return this._wire.style.visibility === \"visible\";\n    }\n\n    _update() {\n\n        var length = Math.abs(Math.sqrt((this._x1 - this._x2) * (this._x1 - this._x2) + (this._y1 - this._y2) * (this._y1 - this._y2)));\n        var angle = Math.atan2(this._y2 - this._y1, this._x2 - this._x1) * 180.0 / Math.PI;\n\n        var wireStyle = this._wire.style;\n        wireStyle[\"width\"] = Math.round(length) + 'px';\n        wireStyle[\"left\"] = Math.round(this._x1) + 'px';\n        wireStyle[\"top\"] = Math.round(this._y1) + 'px';\n        wireStyle['-webkit-transform'] =\n            wireStyle['-moz-transform'] =\n            wireStyle['-ms-transform'] =\n            wireStyle['-o-transform'] =\n            wireStyle['transform'] = 'rotate(' + angle + 'deg) translate(-' + this._thickness + 'px, -' + this._thickness + 'px)';\n\n        var wireClickableStyle = this._wireClickable.style;\n        wireClickableStyle[\"width\"] = Math.round(length) + 'px';\n        wireClickableStyle[\"left\"] = Math.round(this._x1) + 'px';\n        wireClickableStyle[\"top\"] = Math.round(this._y1) + 'px';\n        wireClickableStyle['-webkit-transform'] =\n            wireClickableStyle['-moz-transform'] =\n            wireClickableStyle['-ms-transform'] =\n            wireClickableStyle['-o-transform'] =\n            wireClickableStyle['transform'] = 'rotate(' + angle + 'deg) translate(-' + this._thicknessClickable + 'px, -' + this._thicknessClickable + 'px)';\n    }\n\n    setStartAndEnd(x1, y1, x2, y2) {\n        this._x1 = x1;\n        this._y1 = y1;\n        this._x2 = x2;\n        this._y2 = y2;\n        this._update();\n    }\n\n    setColor(color) {\n        this._color = color || \"black\";\n        this._wire.style.border = \"solid \" + this._thickness + \"px \" + this._color;\n    }\n\n    setOpacity(opacity) {\n        this._wire.style.opacity = opacity;\n    }\n\n    _updateVisibility() {\n        this._wire.style.visibility = this._wireClickable.style.visibility = this._visible && !this._culled ? \"visible\" : \"hidden\";\n    }\n\n    setVisible(visible) {\n        if (this._visible === visible) {\n            return;\n        }\n        this._visible = !!visible;\n        this._updateVisibility();\n    }\n\n    setCulled(culled) {\n        if (this._culled === culled) {\n            return;\n        }\n        this._culled = !!culled;\n        this._updateVisibility();\n    }\n\n    setClickable(clickable) {\n        this._wireClickable.style[\"pointer-events\"] = (clickable) ? \"all\" : \"none\";\n    }\n\n    setHighlighted(highlighted) {\n        if (this._highlighted === highlighted) {\n            return;\n        }\n        this._highlighted = !!highlighted;\n        if (this._highlighted) {\n            this._wire.classList.add(this._highlightClass);\n        } else {\n            this._wire.classList.remove(this._highlightClass);\n        }\n    }\n\n    destroy(visible) {\n        if (this._wire.parentElement) {\n            this._wire.parentElement.removeChild(this._wire);\n        }\n        if (this._wireClickable.parentElement) {\n            this._wireClickable.parentElement.removeChild(this._wireClickable);\n        }\n    }\n}\n\nconst tmpVec2a = math.vec2();\nconst tmpVec2b = math.vec2();\nconst tmpVec2c = math.vec2();\nconst tmpVec2d = math.vec2();\nconst tmpVec3a$2 = math.vec3();\nconst tmpVec3b$2 = math.vec3();\nconst tmpVec4a = math.vec4();\nconst tmpVec4b = math.vec4();\nconst tmpVec4c = math.vec4();\nconst tmpVec4d = math.vec4();\nconst tmpMat4  = math.mat4();\nconst tmpRay = {\n    origin:    math.vec3(),\n    direction: math.vec3()\n};\n\nconst nop = () => { };\n\nconst planeIntersect$1 = function(p0, n, origin, direction) {\n    const t = (p0 - math.dotVec3(origin, n)) / math.dotVec3(direction, n);\n    if (t < 0)\n    {\n        return null;\n    }\n    else\n    {\n        const worldPos = math.vec3();\n        math.mulVec3Scalar(direction, t, worldPos);\n        math.addVec3(origin, worldPos, worldPos);\n        return worldPos;\n    }\n};\n\nfunction transformToNode(from, to, vec) {\n    const fromRec = from.getBoundingClientRect();\n    const toRec = to.getBoundingClientRect();\n    vec[0] += fromRec.left - toRec.left;\n    vec[1] += fromRec.top  - toRec.top;\n}\nconst toClipSpace = (camera, worldPos, p) => {\n    // The reason the projMatrix is explicitely fetched as below is a complex callback chain\n    // leading from a boundary update to a viewMatrix and projMatrix updates, which change their values\n    // in the mid of the toClipSpace, leading to incorrect values.\n    // The fetch ensures that matrix values are stabilized before used to transform worldPos to p.\n    // Better solution would be to ensure that no mutually-triggered callbacks\n    // (like boundary => view/projMatrix in this situation) ever happen, so user code can rely\n    // on a callback running in a stable context.\n    tmpMat4.set(camera.viewMatrix);\n    tmpMat4.set(camera.projMatrix);\n    // to homogeneous coords\n    p.set(worldPos);\n    p[3] = 1;\n\n    // to clip space\n    math.mulMat4v4(camera.viewMatrix, p, p);\n    math.mulMat4v4(camera.projMatrix, p, p);\n};\n\nconst toCanvasSpace = (canvas, parentElement, ndc, p) => {\n    p[0] = (1 + ndc[0]) * 0.5 * canvas.offsetWidth;\n    p[1] = (1 - ndc[1]) * 0.5 * canvas.offsetHeight;\n    transformToNode(canvas, parentElement, p);\n};\n\nconst clipSegment = (scene, parentElement, start, end, canvasStart, canvasEnd) => {\n    const camera = scene.camera;\n    const canvas = scene.canvas.canvas;\n\n    if (math.distVec3(start, end) < 0.001) {\n        return false;\n    }\n\n    const delta = math.subVec3(end, start, tmpVec3a$2);\n    let s_min = 0.0;\n    let s_max = 1.0;\n\n    for (let plane of scene._sectionPlanesState.sectionPlanes) {\n        const endDot   = math.dotVec3(plane.dir, math.subVec3(plane.pos, end,   tmpVec3b$2));\n        const startDot = math.dotVec3(plane.dir, math.subVec3(plane.pos, start, tmpVec3b$2));\n\n        if ((startDot > 0) && (endDot > 0)) {\n            return false;\n        } else if ((startDot > 0) || (endDot > 0)) {\n            const denom = math.dotVec3(plane.dir, delta);\n            if (Math.abs(denom) >= 1e-6) {\n                const ratio = math.dotVec3(plane.dir, tmpVec3b$2) / denom;\n                if (startDot > 0) {\n                    s_min = Math.max(s_min, ratio);\n                } else {\n                    s_max = Math.min(s_max, ratio);\n                }\n            }\n        }\n    }\n\n    const p0 = tmpVec4a;\n    const p1 = tmpVec4b;\n    toClipSpace(camera, (s_min > 0) ? math.addVec3(start, math.mulVec3Scalar(delta, s_min, tmpVec3b$2), tmpVec3b$2) : start, p0);\n    toClipSpace(camera, (s_max < 1) ? math.addVec3(start, math.mulVec3Scalar(delta, s_max, tmpVec3b$2), tmpVec3b$2) : end,   p1);\n\n    const p0Behind = ((p0[2] / p0[3]) < -1) || (p0[3] < 0);\n    const p1Behind = ((p1[2] / p1[3]) < -1) || (p1[3] < 0);\n    if (p0Behind && p1Behind) {\n        return false;\n    }\n\n    const t = (p0[3] + p0[2]) / ((p0[3] + p0[2]) - (p1[3] + p1[2]));\n\n    if ((t > 0) && (t < 1)) { //p0Behind || p1Behind) {\n        // Find the intersection of a segment with the near plane in clip space, if it exists.\"\"\"\n        // Calculate the interpolation factor t where the line segment crosses the near plane\n        const delta = math.subVec4(p1, p0, tmpVec4c);\n        math.mulVec4Scalar(delta, t, delta);\n        math.addVec4(p0, delta, p0Behind ? p0 : p1);\n    }\n\n    // normalize clip space coords\n    math.mulVec4Scalar(p0, 1.0 / p0[3]);\n    math.mulVec4Scalar(p1, 1.0 / p1[3]);\n\n    let t_min = 0.0;\n    let t_max = 1.0;\n\n    // If either point is outside the view frustum, clip the line segment\n\n    for (let i = 0; i < 2; ++i) {\n        const denom = p1[i] - p0[i];\n\n        const l = (-1 - p0[i]) / denom;\n        const r = ( 1 - p0[i]) / denom;\n\n        if (denom > 0) {\n            t_min = Math.max(t_min, l);\n            t_max = Math.min(t_max, r);\n        } else if (denom < 0) {\n            t_min = Math.max(t_min, r);\n            t_max = Math.min(t_max, l);\n        } else {\n            if (p0[0] < -1) {\n                t_min = -window.Infinity;\n            } else if (p0[0] > 1) {\n                t_max = window.Infinity;\n            }\n        }\n    }\n\n    if (t_min >= t_max) {\n        return false;\n    }\n\n    // Calculate the clipped start and end points\n    const ndcDelta = math.subVec4(p1, p0, tmpVec4c);\n    math.addVec4(p0, math.mulVec4Scalar(ndcDelta, t_max, tmpVec4d), p1);\n    math.addVec4(p0, math.mulVec4Scalar(ndcDelta, t_min, tmpVec4d), p0);\n\n    math.mulVec4Scalar(p0, 1 / p0[3]);\n    math.mulVec4Scalar(p1, 1 / p1[3]);\n\n    toCanvasSpace(canvas, parentElement, p0, canvasStart);\n    toCanvasSpace(canvas, parentElement, p1, canvasEnd);\n\n    return true;\n};\n\nclass Dot3D extends Marker {\n    constructor(scene, markerCfg, parentElement, cfg = {}) {\n        const camera = scene.camera;\n\n        super(scene, markerCfg);\n\n        this.__visible = true;  // \"__\" to not interfere with Marker::_visible\n\n        const handler = (cfgEvent, componentEvent) => {\n            return event => {\n                if (cfgEvent) {\n                    cfgEvent(event);\n                }\n                this.fire(componentEvent, event, true);\n            };\n        };\n        this._dot = new Dot(parentElement, {\n            borderColor: cfg.borderColor,\n            fillColor: cfg.fillColor,\n            zIndex: cfg.zIndex,\n            onMouseOver:   handler(cfg.onMouseOver,   \"mouseover\"),\n            onMouseLeave:  handler(cfg.onMouseLeave,  \"mouseleave\"),\n            onMouseWheel:  handler(cfg.onMouseWheel,  \"wheel\"),\n            onMouseDown:   handler(cfg.onMouseDown,   \"mousedown\"),\n            onMouseUp:     handler(cfg.onMouseUp,     \"mouseup\"),\n            onMouseMove:   handler(cfg.onMouseMove,   \"mousemove\"),\n            onTouchstart:  handler(cfg.onTouchstart,  \"touchstart\"),\n            onTouchmove:   handler(cfg.onTouchmove,   \"touchmove\"),\n            onTouchend:    handler(cfg.onTouchend,    \"touchend\"),\n            onContextMenu: handler(cfg.onContextMenu, \"contextmenu\")\n        });\n\n        const toClipSpace = (worldPos, p) => {\n            // to homogeneous coords\n            p.set(worldPos);\n            p[3] = 1;\n\n            // to clip space\n            math.mulMat4v4(camera.viewMatrix, p, p);\n            math.mulMat4v4(camera.projMatrix, p, p);\n        };\n\n        const toCanvasSpace = ndc => {\n            const canvas = scene.canvas.canvas;\n            ndc[0] = (1 + ndc[0]) * 0.5 * canvas.offsetWidth;\n            ndc[1] = (1 - ndc[1]) * 0.5 * canvas.offsetHeight;\n            transformToNode(canvas, parentElement, ndc);\n        };\n\n        const updateDotPos = () => {\n            if (! this.__visible) {\n                return;\n            }\n            const p0 = tmpVec4c;\n            toClipSpace(this.worldPos, p0);\n            math.mulVec3Scalar(p0, 1.0 / p0[3]);\n\n            const outsideFrustum = ((p0[3] < 0)\n                                    ||\n                                    (p0[0] < -1) || (p0[0] > 1)\n                                    ||\n                                    (p0[1] < -1) || (p0[1] > 1)\n                                    ||\n                                    (p0[2] < -1) || (p0[2] > 1));\n            const culled = outsideFrustum || scene._sectionPlanesState.sectionPlanes.some(\n                plane => (math.dotVec3(plane.dir, math.subVec3(plane.pos, this.worldPos, tmpVec3a$2)) > 0));\n\n            this._dot.setCulled(culled);\n            if (!culled) {\n                toCanvasSpace(p0);\n                this._dot.setPos(p0[0], p0[1]);\n            }\n        };\n\n        this.on(\"worldPos\", updateDotPos);\n\n        const onViewMatrix = camera.on(\"viewMatrix\", updateDotPos);\n        const onProjMatrix = camera.on(\"projMatrix\", updateDotPos);\n        const onCanvasBnd  = scene.canvas.on(\"boundary\", updateDotPos);\n        const planesUpdate = scene.on(\"sectionPlaneUpdated\", updateDotPos);\n        const planeCreated = scene.on(\"sectionPlaneCreated\", updateDotPos);\n        const planeDestroyed = scene.on(\"sectionPlaneDestroyed\", updateDotPos);\n\n        this._updatePosition = updateDotPos;\n\n        this._cleanup = () => {\n            camera.off(onViewMatrix);\n            camera.off(onProjMatrix);\n            scene.canvas.off(onCanvasBnd);\n            scene.off(planesUpdate);\n            scene.off(planeCreated);\n            scene.off(planeDestroyed);\n            this._dot.destroy();\n        };\n    }\n\n    setClickable(value) {\n        this._dot.setClickable(value);\n    }\n\n    setFillColor(value) {\n        this._dot.setFillColor(value);\n    }\n\n    setBorderColor(value) {\n        this._dot.setBorderColor(value);\n    }\n\n    setHighlighted(value) {\n        this._dot.setHighlighted(value);\n    }\n\n    setOpacity(value) {\n        this._dot.setOpacity(value);\n    }\n\n    setVisible(value) {\n        if (this.__visible != value) {\n            this.__visible = value;\n            this._updatePosition();\n            this._dot.setVisible(value);\n        }\n    }\n\n    destroy() {\n        this._cleanup();\n        super.destroy();\n    }\n\n}\n\nclass Label3D {\n    constructor(scene, parentElement, cfg) {\n        const camera = scene.camera;\n\n        this._label = new Label(parentElement, cfg);\n        this._start = math.vec3();\n        this._mid   = math.vec3();\n        this._end   = math.vec3();\n        this._yOff  = 0;\n        this.__visible = true;\n\n        this._updatePos = () => {\n            toClipSpace(camera, this._start, tmpVec4a);\n            math.mulVec4Scalar(tmpVec4a, 1.0 / tmpVec4a[3]);\n            toCanvasSpace(scene.canvas.canvas, parentElement, tmpVec4a, tmpVec2a);\n            this._label.setPos(tmpVec2a[0], tmpVec2a[1]);\n        };\n\n        const setPosOnWire = (p0, p1, yOff) => {\n            p0[0] += p1[0];\n            p0[1] += p1[1];\n            math.mulVec2Scalar(p0, .5);\n            this._label.setPos(p0[0], p0[1] + yOff);\n        };\n\n        this._updatePosBetween = () => {\n            const visibleA = clipSegment(scene, parentElement, this._start, this._mid, tmpVec2a, tmpVec2b);\n            const visibleB = clipSegment(scene, parentElement, this._end,   this._mid, tmpVec2c, tmpVec2d);\n            this._label.setCulled(! (visibleA || visibleB));\n            if (visibleA && visibleB) {\n                tmpVec2b[0] += tmpVec2d[0];\n                tmpVec2b[1] += tmpVec2d[1];\n                math.mulVec2Scalar(tmpVec2b, .5);\n\n                tmpVec2b[0] += tmpVec2a[0] + tmpVec2c[0];\n                tmpVec2b[1] += tmpVec2a[1] + tmpVec2c[1];\n                math.mulVec2Scalar(tmpVec2b, 1/3);\n                this._label.setPos(tmpVec2b[0], tmpVec2b[1]);\n            } else if (visibleA) {\n                setPosOnWire(tmpVec2a, tmpVec2b, 0);\n            } else if (visibleB) {\n                setPosOnWire(tmpVec2c, tmpVec2d, 0);\n            }\n        };\n\n        this._updatePosOnWire = () => {\n            const visible = (clipSegment(scene, parentElement, this._start, this._end, tmpVec2a, tmpVec2b)\n                             &&\n                             (math.distVec2(tmpVec2a, tmpVec2b) >= this._labelMinAxisLength));\n            this._label.setCulled(!visible);\n            if (visible) {\n                setPosOnWire(tmpVec2a, tmpVec2b, this._yOff);\n            }\n        };\n\n        let posUpdate = () => { };\n        this._setUpdatePositions = (_posUpdate) => {\n            posUpdate = _posUpdate;\n            this._updatePositions();\n        };\n        this._updatePositions = () => {\n            if (this.__visible) {\n                posUpdate();\n            }\n        };\n\n        const onViewMatrix = camera.on(\"viewMatrix\", this._updatePositions);\n        const onProjMatrix = camera.on(\"projMatrix\", this._updatePositions);\n        const onCanvasBnd  = scene.canvas.on(\"boundary\", this._updatePositions);\n        const planesUpdate = scene.on(\"sectionPlaneUpdated\", this._updatePositions);\n        const planeCreated = scene.on(\"sectionPlaneCreated\", this._updatePositions);\n        const planeDestroyed = scene.on(\"sectionPlaneDestroyed\", this._updatePositions);\n\n        this._cleanup = () => {\n            camera.off(onViewMatrix);\n            camera.off(onProjMatrix);\n            scene.canvas.off(onCanvasBnd);\n            scene.off(planesUpdate);\n            scene.off(planeCreated);\n            scene.off(planeDestroyed);\n            this._label.destroy();\n        };\n    }\n\n    setPos(p0) {\n        this._start.set(p0);\n        this._setUpdatePositions(this._updatePos);\n    }\n\n    setPosOnWire(p0, p1, yOff, labelMinAxisLength) {\n        this._start.set(p0);\n        this._end.set(p1);\n        this._yOff = yOff;\n        this._labelMinAxisLength = labelMinAxisLength;\n        this._setUpdatePositions(this._updatePosOnWire);\n    }\n\n    setPosBetween(p0, p1, p2) {\n        this._start.set(p0);\n        this._mid.set(p1);\n        this._end.set(p2);\n        this._setUpdatePositions(this._updatePosBetween);\n    }\n\n    setFillColor(value) {\n        this._label.setFillColor(value);\n    }\n\n    setHighlighted(value) {\n        this._label.setHighlighted(value);\n    }\n\n    setText(value) {\n        this._label.setText(value);\n    }\n\n    setClickable(value) {\n        this._label.setClickable(value);\n    }\n\n    setVisible(value) {\n        if (this.__visible != value) {\n            this.__visible = value;\n            this._updatePositions();\n            this._label.setVisible(value);\n        }\n    }\n\n    destroy() {\n        this._cleanup();\n    }\n\n}\n\nclass Wire3D {\n    constructor(scene, parentElement, cfg) {\n        const camera = scene.camera;\n\n        this._wire  = new Wire(parentElement, cfg);\n        this._start = math.vec3();\n        this._end   = math.vec3();\n        this.__visible = true;\n\n        this._updatePositions = () => {\n            if (! this.__visible) {\n                return;\n            }\n            const visible = clipSegment(scene, parentElement, this._start, this._end, tmpVec2a, tmpVec2b);\n            this._wire.setCulled(! visible);\n            if (visible) {\n                this._wire.setStartAndEnd(tmpVec2a[0], tmpVec2a[1], tmpVec2b[0], tmpVec2b[1]);\n            }\n        };\n\n        const onViewMatrix = camera.on(\"viewMatrix\", this._updatePositions);\n        const onProjMatrix = camera.on(\"projMatrix\", this._updatePositions);\n        const onCanvasBnd  = scene.canvas.on(\"boundary\", this._updatePositions);\n        const planesUpdate = scene.on(\"sectionPlaneUpdated\", this._updatePositions);\n        const planeCreated = scene.on(\"sectionPlaneCreated\", this._updatePositions);\n        const planeDestroyed = scene.on(\"sectionPlaneDestroyed\", this._updatePositions);\n\n        this._cleanup = () => {\n            camera.off(onViewMatrix);\n            camera.off(onProjMatrix);\n            scene.canvas.off(onCanvasBnd);\n            scene.off(planesUpdate);\n            scene.off(planeCreated);\n            scene.off(planeDestroyed);\n            this._wire.destroy();\n        };\n    }\n\n    setEnds(start, end) {\n        this._start.set(start);\n        this._end.set(end);\n        this._updatePositions();\n    }\n\n    setClickable(value) {\n        this._wire.setClickable(value);\n    }\n\n    setColor(value) {\n        this._wire.setColor(value);\n    }\n\n    setHighlighted(value) {\n        this._wire.setHighlighted(value);\n    }\n\n    setOpacity(value) {\n        this._wire.setOpacity(value);\n    }\n\n    setVisible(value) {\n        if (this.__visible != value) {\n            this.__visible = value;\n            this._updatePositions();\n            this._wire.setVisible(value);\n        }\n    }\n\n    destroy() {\n        this._cleanup();\n    }\n\n}\n\nconst marker3D = function(scene, color) {\n    const marker = new Dot3D(scene, {}, scene.canvas.canvas.parentNode, {\n        borderColor: \"white\",\n        fillColor: color,\n        zIndex: 100\n    });\n\n    return {\n        update: function(worldPos) {\n            if (worldPos)\n            {\n                marker.worldPos = worldPos;\n            }\n            marker.setVisible(!!worldPos);\n        },\n\n        setFillColor:  c => marker.setFillColor(c),\n        setHighlighted: h => marker.setHighlighted(h),\n        getCanvasPos:  () => marker.canvasPos,\n        getWorldPos:   () => marker.worldPos,\n        destroy:       () => marker.destroy()\n    };\n};\n\nconst wire3D = function(scene, color) {\n    const wire = new Wire3D(scene, scene.canvas.canvas.ownerDocument.body, {\n        color: color,\n        thickness: 1,\n        thicknessClickable: 6   // TODO: Remove to make not clickable?\n    });\n    wire.setVisible(false);\n    return {\n        update: (startWorldPos, endWorldPos) => {\n            if (endWorldPos)\n            {\n                wire.setEnds(startWorldPos, endWorldPos);\n            }\n            wire.setVisible(!!endWorldPos);\n        },\n\n        setColor: c => wire.setColor(c),\n        destroy: () => wire.destroy()\n    };\n};\n\nfunction activateDraggableDot(dot, cfg) {\n    const extractCFG = function(propName, defaultValue) {\n        if (propName in cfg) {\n            return cfg[propName];\n        } else if (defaultValue !== undefined) {\n            return defaultValue;\n        } else {\n            throw \"config missing: \" + propName;\n        }\n    };\n\n    const viewer = extractCFG(\"viewer\");\n    const ray2WorldPos = extractCFG(\"ray2WorldPos\");\n    const handleMouseEvents = extractCFG(\"handleMouseEvents\", false);\n    const handleTouchEvents = extractCFG(\"handleTouchEvents\", false);\n    const onStart = extractCFG(\"onStart\", nop);\n    const onMove  = extractCFG(\"onMove\",  nop);\n    const onEnd   = extractCFG(\"onEnd\",   nop);\n\n    const scene = viewer.scene;\n    const canvas = scene.canvas.canvas;\n\n    const pickWorldPos = canvasPos => {\n        const origin = math.vec3();\n        const direction = math.vec3();\n        math.canvasPosToWorldRay(canvas, scene.camera.viewMatrix, scene.camera.projMatrix, scene.camera.projection, canvasPos, origin, direction);\n        return ray2WorldPos(origin, direction, canvasPos);\n    };\n\n    const onChange = event => {\n        const canvasPos = math.vec2([ event.clientX, event.clientY ]);\n        transformToNode(canvas.ownerDocument.documentElement, canvas, canvasPos);\n        onMove(canvasPos, pickWorldPos(canvasPos));\n    };\n\n    let currentDrag = null;\n\n    const onDragMove = function(event) {\n        const e = currentDrag.matchesEvent(event);\n        if (e)\n        {\n            onChange(e);\n        }\n    };\n\n    const onDragEnd = function(event) {\n        const e = currentDrag.matchesEvent(event);\n        if (e)\n        {\n            dot.setOpacity(idleOpacity);\n            currentDrag.cleanup();\n            onChange(e);\n            onEnd();\n        }\n    };\n\n    const startDrag = function(matchesEvent, cleanupHandlers) {\n        if (currentDrag) {\n            currentDrag.cleanup();\n        }\n\n        dot.setOpacity(1.0);\n        dot.setClickable(false);\n        viewer.cameraControl.active = false;\n\n        currentDrag = {\n            matchesEvent: matchesEvent,\n            cleanup: function() {\n                currentDrag = null;\n                dot.setClickable(true);\n                viewer.cameraControl.active = true;\n                cleanupHandlers();\n            }\n        };\n\n        onStart();\n    };\n\n    const cleanupDotHandlers = [ ];\n    const dot_on = function(event, callback) {\n        const id = dot.on(event, callback);\n        cleanupDotHandlers.push(() => dot.off(id));\n    };\n\n    if (handleMouseEvents)\n    {\n        dot_on(\"mouseover\",  () => (! currentDrag) && dot.setOpacity(1.0));\n        dot_on(\"mouseleave\", () => (! currentDrag) && dot.setOpacity(idleOpacity));\n        dot_on(\"mousedown\",  event => {\n            if (event.which === 1)\n            {\n                canvas.addEventListener(\"mousemove\", onDragMove);\n                canvas.addEventListener(\"mouseup\",   onDragEnd);\n                startDrag(\n                    event => (event.which === 1) && event,\n                    () => {\n                        canvas.removeEventListener(\"mousemove\", onDragMove);\n                        canvas.removeEventListener(\"mouseup\",   onDragEnd);\n                    });\n            }\n        });\n    }\n\n    if (handleTouchEvents)\n    {\n        let touchStartId;\n        dot_on(\"touchstart\", event => {\n            event.preventDefault();\n            if (event.touches.length === 1)\n            {\n                touchStartId = event.touches[0].identifier;\n                startDrag(\n                    event => [...event.changedTouches].find(e => e.identifier === touchStartId),\n                    () => { touchStartId = null; });\n            }\n        });\n        dot_on(\"touchmove\", event => {\n            event.preventDefault();\n            onDragMove(event);\n        });\n        dot_on(\"touchend\",  event => {\n            event.preventDefault();\n            onDragEnd(event);\n        });\n    }\n\n    const idleOpacity = 0.8;\n    dot.setOpacity(idleOpacity);\n\n    return function() {\n        currentDrag && currentDrag.cleanup();\n        cleanupDotHandlers.forEach(c => c());\n        dot.setOpacity(1.0);\n    };\n}\nfunction activateDraggableDots(cfg) {\n    const extractCFG = function(propName, defaultValue) {\n        if (propName in cfg) {\n            return cfg[propName];\n        } else if (defaultValue !== undefined) {\n            return defaultValue;\n        } else {\n            throw \"config missing: \" + propName;\n        }\n    };\n\n    const viewer = extractCFG(\"viewer\");\n    const handleMouseEvents = extractCFG(\"handleMouseEvents\", false);\n    const handleTouchEvents = extractCFG(\"handleTouchEvents\", false);\n    const pointerLens = extractCFG(\"pointerLens\", null);\n    const dots = extractCFG(\"dots\");\n    const ray2WorldPos = extractCFG(\"ray2WorldPos\");\n    const onEnd = extractCFG(\"onEnd\", nop);\n\n    const updatePointerLens = (pointerLens\n                               ? function(canvasPos) {\n                                   pointerLens.visible = !! canvasPos;\n                                   if (canvasPos)\n                                   {\n                                       pointerLens.canvasPos = canvasPos;\n                                   }\n                               }\n                               : () => { });\n\n    const cleanups = dots.map(dot => {\n        let initPos;\n        return activateDraggableDot(dot, {\n            handleMouseEvents: handleMouseEvents,\n            handleTouchEvents: handleTouchEvents,\n            viewer: viewer,\n            ray2WorldPos: (orig, dir, canvasPos) => (ray2WorldPos(orig, dir, canvasPos) || initPos),\n            onStart: () => {\n                initPos = dot.worldPos.slice();\n                setOtherDotsActive(false, dot);\n            },\n            onMove: (canvasPos, worldPos) => {\n                updatePointerLens(canvasPos);\n                dot.worldPos = worldPos;\n            },\n            onEnd: () => {\n                if (! onEnd(initPos, dot)) {\n                    dot.worldPos = initPos;\n                }\n                updatePointerLens(null);\n                setOtherDotsActive(true, dot);\n            }\n        });\n    });\n\n    const setOtherDotsActive = (active, dot) => dots.forEach(d => (d !== dot) && d.setClickable(active));\n    setOtherDotsActive(true);\n\n    return function() {\n        cleanups.forEach(c => c());\n        updatePointerLens(null);\n    };\n}\n\nconst touchPointSelector = function(viewer, pointerCircle, ray2WorldPos) {\n    return function(onCancel, onChange, onCommit) {\n        const scene = viewer.scene;\n        const canvas = scene.canvas.canvas;\n        const longTouchTimeoutMs = 300;\n        const moveTolerance = 20;\n\n        const copyCanvasPos = (event, vec2) => {\n            vec2[0] = event.clientX;\n            vec2[1] = event.clientY;\n            transformToNode(canvas.ownerDocument.documentElement, canvas, vec2);\n            return vec2;\n        };\n\n        const pickWorldPos = canvasPos => {\n            const origin = math.vec3();\n            const direction = math.vec3();\n            math.canvasPosToWorldRay(canvas, scene.camera.viewMatrix, scene.camera.projMatrix, scene.camera.projection, canvasPos, origin, direction);\n            return ray2WorldPos(origin, direction);\n        };\n\n        let longTouchTimeout = null;\n        const nop = () => { };\n        let onSingleTouchMove = nop;\n        let startTouchIdentifier;\n\n        const resetAction = function() {\n            pointerCircle.stop();\n            clearTimeout(longTouchTimeout);\n            viewer.cameraControl.active = true;\n            onSingleTouchMove = nop;\n            startTouchIdentifier = null;\n        };\n\n        const cleanup = function() {\n            resetAction();\n            canvas.removeEventListener(\"touchstart\", onCanvasTouchStart);\n            canvas.removeEventListener(\"touchmove\",  onCanvasTouchMove);\n            canvas.removeEventListener(\"touchend\",   onCanvasTouchEnd);\n        };\n\n        const onCanvasTouchStart = function(event) {\n            const touches = event.touches;\n\n            if (touches.length !== 1)\n            {\n                resetAction();\n                onCancel();\n            }\n            else\n            {\n                const startTouch = touches[0];\n                const startCanvasPos = copyCanvasPos(startTouch, math.vec2());\n\n                const startWorldPos = pickWorldPos(startCanvasPos);\n                if (startWorldPos)\n                {\n                    startTouchIdentifier = startTouch.identifier;\n\n                    onSingleTouchMove = canvasPos => {\n                        if (math.distVec2(startCanvasPos, canvasPos) > moveTolerance)\n                        {\n                            resetAction();\n                        }\n                    };\n\n                    longTouchTimeout = setTimeout(\n                        function() {\n                            pointerCircle.start(startCanvasPos);\n\n                            longTouchTimeout = setTimeout(\n                                function() {\n                                    pointerCircle.stop();\n\n                                    viewer.cameraControl.active = false;\n\n                                    onSingleTouchMove = canvasPos => {\n                                        onChange(canvasPos, pickWorldPos(canvasPos));\n                                    };\n\n                                    onSingleTouchMove(startCanvasPos);\n                                },\n                                longTouchTimeoutMs);\n                        },\n                        250);\n                }\n            }\n        };\n        canvas.addEventListener(\"touchstart\", onCanvasTouchStart, {passive: true});\n\n        // canvas.addEventListener(\"touchcancel\", e => console.log(\"touchcancel\", e), {passive: true});\n\n        const onCanvasTouchMove = function(event) {\n            const touch = [...event.changedTouches].find(e => e.identifier === startTouchIdentifier);\n            if (touch)\n            {\n                onSingleTouchMove(copyCanvasPos(touch, math.vec2()));\n            }\n        };\n        canvas.addEventListener(\"touchmove\", onCanvasTouchMove, {passive: true});\n\n        const onCanvasTouchEnd = function(event) {\n            const touch = [...event.changedTouches].find(e => e.identifier === startTouchIdentifier);\n            if (touch)\n            {\n                cleanup();\n                const canvasPos = copyCanvasPos(touch, math.vec2());\n                onCommit(canvasPos, pickWorldPos(canvasPos));\n            }\n        };\n        canvas.addEventListener(\"touchend\", onCanvasTouchEnd, {passive: true});\n\n        return cleanup;\n    };\n};\n\nconst triangulateEarClipping = function(planeCoords) {\n    const polygonVertices = [ ];\n    for (let i = 0; i < planeCoords.length; ++i)\n        polygonVertices.push(i);\n\n    const isCCW = (function() {\n        const ba = math.vec2();\n        const bc = math.vec2();\n\n        let anglesSum = 0;\n\n        for (let i = 0; i < polygonVertices.length; ++i)\n        {\n            const a = planeCoords[polygonVertices[i]];\n            const b = planeCoords[polygonVertices[(i + 1) % polygonVertices.length]];\n            const c = planeCoords[polygonVertices[(i + 2) % polygonVertices.length]];\n\n            math.subVec2(a, b, ba);\n            math.subVec2(c, b, bc);\n\n            const theta = math.dotVec2(ba, bc) / Math.sqrt(math.sqLenVec2(ba) * math.sqLenVec2(bc));\n            const angle = Math.acos(Math.max(-1, Math.min(theta, 1)));\n            const convex = (ba[0] * bc[1] - ba[1] * bc[0]) >= 0;\n            anglesSum += convex ? angle : (2 * Math.PI - angle);\n        }\n\n        return anglesSum < (polygonVertices.length * Math.PI);\n    })();\n\n    const pointInTriangle = (function() {\n        const sign = (p1, p2, p3) => {\n            return (p1[0] - p3[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p3[1]);\n        };\n\n        return (pt, v1, v2, v3) => {\n            const d1 = sign(pt, v1, v2);\n            const d2 = sign(pt, v2, v3);\n            const d3 = sign(pt, v3, v1);\n\n            const has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);\n            const has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);\n\n            return !(has_neg && has_pos);\n        };\n    })();\n\n    const baseTriangles = [ ];\n\n    const vertices = (isCCW ? polygonVertices : polygonVertices.slice(0).reverse()).map(i => ({ idx: i }));\n    vertices.forEach((v, i) => {\n        v.prev = vertices[(i - 1 + vertices.length) % vertices.length];\n        v.next = vertices[(i + 1)                   % vertices.length];\n    });\n\n    const ba = math.vec2();\n    const bc = math.vec2();\n\n    while (vertices.length > 2) {\n        let earIdx = 0;\n        while (true) {\n            if (earIdx >= vertices.length)\n            {\n                throw `isCCW = ${isCCW}; earIdx = ${earIdx}; len = ${vertices.length}`;\n            }\n            const v = vertices[earIdx];\n\n            const a = planeCoords[v.prev.idx];\n            const b = planeCoords[v.idx];\n            const c = planeCoords[v.next.idx];\n\n            math.subVec2(a, b, ba);\n            math.subVec2(c, b, bc);\n\n            if (((ba[0] * bc[1] - ba[1] * bc[0]) >= 0) // a convex vertex\n                &&\n                vertices.every( // no other vertices inside\n                    vv => ((vv === v)\n                           ||\n                           (vv === v.prev)\n                           ||\n                           (vv === v.next)\n                           ||\n                           !pointInTriangle(planeCoords[vv.idx], a, b, c))))\n                break;\n            ++earIdx;\n        }\n\n        const ear = vertices[earIdx];\n        vertices.splice(earIdx, 1);\n\n        baseTriangles.push([ ear.idx, ear.next.idx, ear.prev.idx ]);\n\n        const prev = ear.prev;\n        prev.next = ear.next;\n        const next = ear.next;\n        next.prev = ear.prev;\n    }\n\n    return [ planeCoords, baseTriangles, isCCW ];\n};\n\nconst addMousePressListener = function(element, onChange) {\n    const moveTolerance = 4;\n\n    const copyElementPos = (event, out) => {\n        out[0] = event.clientX;\n        out[1] = event.clientY;\n        transformToNode(element.ownerDocument.documentElement, element, out);\n        return out;\n    };\n\n    let buttonDown = false;\n\n    const cleanups = [ ];\n    const cleanup = () => cleanups.forEach(c => c());\n\n    const addElementEventListener = (type, listener) => {\n        element.addEventListener(type, listener);\n        cleanups.push(() => element.removeEventListener(type, listener));\n    };\n\n    const downPos = math.vec2();\n    addElementEventListener(\"mousedown\", function(event) {\n        if (event.which === 1) {\n            buttonDown = true;\n            onChange(copyElementPos(event, downPos));\n        }\n    });\n\n    addElementEventListener(\"mousemove\", function(event) {\n        copyElementPos(event, tmpVec2a);\n        if (buttonDown && (math.distVec2(downPos, tmpVec2a) > moveTolerance)) {\n            buttonDown = false;\n        }\n        if (buttonDown || (! event.buttons & 1)) {\n            onChange(tmpVec2a);\n        }\n    });\n\n    addElementEventListener(\"mouseup\", function(event) {\n        if ((event.which === 1) && buttonDown) {\n            const commit = onChange(copyElementPos(event, tmpVec2a));\n            if (commit) {\n                cleanup();\n                commit();\n            }\n        }\n    });\n\n    return cleanup;\n};\n\nconst addTouchPressListener = function(element, cameraControl, pointerCircle, onChange) {\n    const longTouchTimeoutMs = 300;\n    const moveTolerance = 20;\n    const startPos = math.vec2();\n\n    const copyElementPos = (event, out) => {\n        out[0] = event.clientX;\n        out[1] = event.clientY;\n        transformToNode(element.ownerDocument.documentElement, element, out);\n        return out;\n    };\n\n    let longTouchTimeout = null;\n    let onSingleTouchMove = nop;\n    let startTouchIdentifier;\n\n    const resetAction = function() {\n        clearTimeout(longTouchTimeout);\n        pointerCircle.stop();\n        cameraControl.active = true;\n        onSingleTouchMove = nop;\n        startTouchIdentifier = null;\n    };\n\n    const cleanups = [ ];\n    const cleanup = () => cleanups.forEach(c => c());\n\n    const addElementEventListener = (type, listener) => {\n        element.addEventListener(type, listener, {passive: true});\n        cleanups.push(() => element.removeEventListener(type, listener));\n    };\n\n    addElementEventListener(\"touchstart\", function(event) {\n        const touches = event.touches;\n\n        if (touches.length !== 1)\n        {\n            resetAction();\n            onChange(null);\n        }\n        else\n        {\n            const touch = touches[0];\n            copyElementPos(touch, startPos);\n\n            startTouchIdentifier = touch.identifier;\n\n            onSingleTouchMove = elementPos => {\n                if (math.distVec2(startPos, elementPos) > moveTolerance)\n                {\n                    resetAction();\n                }\n            };\n\n            longTouchTimeout = setTimeout(\n                function() {\n                    pointerCircle.start(startPos);\n\n                    longTouchTimeout = setTimeout(\n                        function() {\n                            pointerCircle.stop();\n                            cameraControl.active = false;\n                            onSingleTouchMove = onChange;\n                            onSingleTouchMove(startPos);\n                        },\n                        longTouchTimeoutMs);\n                },\n                250);\n        }\n    });\n\n    // element.addEventListener(\"touchcancel\", e => console.log(\"touchcancel\", e), {passive: true});\n\n    addElementEventListener(\"touchmove\", function(event) {\n        const touch = [...event.changedTouches].find(e => e.identifier === startTouchIdentifier);\n        if (touch)\n        {\n            onSingleTouchMove(copyElementPos(touch, tmpVec2a));\n        }\n    });\n\n    addElementEventListener(\"touchend\", function(event) {\n        const touch = [...event.changedTouches].find(e => e.identifier === startTouchIdentifier);\n        if (touch)\n        {\n            const commit = onChange(copyElementPos(touch, tmpVec2a));\n            resetAction();\n\t    if (commit) {\n\t        cleanup();\n\t\tcommit();\n\t    } else {\n                onChange(null);\n            }\n        }\n    });\n\n    return () => {\n        resetAction();\n        cleanup();\n    };\n};\n\nconst startPolygonCreate = function(scene, pointerLens, addPressListener, pickRayResult, onChange, onConclude) {\n    const canvas = scene.canvas.canvas;\n\n    const updatePointerLens = (pointerLens\n                               ? function(canvasPos, isSnapped) {\n                                   pointerLens.visible = !! canvasPos;\n                                   if (canvasPos)\n                                   {\n                                       pointerLens.canvasPos = canvasPos;\n                                       pointerLens.snapped = !! isSnapped;\n                                   }\n                               }\n                               : () => { });\n\n    const testLastSegmentIntersects = (function() {\n        const onSegment = (p, q, r) => ((q[0] <= Math.max(p[0], r[0])) &&\n                                        (q[0] >= Math.min(p[0], r[0])) &&\n                                        (q[1] <= Math.max(p[1], r[1])) &&\n                                        (q[1] >= Math.min(p[1], r[1])));\n\n        const orient = (p, q, r) => {\n            const val = (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]);\n            // collinear\n            // clockwise\n            // counterclockwise\n            return ((val === 0) ? 0 : ((val > 0) ? 1 : 2));\n        };\n\n        return function(pos2D, lastSegmentClosesLoop) {\n            const s = lastSegmentClosesLoop ? 1 : 0;\n            const a = pos2D[(pos2D.length - 2 + s) % pos2D.length];\n            const b = pos2D[(pos2D.length - 1 + s) % pos2D.length];\n\n            for (let i = s; i < pos2D.length - 2 - 1 + s; ++i) {\n                const c = pos2D[i];\n                const d = pos2D[i + 1];\n\n                const o1 = orient(a, b, c);\n                const o2 = orient(a, b, d);\n                const o3 = orient(c, d, a);\n                const o4 = orient(c, d, b);\n\n                if (((o1 !== o2) && (o3 !== o4))       || // General case\n                    ((o1 === 0) && onSegment(a, c, b)) || // a, b and c are collinear and c lies on segment ab\n                    ((o2 === 0) && onSegment(a, d, b)) || // a, b and d are collinear and d lies on segment ab\n                    ((o3 === 0) && onSegment(c, a, d)) || // c, d and a are collinear and a lies on segment cd\n                    ((o4 === 0) && onSegment(c, b, d)))   // c, d and b are collinear and b lies on segment cd\n                {\n                    return true;\n                }\n            }\n\n            return false;\n        };\n    })();\n\n    const getPlane = (points) => (points.length >= 3) && (function() {\n        const u      = math.normalizeVec3(math.subVec3(points[1], points[0], math.vec3()));\n        const v20    = math.normalizeVec3(math.subVec3(points[2], points[0], tmpVec3a$2));\n        const normal = math.normalizeVec3(math.cross3Vec3(u, v20, math.vec3()));\n        const v      = math.normalizeVec3(math.cross3Vec3(normal, u, math.vec3()));\n        return {\n            normal: normal,\n            origin: math.vec3(points[0]),\n            u:      u,\n            v:      v\n        };\n    })();\n\n    const vertices = [ ];\n    let currentInteraction;\n\n    (function selectNextPoint() {\n        const plane = getPlane(vertices);\n\n        const canvasPos2Ray = (canvasPos, dst) => (math.canvasPosToWorldRay(canvas, scene.camera.viewMatrix, scene.camera.projMatrix, scene.camera.projection, canvasPos, dst.origin, dst.direction), dst);\n\n        const pickRay = (ray) => {\n            const pickResult = pickRayResult(ray);\n            const snapWorldPos = pickResult && pickResult.entity && ((! plane) || pickResult.snapped) && pickResult.worldPos;\n            if (plane) {\n                const originDistance = math.dotVec3(plane.normal, plane.origin);\n                const snapPlaneDist = (snapWorldPos\n                                       ? ((originDistance - math.dotVec3(snapWorldPos, plane.normal)))\n                                       : window.Infinity);\n                if (Math.abs(snapPlaneDist) < 0.0001) {\n                    const ret = math.vec3();\n                    return {\n                        worldPos: math.addVec3(snapWorldPos, math.mulVec3Scalar(plane.normal, snapPlaneDist, ret), ret),\n                        snapped:  true\n                    };\n                } else {\n                    return {\n                        worldPos: planeIntersect$1(originDistance, plane.normal, ray.origin, ray.direction),\n                        snapped:  false\n                    };\n                }\n            } else {\n                return {\n                    worldPos: snapWorldPos,\n                    snapped:  pickResult && pickResult.snapped\n                };\n            }\n        };\n\n        let placeVertex = false;\n        const removePressListener = addPressListener(\n            (inputCanvasPos) => {\n                const rayPick = inputCanvasPos && pickRay(canvasPos2Ray(inputCanvasPos, tmpRay));\n                const worldPos = rayPick && rayPick.worldPos;\n                return onWorldPos(worldPos, inputCanvasPos, rayPick && rayPick.snapped);\n            });\n\n        const onWorldPos = (worldPos, inputCanvasPos, rayPickSnapped) => {\n                const canvasPos = worldPos ? scene.camera.projectWorldPos(worldPos) : inputCanvasPos;\n                const firstMarker = (vertices.length > 0) && (function() {\n                    const v = vertices[0];\n                    return {\n                        canvasPos: scene.camera.projectWorldPos(v),\n                        worldPos: v\n                    };\n                })();\n                const snapToFirst = (vertices.length >= 3) && ((canvasPos && (math.distVec2(canvasPos, firstMarker.canvasPos) < 10))\n                                                               ||\n                                                               (worldPos && math.compareVec3(worldPos, firstMarker.worldPos)));\n\n                updatePointerLens(snapToFirst ? firstMarker.canvasPos : canvasPos, snapToFirst || rayPickSnapped);\n\n                const lastPointOverlaps = (inputCanvasPos\n                                           &&\n                                           ((! worldPos)\n                                            ||\n                                            ((vertices.length < 3)\n                                             ? vertices.some(v => math.compareVec3(v, worldPos))\n                                             : math.compareVec3(vertices[vertices.length - 1], worldPos))));\n\n                const points = vertices.concat(((! snapToFirst) && worldPos && (! lastPointOverlaps)) ? [worldPos] : []);\n\n                const curPlane = (! lastPointOverlaps) && (plane || getPlane(points));\n\n                const uvs = curPlane && points.map(p => {\n                    math.subVec3(p, curPlane.origin, tmpVec3a$2);\n                    return math.vec2([ math.dotVec3(tmpVec3a$2, curPlane.u), math.dotVec3(tmpVec3a$2, curPlane.v) ]);\n                });\n\n                const isValid = (! lastPointOverlaps) && (! (uvs && testLastSegmentIntersects(uvs, snapToFirst)));\n                const geometry = isValid && uvs && (snapToFirst || (! testLastSegmentIntersects(uvs, true))) && (function() {\n                    try {\n                        const [ baseVertices, baseTriangles, isCCW ] = triangulateEarClipping(uvs);\n                        return {\n                            faces: baseTriangles,\n                            vertices: baseVertices.map(uv => math.addVec3(\n                                curPlane.origin,\n                                math.addVec3(\n                                    math.mulVec3Scalar(curPlane.u, uv[0], tmpVec3a$2),\n                                    math.mulVec3Scalar(curPlane.v, uv[1], tmpVec3b$2),\n                                    tmpVec3a$2),\n                                math.vec3()))\n                        };\n                    } catch (e) {\n                        console.warn(\"e\", e);\n                        return false;\n                    }\n                })();\n\n                onChange(points, snapToFirst, isValid, geometry);\n\n                return placeVertex = (isValid && (snapToFirst\n                                                  ? () => {\n                                                      updatePointerLens(null);\n                                                      onConclude();\n                                                  }\n                                                  : () => {\n                                                      vertices.push(math.vec3(worldPos));\n                                                      updatePointerLens(null);\n                                                      selectNextPoint();\n                                                  }));\n            };\n\n        currentInteraction = {\n            closePolygon: (() => {\n                const commit = (vertices.length >= 3) && onWorldPos(vertices[0]);\n                if (commit) {\n                    removePressListener();\n                    commit();\n                }\n                return !! commit;\n            }),\n            placeVertex: () => {\n                if (placeVertex) {\n                    removePressListener();\n                    placeVertex();\n                }\n                return !!placeVertex;\n            },\n            popVertex: () => {\n                if (vertices.length > 0) {\n                    removePressListener();\n                    vertices.pop();\n                    selectNextPoint();\n                    return true;\n                } else {\n                    return false;\n                }\n            },\n            removePressListener: removePressListener,\n            updateOnChange: () => onWorldPos()\n        };\n    })();\n\n    return {\n        cancel: () => {\n            currentInteraction.removePressListener();\n            updatePointerLens(null);\n        },\n        closePolygon:   () => currentInteraction.closePolygon(),\n        placeVertex:    () => currentInteraction.placeVertex(),\n        popVertex:      () => currentInteraction.popVertex(),\n        updateOnChange: () => currentInteraction.updateOnChange()\n    };\n};\n\n/**\n * The 3D Viewer at the heart of the xeokit SDK.\n *\n * * A Viewer wraps a single {@link Scene}\n * * Add {@link Plugin}s to a Viewer to extend its functionality.\n * * {@link Viewer#metaScene} holds metadata about models in the\n * Viewer's {@link MetaScene}.\n * * Use {@link Viewer#cameraFlight} to fly or jump the {@link Scene}'s\n * {@link Camera} to target positions, boundaries or {@link Entity}s.\n *\n * @public\n */\nclass Viewer {\n\n    /**\n     * @constructor\n     * @param {Object} cfg Viewer configuration.\n     * @param {String} [cfg.id] Optional ID for this Viewer, defaults to the ID of {@link Viewer#scene}, which xeokit automatically generates.\n     * @param {String} [cfg.canvasId]  ID of an existing HTML canvas for the {@link Viewer#scene} - either this or canvasElement is mandatory. When both values are given, the element reference is always preferred to the ID.\n     * @param {HTMLCanvasElement} [cfg.canvasElement] Reference of an existing HTML canvas for the {@link Viewer#scene} - either this or canvasId is mandatory. When both values are given, the element reference is always preferred to the ID.\n     * @param {HTMLElement} [cfg.keyboardEventsElement] Optional reference to HTML element on which key events should be handled. Defaults to the HTML Document.\n     * @param {String} [cfg.spinnerElementId]  ID of existing HTML element to show the {@link Spinner} - internally creates a default element automatically if this is omitted.\n     * @param {Number} [cfg.passes=1] The number of times the {@link Viewer#scene} renders per frame.\n     * @param {Boolean} [cfg.clearEachPass=false] When doing multiple passes per frame, specifies if to clear the canvas before each pass (true) or just before the first pass (false).\n     * @param {Boolean} [cfg.preserveDrawingBuffer=true]  Whether or not to preserve the WebGL drawing buffer. This needs to be ````true```` for {@link Viewer#getSnapshot} to work.\n     * @param {Boolean} [cfg.transparent=true]  Whether or not the canvas is transparent.\n     * @param {Boolean} [cfg.premultipliedAlpha=false]  Whether or not you want alpha composition with premultiplied alpha. Highlighting and selection works best when this is ````false````.\n     * @param {Boolean} [cfg.gammaInput=true]  When true, expects that all textures and colors are premultiplied gamma.\n     * @param {Boolean} [cfg.gammaOutput=false]  Whether or not to render with pre-multiplied gama.\n     * @param {Number} [cfg.gammaFactor=2.2] The gamma factor to use when rendering with pre-multiplied gamma.\n     * @param {Number[]} [cfg.backgroundColor=[1,1,1]] Sets the canvas background color to use when ````transparent```` is false.\n     * @param {Boolean} [cfg.backgroundColorFromAmbientLight=true] When ````transparent```` is false, set this ````true````\n     * to derive the canvas background color from {@link AmbientLight#color}, or ````false```` to set the canvas background to ````backgroundColor````.\n     * @param {String} [cfg.units=\"meters\"] The measurement unit type. Accepted values are ````\"meters\"````, ````\"metres\"````, , ````\"centimeters\"````, ````\"centimetres\"````, ````\"millimeters\"````,  ````\"millimetres\"````, ````\"yards\"````, ````\"feet\"```` and ````\"inches\"````.\n     * @param {Number} [cfg.scale=1] The number of Real-space units in each World-space coordinate system unit.\n     * @param {Number[]} [cfg.origin=[0,0,0]] The Real-space 3D origin, in current measurement units, at which the World-space coordinate origin ````[0,0,0]```` sits.\n     * @param {Boolean} [cfg.saoEnabled=false] Whether to enable Scalable Ambient Obscurance (SAO) effect. See {@link SAO} for more info.\n     * @param {Boolean} [cfg.antialias=true] Whether to enable anti-aliasing.\n     * @throws {String} Throws an exception when both canvasId or canvasElement are missing or they aren't pointing to a valid HTMLCanvasElement.\n     * @param {Boolean} [cfg.alphaDepthMask=true] Whether writing into the depth buffer is enabled or disabled when rendering transparent objects.\n     * @param {Boolean} [cfg.entityOffsetsEnabled=false] Whether to enable {@link Entity#offset}. For best performance, only set this ````true```` when you need to use {@link Entity#offset}.\n     * @param {Boolean} [cfg.readableGeometryEnabled=false] Whether to enable full-precision accuracy when surface picking with {@link Scene#pick}. Note that when ````true````, this configuration will increase the amount of browser memory used by the Viewer. The ````pickSurfacePrecision```` option for ````Scene#pick```` only works if this is set ````true````.\n     * @param {Boolean} [cfg.logarithmicDepthBufferEnabled=false] Whether to enable logarithmic depth buffer. When this is true,\n     * you can set huge values for {@link Perspective#far} and {@link Ortho#far}, to push the far clipping plane back so\n     * that it does not clip huge models.\n     * @param {Boolean} [cfg.colorTextureEnabled=true] Whether to enable base color texture rendering.\n     * @param {Boolean} [cfg.pbrEnabled=false] Whether to enable physically-based rendering.\n     * @param {LocaleService} [cfg.localeService=null] Optional locale-based translation service.\n     * @param {Boolean} [cfg.dtxEnabled=false] Whether to enable data texture-based (DTX) scene representation within the Viewer. When this is true, the Viewer will use data textures to\n     * store geometry on the GPU for triangle meshes that don't have textures. This gives a much lower memory footprint for these types of model element. This mode may not perform well on low-end GPUs that are optimized\n     * to use textures to hold geometry data. Works great on most medium/high-end GPUs found in desktop computers, including the nVIDIA and Intel HD chipsets. Set this false to use the default vertex buffer object (VBO)\n     * mode for storing geometry, which is the standard technique used in most graphics engines, and will work adequately on most low-end GPUs.\n     * @param {Number} [cfg.markerZOffset=-0.001] The Z value of offset for Marker's OcclusionTester. The closest the value is to 0.000 the more precise OcclusionTester will be, but at the same time the less precise it will behave for Markers that are located exactly on the Surface.\n     * @param {number} [cfg.numCachedSectionPlanes=0] Enhances the efficiency of SectionPlane creation by proactively allocating Viewer resources for a specified quantity\n     * of SectionPlanes. Introducing this parameter streamlines the initial creation speed of SectionPlanes, particularly up to the designated quantity. This parameter internally\n     * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing\n     * responsiveness. It is important to consider that each SectionPlane impacts rendering performance, so it is recommended to set this value to a quantity that aligns with\n     * your expected usage.\n     */\n    constructor(cfg) {\n\n        /**\n         * The Viewer's current language setting.\n         * @property language\n         * @deprecated\n         * @type {String}\n         */\n        this.language = \"en\";\n\n        /**\n         * The viewer's locale service.\n         *\n         * This is configured via the Viewer's constructor.\n         *\n         * By default, this service will be an instance of {@link LocaleService}, which will just return\n         * null translations for all given strings and phrases.\n         *\n         * @property localeService\n         * @type {LocaleService}\n         * @since 2.0\n         */\n        this.localeService = cfg.localeService || new LocaleService();\n\n        /**\n         * The Viewer's {@link Scene}.\n         * @property scene\n         * @type {Scene}\n         */\n        this.scene = new Scene(this, {\n            canvasId: cfg.canvasId,\n            canvasElement: cfg.canvasElement,\n            keyboardEventsElement: cfg.keyboardEventsElement,\n            contextAttr: {\n                preserveDrawingBuffer: cfg.preserveDrawingBuffer !== false,\n                premultipliedAlpha: (!!cfg.premultipliedAlpha),\n                antialias: (cfg.antialias !== false)\n            },\n            spinnerElementId: cfg.spinnerElementId,\n            transparent: (cfg.transparent !== false),\n            gammaInput: true,\n            gammaOutput: false,\n            backgroundColor: cfg.backgroundColor,\n            backgroundColorFromAmbientLight: cfg.backgroundColorFromAmbientLight,\n            ticksPerRender: 1,\n            ticksPerOcclusionTest: 20,\n            units: cfg.units,\n            scale: cfg.scale,\n            origin: cfg.origin,\n            saoEnabled: cfg.saoEnabled,\n            alphaDepthMask: (cfg.alphaDepthMask !== false),\n            entityOffsetsEnabled: (!!cfg.entityOffsetsEnabled),\n            readableGeometryEnabled: (!!cfg.readableGeometryEnabled),\n            logarithmicDepthBufferEnabled: (!!cfg.logarithmicDepthBufferEnabled),\n            pbrEnabled: (!!cfg.pbrEnabled),\n            colorTextureEnabled: (cfg.colorTextureEnabled !== false),\n            dtxEnabled: (!!cfg.dtxEnabled),\n            markerZOffset: cfg.markerZOffset,\n            numCachedSectionPlanes: cfg.numCachedSectionPlanes\n        });\n\n        /**\n         * Metadata about the {@link Scene} and the models and objects within it.\n         * @property metaScene\n         * @type {MetaScene}\n         * @readonly\n         */\n        this.metaScene = new MetaScene(this, this.scene);\n\n        /**\n         * The Viewer's ID.\n         * @property id\n         *\n         * @type {String|Number}\n         */\n        this.id = cfg.id || this.scene.id;\n\n        /**\n         * The Viewer's {@link Camera}. This is also found on {@link Scene#camera}.\n         * @property camera\n         * @type {Camera}\n         */\n        this.camera = this.scene.camera;\n\n        /**\n         * The Viewer's {@link CameraFlightAnimation}, which\n         * is used to fly the {@link Scene}'s {@link Camera} to given targets.\n         * @property cameraFlight\n         * @type {CameraFlightAnimation}\n         */\n        this.cameraFlight = new CameraFlightAnimation(this.scene, {\n            duration: 0.5\n        });\n\n        /**\n         * The Viewer's {@link CameraControl}, which\n         * controls the {@link Scene}'s {@link Camera} with mouse,  touch and keyboard input.\n         * @property cameraControl\n         * @type {CameraControl}\n         */\n        this.cameraControl = new CameraControl(this.scene, {\n            // panToPointer: true,\n            doublePickFlyTo: true\n        });\n\n        this._plugins = [];\n\n        /**\n         * Subscriptions to events sent with {@link fire}.\n         * @private\n         */\n        this._eventSubs = {};\n    }\n\n    /**\n     * Returns the capabilities of this Viewer.\n     *\n     * @returns {{astcSupported: boolean, etc1Supported: boolean, pvrtcSupported: boolean, etc2Supported: boolean, dxtSupported: boolean, bptcSupported: boolean}}\n     */\n    get capabilities() {\n        return this.scene.capabilities;\n    }\n\n    /**\n     * Subscribes to an event fired at this Viewer.\n     *\n     * @param {String} event The event\n     * @param {Function} callback Callback fired on the event\n     */\n    on(event, callback) {\n        let subs = this._eventSubs[event];\n        if (!subs) {\n            subs = [];\n            this._eventSubs[event] = subs;\n        }\n        subs.push(callback);\n    }\n\n    /**\n     * Fires an event at this Viewer.\n     *\n     * @param {String} event Event name\n     * @param {Object} value Event parameters\n     */\n    fire(event, value) {\n        const subs = this._eventSubs[event];\n        if (subs) {\n            for (let i = 0, len = subs.length; i < len; i++) {\n                subs[i](value);\n            }\n        }\n    }\n\n    /**\n     * Unsubscribes from an event fired at this Viewer.\n     * @param event\n     */\n    off(event) { // TODO\n\n    }\n\n    /**\n     * Logs a message to the JavaScript developer console, prefixed with the ID of this Viewer.\n     *\n     * @param {String} msg The message\n     */\n    log(msg) {\n        console.log(`[xeokit viewer ${this.id}]: ${msg}`);\n    }\n\n    /**\n     * Logs an error message to the JavaScript developer console, prefixed with the ID of this Viewer.\n     *\n     * @param {String} msg The error message\n     */\n    error(msg) {\n        console.error(`[xeokit viewer ${this.id}]: ${msg}`);\n    }\n\n    /**\n     * Installs a Plugin.\n     *\n     * @private\n     */\n    addPlugin(plugin) {\n        this._plugins.push(plugin);\n    }\n\n    /**\n     * Uninstalls a Plugin, clearing content from it first.\n     *\n     * @private\n     */\n    removePlugin(plugin) {\n        for (let i = 0, len = this._plugins.length; i < len; i++) {\n            const p = this._plugins[i];\n            if (p === plugin) {\n                if (p.clear) {\n                    p.clear();\n                }\n                this._plugins.splice(i, 1);\n                return;\n            }\n        }\n    }\n\n    /**\n     * Sends a message to installed Plugins.\n     *\n     * The message can optionally be accompanied by a value.\n     * @private\n     */\n    sendToPlugins(name, value) {\n        for (let i = 0, len = this._plugins.length; i < len; i++) {\n            const p = this._plugins[i];\n            if (p.send) {\n                p.send(name, value);\n            }\n        }\n    }\n\n    /**\n     * @private\n     * @deprecated\n     */\n    clear() {\n        throw \"Viewer#clear() no longer implemented - use '#sendToPlugins(\\\"clear\\\") instead\";\n    }\n\n    /**\n     * @private\n     * @deprecated\n     */\n    resetView() {\n        throw \"Viewer#resetView() no longer implemented - use CameraMemento & ObjectsMemento classes instead\";\n    }\n\n    /**\n     * Enter snapshot mode.\n     *\n     * Switches rendering to a hidden snapshot canvas.\n     *\n     * Exit snapshot mode using {@link Viewer#endSnapshot}.\n     */\n    beginSnapshot() {\n        if (! this._snapshotBegun) {\n            this.scene._renderer.snapshot.beginSnapshot();\n            this._snapshotBegun = true;\n        }\n    }\n\n    _renderSnapshotToCanvas(params) {\n        const resize = (params.width !== undefined && params.height !== undefined);\n        const canvas = this.scene.canvas.canvas;\n        const saveWidth  = canvas.clientWidth;\n        const saveHeight = canvas.clientHeight;\n        const excludeGizmos = !params.includeGizmos;\n\n        if (resize) {\n            canvas.width  = params.width  ? Math.floor(params.width)  : canvas.width;\n            canvas.height = params.height ? Math.floor(params.height) : canvas.height;\n        }\n\n        this.beginSnapshot();\n\n        if (excludeGizmos) {\n            this.sendToPlugins(\"snapshotStarting\"); // Tells plugins to hide things that shouldn't be in snapshot\n        }\n\n        const snapshotCanvas = this.scene._renderer.snapshot.renderSnapshotToCanvas();\n\n        if (resize) {\n            canvas.width = saveWidth;\n            canvas.height = saveHeight;\n            this.scene.glRedraw();\n        }\n\n        return {\n            canvas:    snapshotCanvas,\n            toDataURL: () => {\n                if (excludeGizmos) {\n                    this.sendToPlugins(\"snapshotFinished\");\n                }\n\n                this.endSnapshot();\n\n                let format = params.format || \"png\";\n                if (format !== \"jpeg\" && format !== \"png\" && format !== \"bmp\") {\n                    console.error(\"Unsupported image format: '\" + format + \"' - supported types are 'jpeg', 'bmp' and 'png' - defaulting to 'png'\");\n                    format = \"png\";\n                }\n                return snapshotCanvas.toDataURL(`image/${format}`);\n            }\n        };\n    }\n\n    /**\n     * Gets a snapshot of this Viewer's {@link Scene} as a Base64-encoded image.\n     *\n     * #### Usage:\n     *\n     * ````javascript\n     * const imageData = viewer.getSnapshot({\n     *    width: 500,\n     *    height: 500,\n     *    format: \"png\"\n     * });\n     * ````\n     * @param {*} [params] Capture options.\n     * @param {Number} [params.width] Desired width of result in pixels - defaults to width of canvas.\n     * @param {Number} [params.height] Desired height of result in pixels - defaults to height of canvas.\n     * @param {String} [params.format=\"jpeg\"] Desired format; \"jpeg\", \"png\" or \"bmp\".\n     * @param {Boolean} [params.includeGizmos=false] When true, will include gizmos like {@link SectionPlane} in the snapshot.\n     * @returns {String} String-encoded image data URI.\n     */\n    getSnapshot(params = {}) {\n        // firing \"rendering\" is necessary to trigger DTX{Lines,Triangles}Layer::_uploadDeferredFlags\n        this.scene.fire(\"rendering\", { }, true);\n        return this._renderSnapshotToCanvas(params).toDataURL();\n    }\n\n    /**\n     * Gets a snapshot of this Viewer's {@link Scene} as a Base64-encoded image which includes\n     * the HTML elements created by various plugins.\n     *\n     * The snapshot image is composed of an image of the viewer canvas, overlaid with an image\n     * of the HTML container element belonging to each installed Viewer plugin. Each container\n     * element is only rendered once, so it's OK for plugins to share the same container.\n     *\n     * #### Usage:\n     *\n     * ````javascript\n     * viewer.getSnapshotWithPlugins({\n     *    width: 500,\n     *    height: 500,\n     *    format: \"png\"\n     * }).then((imageData)=>{\n     *\n     * });\n     * ````\n     * @param {*} [params] Capture options.\n     * @param {Number} [params.width] Desired width of result in pixels - defaults to width of canvas.\n     * @param {Number} [params.height] Desired height of result in pixels - defaults to height of canvas.\n     * @param {String} [params.format=\"jpeg\"] Desired format; \"jpeg\", \"png\" or \"bmp\".\n     * @param {Boolean} [params.includeGizmos=false] When true, will include gizmos like {@link SectionPlane} in the snapshot.\n     * @returns {Promise} Promise which returns a string-encoded image data URI.\n     */\n    async getSnapshotWithPlugins(params = {}) {\n\n        // We use gl.readPixels to get the WebGL canvas snapshot in a new\n        // HTMLCanvas element, scaled to the target snapshot size, then\n        // use html2canvas to render each plugin's container element into\n        // that HTMLCanvas. Finally, we save the HTMLCanvas to a bitmap.\n\n        // We don't rely on html2canvas to up-scale our WebGL canvas\n        // when we want a higher-resolution snapshot, which would cause\n        // blurring. Instead, we manage the scale and redraw of the WebGL\n        // canvas ourselves, in order to allow the Viewer to render the\n        // right amount of pixels, for a sharper image.\n\n\n        const snapshotResult = this._renderSnapshotToCanvas(params);\n\n        const pluginToCapture = {};\n        const pluginContainerElements = [];\n\n        for (let i = 0, len = this._plugins.length; i < len; i++) { // Find plugin container elements\n            const plugin = this._plugins[i];\n            if (plugin.getContainerElement) {\n                const containerElement = plugin.getContainerElement();\n                if (containerElement !== document.body) {\n                    if (!pluginToCapture[containerElement.id]) {\n                        pluginToCapture[containerElement.id] = true;\n                        pluginContainerElements.push(containerElement);\n                    }\n                }\n            }\n        }\n\n        // Added to fix label's text offset in an html2canvas capture (See XEOK-151)\n        // based on https://github.com/niklasvh/html2canvas/issues/2775#issuecomment-1316356991\n        const style = document.createElement('style');\n        document.head.appendChild(style);\n        style.sheet?.insertRule('body > div:last-child img { display: inline-block; }');\n\n        const snapshotCanvas = snapshotResult.canvas;\n        for (let i = 0, len = pluginContainerElements.length; i < len; i++) {\n            const containerElement = pluginContainerElements[i];\n            await html2canvas(containerElement, {\n                canvas: snapshotCanvas,\n                backgroundColor: null,\n                scale: snapshotCanvas.width / containerElement.clientWidth\n            });\n            // Reverts translation and scaling applied to the snapshotCanvas's context\n            // by the html2canvas call (inside the ForeignObjectRenderer's constructor)\n            // (implemented to compensate XCD-153 issue)\n            snapshotCanvas.getContext(\"2d\").resetTransform();\n        }\n\n        style.remove();\n\n        return snapshotResult.toDataURL();\n    }\n\n    /**\n     * Exits snapshot mode.\n     *\n     * Switches rendering back to the main canvas.\n     *\n     */\n    endSnapshot() {\n        if (this._snapshotBegun) {\n            this.scene._renderer.snapshot.endSnapshot();\n            this._snapshotBegun = false;\n        }\n    }\n\n    /** Destroys this Viewer.\n     */\n    destroy() {\n        const plugins = this._plugins.slice(); // Array will modify as we delete plugins\n        for (let i = 0, len = plugins.length; i < len; i++) {\n            const plugin = plugins[i];\n            plugin.destroy();\n        }\n        this.scene.destroy();\n    }\n}\n\n/**\n * @param {Component} scene \n * @param {*} [cfg]  Texture configuration\n * @param {String[]} [cfg.src=null] Path to 6 images\n * @param {Number} [cfg.encoding=LinearEncoding] Texture encoding format.  See the {@link Texture#encoding} property for more info.\n */\n\nasync function createCombinedTexture(scene, cfg) {\n    if(!cfg.src || !Array.isArray(cfg.src) || cfg.src.length !== 6)\n        throw new Error(\"src requires path to 6 images\");\n    const [\n        posX,\n        negX,\n        posY,\n        negY,\n        posZ,\n        negZ\n    ] = cfg.src;\n\n    if (!posX || !negX || !posY || !negY || !posZ || !negZ) {\n        throw new Error(\"All six images must be provided\");\n    }\n\n    const canvas = document.createElement('canvas');\n    const ctx = canvas.getContext('2d');\n\n    const loadImage = src => {\n        return new Promise((resolve, reject) => {\n            const img = new Image();\n            img.crossOrigin = \"anonymous\";\n            img.onload = () => resolve(img);\n            img.onerror = () => reject(new Error(`Failed to load image: ${src}`));\n            img.src = src;\n        });\n    };\n\n    try {\n        const [imgPosX, imgNegX, imgPosY, imgNegY, imgPosZ, imgNegZ] = await Promise.all([\n            loadImage(posX),\n            loadImage(negX),\n            loadImage(posY),\n            loadImage(negY),\n            loadImage(posZ),\n            loadImage(negZ)\n        ]);\n\n        const imageSize = imgPosX.width;\n        if (\n            imgNegX.width !== imageSize || imgPosY.width !== imageSize ||\n            imgNegY.width !== imageSize || imgPosZ.width !== imageSize ||\n            imgNegZ.width !== imageSize\n        ) {\n            throw new Error(\"All skybox textures must have the same dimensions\");\n        }\n\n        // Set canvas size for the Christ cross layout (3×4 grid)\n        canvas.width = imageSize * 4;\n        canvas.height = imageSize * 3;\n\n        ctx.fillStyle = 'black';\n        ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n        ctx.drawImage(imgNegX, imageSize * 0, imageSize * 1, imageSize, imageSize);  // -X (left)\n        ctx.drawImage(imgPosX, imageSize * 2, imageSize * 1, imageSize, imageSize);  // +X (right)\n        ctx.drawImage(imgPosY, imageSize * 1, imageSize * 0, imageSize, imageSize);  // +Y (top)\n        ctx.drawImage(imgNegY, imageSize * 1, imageSize * 2, imageSize, imageSize);  // -Y (bottom)\n        ctx.drawImage(imgPosZ, imageSize * 1, imageSize * 1, imageSize, imageSize);  // +Z (front)\n        ctx.drawImage(imgNegZ, imageSize * 3, imageSize * 1, imageSize, imageSize);  // -Z (back)\n\n        const combinedTexture = new Texture(scene, {\n            image: canvas,\n            flipY: true,\n            wrapS: ClampToEdgeWrapping,\n            wrapT: ClampToEdgeWrapping,\n            encoding: cfg.encoding || LinearEncoding\n        });\n\n        return combinedTexture;\n    } catch (error) {\n        console.error(\"Error creating combined skybox texture:\", error);\n        throw error;\n    }\n}\n\n/**\n * @param {Component} scene \n * @param {Texture} [texture] Texture to be used on the skybox mesh \n */\n\nfunction createSkyboxMesh(scene, texture) {\n\n    return new Mesh(scene, {\n\n        geometry: new ReadableGeometry(scene, { // Box-shaped geometry\n            primitive: \"triangles\",\n            positions: [\n                1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // v0-v1-v2-v3 front\n                1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, // v0-v3-v4-v5 right\n                1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, // v0-v5-v6-v1 top\n                -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // v1-v6-v7-v2 left\n                -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, // v7-v4-v3-v2 bottom\n                1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1 // v4-v7-v6-v5 back\n            ],\n            uv: [\n                0.5, 0.6666, 0.25, 0.6666, 0.25, 0.3333, 0.5, 0.3333, 0.5, 0.6666, 0.5, 0.3333, 0.75, 0.3333, 0.75, 0.6666,\n                0.5, 0.6666, 0.5, 1, 0.25, 1, 0.25, 0.6666, 0.25, 0.6666, 0.0, 0.6666, 0.0, 0.3333, 0.25, 0.3333,\n                0.25, 0, 0.50, 0, 0.50, 0.3333, 0.25, 0.3333, 0.75, 0.3333, 1.0, 0.3333, 1.0, 0.6666, 0.75, 0.6666\n            ],\n            indices: [\n                0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11,\n                12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23\n            ]\n        }),\n        background: true,\n        scale: [1000, 1000, 1000],\n        rotation: [0, -90, 0],\n        material: new PhongMaterial(scene, {\n            ambient: [0, 0, 0],\n            diffuse: [0, 0, 0],\n            specular: [0, 0, 0],\n            emissive: [1, 1, 1],\n            emissiveMap: texture,\n            backfaces: true // Show interior faces of our skybox geometry\n        }),\n        visible: true,\n        pickable: false,\n        clippable: false,\n        collidable: false\n    });\n}\n\n/**\n *\n * @param {*} scene\n * @param {Texture} [texture] Texture to be used on the material for SphereMap\n * @returns {Mesh}\n */\n\nfunction createSphereMapMesh(scene, texture) {\n    const sphereMapGeometry = new ReadableGeometry(scene, buildSphereGeometry({\n        center: [0, 0, 0],\n        radius: 1,\n        heightSegments: 60,\n        widthSegments: 60\n    }));\n\n    const sphereMapMaterial = new PhongMaterial(scene, {\n        ambient: [0, 0, 0],\n        diffuse: [0, 0, 0],\n        specular: [0, 0, 0],\n        emissive: [1, 1, 1],\n        emissiveMap: texture,\n        backfaces: true\n    });\n\n    return new Mesh(scene, {\n        geometry: sphereMapGeometry,\n        background: true,\n        rotation: [0, 0, 180],\n        material: sphereMapMaterial,\n        visible: true,\n        pickable: false,\n        clippable: false,\n        collidable: false\n    });\n}\n\nconst tmpVec3a$1 = math.vec3();\nconst tmpVec3b$1 = math.vec3();\n\n/**\n * @desc Measures the angle indicated by three 3D points.\n *\n * See {@link AngleMeasurementsPlugin} for more info.\n */\nclass AngleMeasurement extends Component {\n\n    /**\n     * @private\n     */\n    constructor(plugin, cfg = {}) {\n\n        const scene = plugin.viewer.scene;\n\n        super(scene, cfg);\n\n        /**\n         * The {@link AngleMeasurementsPlugin} that owns this AngleMeasurement.\n         * @type {AngleMeasurementsPlugin}\n         */\n        this.plugin = plugin;\n\n        const container = cfg.container;\n        if (!container) {\n            throw \"config missing: container\";\n        }\n\n        this._color = cfg.color || plugin.defaultColor;\n\n        const channel = function(v) {\n            const listeners = [ ];\n            let value = v !== false;\n            return {\n                reg: (l) => listeners.push(l),\n                get: () => value,\n                set: (v) => {\n                    value = v !== false;\n                    listeners.forEach(l => l(value));\n                }\n            };\n        };\n\n        this._visible           = channel(cfg.visible);\n        this._originVisible     = channel(cfg.originVisible);\n        this._cornerVisible     = channel(cfg.cornerVisible);\n        this._targetVisible     = channel(cfg.targetVisible);\n        this._originWireVisible = channel(cfg.originWireVisible);\n        this._targetWireVisible = channel(cfg.targetWireVisible);\n        this._angleVisible      = channel(cfg.angleVisible);\n        this._labelsVisible     = channel();\n        this.labelsVisible      = cfg.labelsVisible;\n        this._clickable         = channel(false);\n\n        this.approximate = cfg.approximate;\n\n        this._labelStringFormat = (angle) => {\n            return (this._approximate ? \" ~ \" : \" = \") + angle.toFixed(2) + \"°\";\n        };\n\n        const canvas = scene.canvas.canvas;\n\n        const onMouseOver = cfg.onMouseOver ? (event) => {\n            cfg.onMouseOver(event, this);\n            canvas.dispatchEvent(new MouseEvent('mouseover', event));\n        } : null;\n\n        const onMouseLeave = cfg.onMouseLeave ? (event) => {\n            cfg.onMouseLeave(event, this);\n            canvas.dispatchEvent(new MouseEvent('mouseleave', event));\n        } : null;\n\n        const onContextMenu = cfg.onContextMenu ? (event) => {\n            cfg.onContextMenu(event, this);\n        } : null;\n\n        const onMouseDown  = (event) => canvas.dispatchEvent(new MouseEvent('mousedown', event));\n        const onMouseUp    = (event) => canvas.dispatchEvent(new MouseEvent('mouseup', event));\n        const onMouseMove  = (event) => canvas.dispatchEvent(new MouseEvent('mousemove', event));\n        const onMouseWheel = (event) => canvas.dispatchEvent(new WheelEvent('wheel', event));\n\n\n        this._cleanups = [ ];\n        this._drawables = [ ];\n\n        const registerDrawable = (drawable, visibilityChannels) => {\n            const updateVisibility = () => drawable.setVisible(visibilityChannels.every(ch => ch.get()));\n            visibilityChannels.forEach(ch => ch.reg(updateVisibility));\n            this._drawables.push(drawable);\n            this._cleanups.push(() => drawable.destroy());\n        };\n\n        const makeWire = (color, thickness, visibilityChannels) => {\n            const wire = new Wire3D(scene, container, {\n                color: color,\n                thickness: thickness,\n                thicknessClickable: 6,\n                zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1 : undefined,\n                onMouseOver,\n                onMouseLeave,\n                onMouseWheel,\n                onMouseDown,\n                onMouseUp,\n                onMouseMove,\n                onContextMenu\n            });\n            registerDrawable(wire, visibilityChannels);\n            return {\n                setEnds: (p0, p1) => wire.setEnds(p0, p1),\n                setColor: value => wire.setColor(value)\n            };\n        };\n        this._originWire = makeWire(this._color || \"blue\", 1, [ this._visible, this._originWireVisible ]);\n        this._targetWire = makeWire(this._color || \"red\",  1, [ this._visible, this._targetWireVisible ]);\n\n        const makeLabel = (color, zIndexOffset, visibilityChannels) => {\n            const label = new Label3D(scene, container, {\n                fillColor: color,\n                zIndex: plugin.zIndex + zIndexOffset,\n                onMouseOver,\n                onMouseLeave,\n                onMouseWheel,\n                onMouseDown,\n                onMouseUp,\n                onMouseMove,\n                onContextMenu\n            });\n            registerDrawable(label, visibilityChannels);\n            return {\n                setFillColor:  value => label.setFillColor(value),\n                setPosOnWire:  (p0, p1, offset) => label.setPosOnWire(p0, p1, offset),\n                setPosBetween: (p0, p1, p2) => label.setPosBetween(p0, p1, p2),\n                setText:       str => label.setText(str)\n            };\n        };\n        this._angleLabel = makeLabel(this._color || \"#00BBFF\", 2, [ this._visible, this._angleVisible, this._labelsVisible ]);\n\n        const makeDot = (cfg, visibilityChannels) => {\n            const dot = new Dot3D(scene, cfg, container, {\n                fillColor: this._color,\n                zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 2 : undefined,\n                onMouseOver,\n                onMouseLeave,\n                onMouseWheel,\n                onMouseDown,\n                onMouseUp,\n                onMouseMove,\n                onContextMenu\n            });\n            dot.on(\"worldPos\", () => this._update());\n            registerDrawable(dot, visibilityChannels);\n            return dot;\n        };\n        this._originDot = makeDot(cfg.origin, [ this._visible, this._originVisible ]);\n        this._cornerDot = makeDot(cfg.corner, [ this._visible, this._cornerVisible ]);\n        this._targetDot = makeDot(cfg.target, [ this._visible, this._targetVisible ]);\n\n        this._update();\n    }\n\n    _update() {\n        if (! this._targetDot) {\n            return;\n        }\n\n        const p0 = this._originDot.worldPos;\n        const p1 = this._cornerDot.worldPos;\n        const p2 = this._targetDot.worldPos;\n\n        this._originWire.setEnds(p0, p1);\n        this._targetWire.setEnds(p1, p2);\n        this._angleLabel.setPosBetween(p0, p1, p2);\n\n        math.subVec3(p0, p1, tmpVec3a$1);\n        math.subVec3(p2, p1, tmpVec3b$1);\n\n        if ((math.lenVec3(tmpVec3a$1) > 0) && (math.lenVec3(tmpVec3b$1) > 0)) {\n            math.normalizeVec3(tmpVec3a$1);\n            math.normalizeVec3(tmpVec3b$1);\n            this._angle = Math.abs(math.angleVec3(tmpVec3a$1, tmpVec3b$1)) * math.RADTODEG;\n            this._angleLabel.setText(this._labelStringFormat(this._angle));\n        } else {\n            this._angle = undefined;\n            this._angleLabel.setText(\"\");\n        }\n    }\n\n    /**\n     * Sets whether this AngleMeasurement indicates that its measurement is approximate.\n     *\n     * This is ````true```` by default.\n     *\n     * @type {Boolean}\n     */\n    set approximate(approximate) {\n        approximate = approximate !== false;\n        if (this._approximate === approximate) {\n            return;\n        }\n        this._approximate = approximate;\n        this._update();\n    }\n\n    /**\n     * Gets whether this AngleMeasurement indicates that its measurement is approximate.\n     *\n     * This is ````true```` by default.\n     *\n     * @type {Boolean}\n     */\n    get approximate() {\n        return this._approximate;\n    }\n\n    /**\n     * Gets the origin {@link Dot3D}.\n     *\n     * @type {Dot3D}\n     */\n    get origin() {\n        return this._originDot;\n    }\n\n    /**\n     * Gets the corner {@link Dot3D}.\n     *\n     * @type {Dot3D}\n     */\n    get corner() {\n        return this._cornerDot;\n    }\n\n    /**\n     * Gets the target {@link Dot3D}.\n     *\n     * @type {Dot3D}\n     */\n    get target() {\n        return this._targetDot;\n    }\n\n    /**\n     * Gets the angle between two connected 3D line segments, given\n     * as three positions on the surface(s) of one or more {@link Entity}s.\n     *\n     * @type {Number}\n     */\n    get angle() {\n        return this._angle;\n    }\n\n    /**\n     * Gets the color of the angle measurement.\n     *\n     * The color is an HTML string representation, eg. \"#00BBFF\" and \"blue\".\n     *\n     * @type {String}\n     */\n    get color() {\n        return this._color;\n    }\n\n    /** Sets the color of the angle measurement.\n     *\n     * The color is given as an HTML string representation, eg. \"#00BBFF\" and \"blue\".\n     *\n     * @type {String}\n     */\n    set color(value) {\n        this._color = value;\n        this._originDot.setFillColor(value);\n        this._cornerDot.setFillColor(value);\n        this._targetDot.setFillColor(value);\n        this._originWire.setColor(value || \"blue\");\n        this._targetWire.setColor(value || \"red\");\n        this._angleLabel.setFillColor(value || \"#00BBFF\");\n    }\n\n    /**\n     * Sets whether this AngleMeasurement is visible or not.\n     *\n     * @type {Boolean}\n     */\n    set visible(value) {\n        this._visible.set(value);\n    }\n\n    /**\n     * Gets whether this AngleMeasurement is visible or not.\n     *\n     * @type {Boolean}\n     */\n    get visible() {\n        return this._visible.get();\n    }\n\n    /**\n     * Sets if the origin {@link Dot3D} is visible.\n     *\n     * @type {Boolean}\n     */\n    set originVisible(value) {\n        this._originVisible.set(value);\n    }\n\n    /**\n     * Gets if the origin {@link Dot3D} is visible.\n     *\n     * @type {Boolean}\n     */\n    get originVisible() {\n        return this._originVisible.get();\n    }\n\n    /**\n     * Sets if the corner {@link Dot3D} is visible.\n     *\n     * @type {Boolean}\n     */\n    set cornerVisible(value) {\n        this._cornerVisible.set(value);\n    }\n\n    /**\n     * Gets if the corner {@link Dot3D} is visible.\n     *\n     * @type {Boolean}\n     */\n    get cornerVisible() {\n        return this._cornerVisible.get();\n    }\n\n    /**\n     * Sets if the target {@link Dot3D} is visible.\n     *\n     * @type {Boolean}\n     */\n    set targetVisible(value) {\n        this._targetVisible.set(value);\n    }\n\n    /**\n     * Gets if the target {@link Dot3D} is visible.\n     *\n     * @type {Boolean}\n     */\n    get targetVisible() {\n        return this._targetVisible.get();\n    }\n\n    /**\n     * Sets if the wire between the origin and the corner is visible.\n     *\n     * @type {Boolean}\n     */\n    set originWireVisible(value) {\n        this._originWireVisible.set(value);\n    }\n\n    /**\n     * Gets if the wire between the origin and the corner is visible.\n     *\n     * @type {Boolean}\n     */\n    get originWireVisible() {\n        return this._originWireVisible.get();\n    }\n\n    /**\n     * Sets if the wire between the target and the corner is visible.\n     *\n     * @type {Boolean}\n     */\n    set targetWireVisible(value) {\n        this._targetWireVisible.set(value);\n    }\n\n    /**\n     * Gets if the wire between the target and the corner is visible.\n     *\n     * @type {Boolean}\n     */\n    get targetWireVisible() {\n        return this._targetWireVisible.get();\n    }\n\n    /**\n     * Sets if the angle label is visible.\n     *\n     * @type {Boolean}\n     */\n    set angleVisible(value) {\n        this._angleVisible.set(value);\n    }\n\n    /**\n     * Gets if the angle label is visible.\n     *\n     * @type {Boolean}\n     */\n    get angleVisible() {\n        return this._angleVisible.get();\n    }\n\n    /**\n     * Sets if the labels are visible.\n     *\n     * @type {Boolean}\n     */\n    set labelsVisible(value) {\n        this._labelsVisible.set(value !== undefined ? Boolean(value) : this.plugin.defaultLabelsVisible);\n    }\n\n    /**\n     * Gets if the labels are visible.\n     *\n     * @type {Boolean}\n     */\n    get labelsVisible() {\n        return this._labelsVisible.get();\n    }\n\n    /**\n     * Sets if this DistanceMeasurement appears highlighted.\n     * @param highlighted\n     */\n    setHighlighted(highlighted) {\n        this._drawables.forEach(d => d.setHighlighted(highlighted));\n    }\n\n    /**\n     * Sets if the wires, dots ad labels will fire \"mouseOver\" \"mouseLeave\" and \"contextMenu\" events.\n     *\n     * @type {Boolean}\n     */\n    set clickable(value) {\n        this._clickable.set(!!value);\n        this._drawables.forEach(d => d.setClickable(this._clickable.get()));\n    }\n\n    /**\n     * Gets the function that formats the angle label's text.\n     *\n     * By default, this function formats the angle with two decimal places.\n     */\n    get labelStringFormat() {\n        return this._labelStringFormat;\n    }\n\n    /** \n     * Sets the function that formats the angle label's text.\n     */\n    set labelStringFormat(value) {\n        this._labelStringFormat = value;\n        this._update();\n    }\n\n    /**\n     * Gets if the wires, dots ad labels will fire \"mouseOver\" \"mouseLeave\" and \"contextMenu\" events.\n     *\n     * @type {Boolean}\n     */\n    get clickable() {\n        return this._clickable.get();\n    }\n\n    /**\n     * @private\n     */\n    destroy() {\n        this._cleanups.forEach(cleanup => cleanup());\n        super.destroy();\n    }\n}\n\n/**\n * Creates {@link AngleMeasurement}s in an {@link AngleMeasurementsPlugin} from user input.\n *\n * @interface\n * @abstract\n */\nclass AngleMeasurementsControl extends Component {\n\n    /**\n     * Gets if this AngleMeasurementsControl is currently active, where it is responding to input.\n     *\n     * @returns {boolean} True if this AngleMeassurementsControl is active.\n     * @abstract\n     */\n    get active() {\n    }\n\n    /**\n     * Sets whether snap-to-vertex and snap-to-edge are enabled for this AngleMeasurementsControl.\n     *\n     * This is `true` by default.\n     *\n     * Internally, this deactivates then activates the AngleMeasurementsControl when changed, which means that\n     * it will destroy any AngleMeasurements currently under construction, and incurs some overhead, since it unbinds\n     * and rebinds various input handlers.\n     *\n     * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this AngleMeasurementsControl.\n     */\n    set snapping(snapping) {\n    }\n\n    /**\n     * Gets whether snap-to-vertex and snap-to-edge are enabled for this AngleMeasurementsControl.\n     *\n     * This is `true` by default.\n     *\n     * @returns {boolean} Whether snap-to-vertex and snap-to-edge are enabled for this AngleMeasurementsControl.\n     */\n    get snapping() {\n        return true;\n    }\n\n    /**\n     * Activates this AngleMeasurementsMouseControl, ready to respond to input.\n     *\n     * @abstract\n     */\n    activate() {\n    }\n\n    /**\n     * Deactivates this AngleMeasurementsControl, making it unresponsive to input.\n     *\n     * Destroys any {@link AngleMeasurement} under construction by this AngleMeasurementsControl.\n     *\n     * @abstract\n     */\n    deactivate() {\n    }\n\n    /**\n     * Resets this AngleMeasurementsControl.\n     *\n     * Destroys any {@link AngleMeasurement} under construction by this AngleMeasurementsControl.\n     *\n     * Does nothing if the AngleMeasurementsControl is not active.\n     *\n     * @abstract\n     */\n    reset() {\n    }\n\n    /**\n     * Gets the {@link AngleMeasurement} under construction by this AngleMeasurementsControl, if any.\n     *\n     * @returns {null|AngleMeasurement}\n     * @abstract\n     */\n    get currentMeasurement() {\n        return null;\n    }\n\n    /**\n     * Destroys this AngleMeasurementsMouseControl.\n     *\n     * Destroys any {@link AngleMeasurement} under construction by this AngleMeasurementsControl.\n     *\n     * @abstract\n     */\n    destroy() {\n    }\n}\n\nconst MOUSE_FINDING_ORIGIN = 0;\nconst MOUSE_FINDING_CORNER = 1;\nconst MOUSE_FINDING_TARGET = 2;\n\n/**\n * Creates {@link AngleMeasurement}s in an {@link AngleMeasurementsPlugin} from mouse input.\n *\n * ## Usage\n *\n * [[Run example](/examples/measurement/#angle_createWithMouse_snapping)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, AngleMeasurementsPlugin, AngleMeasurementsMouseControl, PointerLens} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n * });\n *\n * viewer.camera.eye = [-3.93, 2.85, 27.01];\n * viewer.camera.look = [4.40, 3.72, 8.89];\n * viewer.camera.up = [-0.01, 0.99, 0.039];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const sceneModel = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"Duplex.xkt\"\n * });\n *\n * const angleMeasurements = new AngleMeasurementsPlugin(viewer);\n *\n * const angleMeasurementsMouseControl  = new AngleMeasurementsMouseControl(angleMeasurements, {\n *     pointerLens : new PointerLens(viewer)\n * })\n *\n * angleMeasurementsMouseControl.snapping = true;\n *\n * angleMeasurementsMouseControl.activate();\n * ````\n */\nclass AngleMeasurementsMouseControl extends AngleMeasurementsControl {\n\n    /**\n     * Creates a AngleMeasurementsMouseControl bound to the given AngleMeasurementsPlugin.\n     *\n     * @param {AngleMeasurementsPlugin} angleMeasurementsPlugin The AngleMeasurementsPlugin to control.\n     * @param {*} [cfg] Configuration\n     * @param {function} [cfg.canvasToPagePos] Optional function to map canvas-space coordinates to page coordinates.\n     * @param {PointerLens} [cfg.pointerLens] A PointerLens to use to provide a magnified view of the cursor when snapping is enabled.\n     * @param {boolean} [cfg.snapping=true] Whether to initially enable snap-to-vertex and snap-to-edge for this AngleMeasurementsMouseControl.\n     */\n    constructor(angleMeasurementsPlugin, cfg = {}) {\n\n        super(angleMeasurementsPlugin.viewer.scene);\n\n        this._canvasToPagePos = cfg.canvasToPagePos;\n\n        this.pointerLens = cfg.pointerLens;\n\n        this._active = false;\n\n        this._currentAngleMeasurement = null;\n\n        this._initMarkerDiv();\n\n        this._snapping = cfg.snapping !== false;\n        this._mouseState = MOUSE_FINDING_ORIGIN;\n\n        this._attachPlugin(angleMeasurementsPlugin, cfg);\n    }\n\n    _initMarkerDiv() {\n        const markerDiv = document.createElement('div');\n        const canvas = this.scene.canvas.canvas;\n        canvas.parentNode.insertBefore(markerDiv, canvas);\n\n        markerDiv.style.background = \"black\";\n        markerDiv.style.border = \"2px solid blue\";\n        markerDiv.style.borderRadius = \"10px\";\n        markerDiv.style.width = \"5px\";\n        markerDiv.style.height = \"5px\";\n        markerDiv.style.top = \"-200px\";\n        markerDiv.style.left = \"-200px\";\n        markerDiv.style.margin = \"0 0\";\n        markerDiv.style.zIndex = \"100\";\n        markerDiv.style.position = \"absolute\";\n        markerDiv.style.pointerEvents = \"none\";\n\n        this.markerDiv = markerDiv;\n    }\n\n    _destroyMarkerDiv() {\n        if (this.markerDiv) {\n            this.markerDiv.parentNode.removeChild(this.markerDiv);\n            this.markerDiv = null;\n        }\n    }\n\n    _attachPlugin(angleMeasurementsPlugin, cfg = {}) {\n\n        /**\n         * The {@link AngleMeasurementsPlugin} that owns this AngleMeasurementsMouseControl.\n         *\n         * @type {AngleMeasurementsPlugin}\n         */\n        this.angleMeasurementsPlugin = angleMeasurementsPlugin;\n\n        /**\n         * The {@link AngleMeasurementsPlugin} that owns this AngleMeasurementsMouseControl.\n         *\n         * @type {AngleMeasurementsPlugin}\n         */\n        this.plugin = angleMeasurementsPlugin;\n    }\n\n    /**\n     * Gets if this AngleMeasurementsMouseControl is currently active, where it is responding to input.\n     *\n     * @returns {boolean}\n     */\n    get active() {\n        return this._active;\n    }\n\n    /**\n     * Sets whether snap-to-vertex and snap-to-edge are enabled for this AngleMeasurementsMouseControl.\n     *\n     * This is `true` by default.\n     *\n     * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this AngleMeasurementsMouseControl.\n     */\n    set snapping(snapping) {\n        this._snapping = snapping;\n    }\n\n    /**\n     * Gets whether snap-to-vertex and snap-to-edge are enabled for this AngleMeasurementsMouseControl.\n     *\n     * This is `true` by default.\n     *\n     * @returns {boolean} Whether snap-to-vertex and snap-to-edge are enabled for this AngleMeasurementsMouseControl.\n     */\n    get snapping() {\n        return this._snapping;\n    }\n\n    /**\n     * Activates this AngleMeasurementsMouseControl, ready to respond to input.\n     */\n    activate() {\n        if (this._active) {\n            return;\n        }\n        if (!this.markerDiv) {\n            this._initMarkerDiv(); // if the marker is destroyed after deactivation, we recreate it\n        }\n        this.angleMeasurementsPlugin;\n        const scene = this.scene;\n        scene.input;\n        const canvas = scene.canvas.canvas;\n        const clickTolerance = 20;\n        const cameraControl = this.angleMeasurementsPlugin.viewer.cameraControl;\n        const pointerLens = this.pointerLens;\n        let mouseHovering = false;\n        let hoveredEntity = null;\n        let lastMouseCanvasX = 0;\n        let lastMouseCanvasY = 0;\n        const mouseWorldPos = math.vec3();\n        const mouseHoverCanvasPos = math.vec2();\n        this._currentAngleMeasurement = null;\n\n        const pagePos = math.vec2();\n\n        const hoverOn = event => {\n                if (event.snappedToVertex || event.snappedToEdge) {\n                    if (pointerLens) {\n                        pointerLens.visible = true;\n                        pointerLens.canvasPos = event.canvasPos;\n                        pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;\n                        pointerLens.snapped = true;\n                    }\n                    this.markerDiv.style.background = \"greenyellow\";\n                    this.markerDiv.style.border = \"2px solid green\";\n                } else {\n                    if (pointerLens) {\n                        pointerLens.visible = true;\n                        pointerLens.canvasPos =  event.canvasPos;\n                        pointerLens.snappedCanvasPos = event.canvasPos;\n                        pointerLens.snapped = false;\n                    }\n                    this.markerDiv.style.background = \"pink\";\n                    this.markerDiv.style.border = \"2px solid red\";\n                }\n                const canvasPos = event.snappedCanvasPos || event.canvasPos;\n                mouseHovering = true;\n                hoveredEntity = event.entity;\n                mouseWorldPos.set(event.worldPos);\n                mouseHoverCanvasPos.set(canvasPos);\n                switch (this._mouseState) {\n                    case MOUSE_FINDING_ORIGIN:\n                        if (this._canvasToPagePos) {\n                            this._canvasToPagePos(canvas, canvasPos, pagePos);\n                            this.markerDiv.style.left = `${pagePos[0] - 5}px`;\n                            this.markerDiv.style.top = `${pagePos[1] - 5}px`;\n                        } else {\n                            const markerPos = math.vec2(canvasPos);\n                            transformToNode(canvas, this.markerDiv.parentNode, markerPos);\n                            this.markerDiv.style.left = `${markerPos[0] - 5}px`;\n                            this.markerDiv.style.top = `${markerPos[1] - 5}px`;\n                        }\n                        break;\n                    case MOUSE_FINDING_CORNER:\n                        if (this._currentAngleMeasurement) {\n                            this._currentAngleMeasurement.originWireVisible = true;\n                            this._currentAngleMeasurement.targetWireVisible = false;\n                            this._currentAngleMeasurement.cornerVisible = true;\n                            this._currentAngleMeasurement.angleVisible = false;\n                            this._currentAngleMeasurement.corner.worldPos = event.worldPos;\n                            this._currentAngleMeasurement.corner.entity = event.entity;\n                        }\n                        this.markerDiv.style.left = `-10000px`;\n                        this.markerDiv.style.top = `-10000px`;\n                        canvas.style.cursor = \"pointer\";\n                        break;\n                    case MOUSE_FINDING_TARGET:\n                        if (this._currentAngleMeasurement) {\n                            this._currentAngleMeasurement.targetWireVisible = true;\n                            this._currentAngleMeasurement.targetVisible = true;\n                            this._currentAngleMeasurement.angleVisible = true;\n                            this._currentAngleMeasurement.target.worldPos = event.worldPos;\n                            this._currentAngleMeasurement.target.entity = event.entity;\n                        }\n                        this.markerDiv.style.left = `-10000px`;\n                        this.markerDiv.style.top = `-10000px`;\n                        canvas.style.cursor = \"pointer\";\n                        break;\n                }\n        };\n        this._onHoverSnapOrSurface = cameraControl.on(\"hoverSnapOrSurface\", e => { if (this._snapping)   hoverOn(e); });\n        this._onHoverSurface       = cameraControl.on(\"hoverSurface\",       e => { if (! this._snapping) hoverOn(e); });\n\n        canvas.addEventListener('mousedown', this._onMouseDown = (e) => {\n            if (e.which !== 1) {\n                return;\n            }\n            lastMouseCanvasX = e.clientX;\n            lastMouseCanvasY = e.clientY;\n        });\n        canvas.addEventListener(\"mouseup\", this._onMouseUp =(e) => {\n            if (e.which !== 1) {\n                return;\n            }\n            if (e.clientX > lastMouseCanvasX + clickTolerance ||\n                e.clientX < lastMouseCanvasX - clickTolerance ||\n                e.clientY > lastMouseCanvasY + clickTolerance ||\n                e.clientY < lastMouseCanvasY - clickTolerance) {\n                return;\n            }\n            switch (this._mouseState) {\n                case MOUSE_FINDING_ORIGIN:\n                    if (mouseHovering) {\n                        this._currentAngleMeasurement = this.angleMeasurementsPlugin.createMeasurement({\n                            id: math.createUUID(),\n                            origin: {\n                                worldPos: mouseWorldPos,\n                                entity: hoveredEntity\n                            },\n                            corner: {\n                                worldPos: mouseWorldPos,\n                                entity: hoveredEntity\n                            },\n                            target: {\n                                worldPos: mouseWorldPos,\n                                entity: hoveredEntity\n                            },\n                            approximate: true\n                        });\n                        this._currentAngleMeasurement.clickable = false;\n                        this._currentAngleMeasurement.originVisible = true;\n                        this._currentAngleMeasurement.originWireVisible = true;\n                        this._currentAngleMeasurement.cornerVisible = false;\n                        this._currentAngleMeasurement.targetWireVisible = false;\n                        this._currentAngleMeasurement.targetVisible = false;\n                        this._currentAngleMeasurement.angleVisible = false;\n                        this._currentAngleMeasurement.origin.entity = hoveredEntity;\n                        this._mouseState = MOUSE_FINDING_CORNER;\n                        this.angleMeasurementsPlugin.fire(\"measurementStart\", this._currentAngleMeasurement);\n                    }\n                    break;\n                case MOUSE_FINDING_CORNER:\n                    if (mouseHovering) {\n                        this._currentAngleMeasurement.targetWireVisible = false;\n                        this._currentAngleMeasurement.targetVisible = true;\n                        this._currentAngleMeasurement.angleVisible = true;\n                        this._currentAngleMeasurement.corner.entity = hoveredEntity;\n                        this._mouseState = MOUSE_FINDING_TARGET;\n                    } else {\n                        if (this._currentAngleMeasurement) {\n                            this._currentAngleMeasurement.destroy();\n                            this._currentAngleMeasurement = null;\n                            hoveredEntity = null;\n                            this._mouseState = MOUSE_FINDING_ORIGIN;\n                            this.angleMeasurementsPlugin.fire(\"measurementCancel\", this._currentAngleMeasurement);\n                        }\n                    }\n                    break;\n                case MOUSE_FINDING_TARGET:\n                    if (mouseHovering) {\n                        this._currentAngleMeasurement.targetVisible = true;\n                        this._currentAngleMeasurement.angleVisible = true;\n                        this._currentAngleMeasurement.target.entity = hoveredEntity;\n                        this._currentAngleMeasurement.clickable = true;\n                        hoveredEntity = null;\n                        this.angleMeasurementsPlugin.fire(\"measurementEnd\", this._currentAngleMeasurement);\n                        this._currentAngleMeasurement = null;\n                        this._mouseState = MOUSE_FINDING_ORIGIN;\n                    } else {\n                        if (this._currentAngleMeasurement) {\n                            this._currentAngleMeasurement.destroy();\n                            this._currentAngleMeasurement = null;\n                            hoveredEntity = null;\n                            this._mouseState = MOUSE_FINDING_ORIGIN;\n                            this.angleMeasurementsPlugin.fire(\"measurementCancel\", this._currentAngleMeasurement);\n                        }\n                    }\n                    break;\n            }\n        });\n\n        const hoverOff = event => {\n                mouseHovering = false;\n                if (pointerLens) {\n                    pointerLens.visible = true;\n                    pointerLens.canvasPos = event.canvasPos;\n                    pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;\n                    pointerLens.snapped = false;\n                }\n                this.markerDiv.style.left = `-100px`;\n                this.markerDiv.style.top = `-100px`;\n                if (this._currentAngleMeasurement) {\n                    switch (this._mouseState) {\n                        case MOUSE_FINDING_ORIGIN:\n                            this._currentAngleMeasurement.originVisible = false;\n                            break;\n                        case MOUSE_FINDING_CORNER:\n                            this._currentAngleMeasurement.cornerVisible = false;\n                            this._currentAngleMeasurement.originWireVisible = false;\n                            this._currentAngleMeasurement.targetVisible = false;\n                            this._currentAngleMeasurement.targetWireVisible = false;\n                            this._currentAngleMeasurement.angleVisible = false;\n                            break;\n                        case MOUSE_FINDING_TARGET:\n                            this._currentAngleMeasurement.targetVisible = false;\n                            this._currentAngleMeasurement.targetWireVisible = false;\n                            this._currentAngleMeasurement.angleVisible = false;\n                            break;\n                    }\n                    canvas.style.cursor = \"default\";\n                }\n        };\n        this._onHoverSnapOrSurfaceOff = cameraControl.on(\"hoverSnapOrSurfaceOff\", e => { if (this._snapping)   hoverOff(e); });\n        this._onHoverOff              = cameraControl.on(\"hoverOff\",              e => { if (! this._snapping) hoverOff(e); });\n\n        this._active = true;\n    }\n\n    /**\n     * Deactivates this AngleMeasurementsMouseControl, making it unresponsive to input.\n     *\n     * Destroys any {@link AngleMeasurement} under construction by this AngleMeasurementsMouseControl.\n     */\n    deactivate() {\n        if (!this._active) {\n            return;\n        }\n\n        if (this.pointerLens) {\n            this.pointerLens.visible = false;\n        }\n\n        this.reset();\n\n        const canvas = this.scene.canvas.canvas;\n        canvas.removeEventListener(\"mousedown\", this._onMouseDown);\n        canvas.removeEventListener(\"mouseup\", this._onMouseUp);\n        const cameraControl = this.angleMeasurementsPlugin.viewer.cameraControl;\n        cameraControl.off(this._onHoverSnapOrSurface);\n        cameraControl.off(this._onHoverSurface);\n        cameraControl.off(this._onHoverSnapOrSurfaceOff);\n        cameraControl.off(this._onHoverOff);\n\n        this._active = false;\n    }\n\n    /**\n     * Resets this AngleMeasurementsMouseControl.\n     *\n     * Destroys any {@link AngleMeasurement} under construction by this AngleMeasurementsMouseControl.\n     *\n     * Does nothing if the AngleMeasurementsMouseControl is not active.\n     */\n    reset() {\n        if (!this._active) {\n            return;\n        }\n\n        this._destroyMarkerDiv();\n        this._initMarkerDiv();\n\n        if (this._currentAngleMeasurement) {\n            this._currentAngleMeasurement.destroy();\n            this._currentAngleMeasurement = null;\n        }\n\n        this._mouseState = MOUSE_FINDING_ORIGIN;\n    }\n\n    /**\n     * Gets the {@link AngleMeasurement} under construction by this AngleMeasurementsMouseControl, if any.\n     *\n     * @returns {null|AngleMeasurement}\n     */\n    get currentMeasurement() {\n        return this._currentAngleMeasurement;\n    }\n\n    /**\n     * Destroys this AngleMeasurementsMouseControl.\n     */\n    destroy() {\n        this.deactivate();\n        super.destroy();\n    }\n}\n\n/**\n * {@link Viewer} plugin for measuring angles.\n *\n * [<img src=\"https://user-images.githubusercontent.com/83100/63641903-61488180-c6b6-11e9-8e00-895b9d16dc4b.gif\">](https://xeokit.github.io/xeokit-sdk/examples/index.html#measurements_angle_createWithMouse)\n *\n * * [[Example 1: Model with angle measurements](https://xeokit.github.io/xeokit-sdk/examples/index.html#measurements_angle_modelWithMeasurements)]\n * * [[Example 2: Create angle measurements with mouse](https://xeokit.github.io/xeokit-sdk/examples/measurement/#angle_createWithMouse_snapping)]\n *\n * ## Overview\n *\n * * An {@link AngleMeasurement} shows the angle between two connected 3D line segments, given\n * as three positions on the surface(s) of one or more {@link Entity}s.\n * * As shown on the screen capture above, a AngleMeasurement has two wires that show the line segments, with a label that shows the angle between them.\n * * Create AngleMeasurements programmatically with {@link AngleMeasurementsPlugin#createMeasurement}.\n * * Create AngleMeasurements interactively using a {@link AngleMeasurementsControl}.\n * * Existing AngleMeasurements are registered by ID in {@link AngleMeasurementsPlugin#measurements}.\n * * Destroy AngleMeasurements using {@link AngleMeasurementsPlugin#destroyMeasurement}.\n * * Configure global measurement units and scale via {@link Metrics}, located at {@link Scene#metrics}\n *\n * ## Example 1: Creating AngleMeasurements Programmatically\n *\n * In our first example, we'll use an {@link XKTLoaderPlugin} to load a model, and then use a AngleMeasurementsPlugin to programmatically create two {@link AngleMeasurement}s.\n *\n * Note how each AngleMeasurement has ````origin````, ````corner```` and  ````target````, which each indicate a 3D World-space\n * position on the surface of an {@link Entity}. These can be aon the same Entity, or on different Entitys.\n *\n * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#measurements_angle_modelWithMeasurements)]\n *\n * ````JavaScript\n * import {Viewer, XKTLoaderPlugin, AngleMeasurementsPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-2.37, 18.97, -26.12];\n * viewer.scene.camera.look = [10.97, 5.82, -11.22];\n * viewer.scene.camera.up = [0.36, 0.83, 0.40];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const angleMeasurements = new AngleMeasurementsPlugin(viewer);\n *\n * const model = xktLoader.load({\n *      src: \"./models/xkt/duplex/duplex.xkt\"\n * });\n *\n * model.on(\"loaded\", () => {\n *\n *      const myMeasurement1 = angleMeasurements.createMeasurement({\n *          id: \"myAngleMeasurement1\",\n *          origin: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FLOH\"],\n *              worldPos: [0.044, 5.998, 17.767]\n *          },\n *          corner: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FLOH\"],\n *              worldPos: [0.044, 5.998, 17.767]\n *          },\n *          target: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FLOH\"],\n *              worldPos: [4.738, 3.172, 17.768]\n *          },\n *          visible: true\n *      });\n *\n *      const myMeasurement2 = angleMeasurements.createMeasurement({\n *          id: \"myAngleMeasurement2\",\n *          origin: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FNr2\"],\n *              worldPos: [0.457, 2.532, 17.766]\n *          },\n *          corner: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FNr2\"],\n *              worldPos: [0.457, 2.532, 17.766]\n *          },\n *          target: {\n *              entity: viewer.scene.objects[\"1CZILmCaHETO8tf3SgGEXu\"],\n *              worldPos: [0.436, 0.001, 22.135]\n *          },\n *          visible: true\n *      });\n * });\n * ````\n *\n * ## Example 2: Creating AngleMeasurements with Mouse Input\n *\n * In our second example, we'll use an {@link XKTLoaderPlugin} to load a model, then we'll use the AngleMeasurementsPlugin's {@link AngleMeasurementsTouchControl} to interactively create {@link AngleMeasurement}s with mouse or touch input.\n *\n * After we've activated the AngleMeasurementsControl, the first click on any {@link Entity} begins constructing a AngleMeasurement, fixing its\n * origin to that Entity. The next click on any Entity will fix the AngleMeasurement's corner, and the next click after\n * that will fix its target and complete the AngleMeasurement.\n *\n * The AngleMeasurementControl will then wait for the next click on any Entity, to begin constructing\n * another AngleMeasurement, and so on, until deactivated again.\n *\n * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/measurement/#angle_createWithMouse_snapping)]\n *\n * ````JavaScript\n * import {Viewer, XKTLoaderPlugin, AngleMeasurementsPlugin, AngleMeasurementsMouseControl, PointerLens} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-2.37, 18.97, -26.12];\n * viewer.scene.camera.look = [10.97, 5.82, -11.22];\n * viewer.scene.camera.up = [0.36, 0.83, 0.40];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * cconst angleMeasurementsMouseControl  = new AngleMeasurementsMouseControl(angleMeasurements, {\n *     pointerLens : new PointerLens(viewer)\n * })\n *\n * angleMeasurementsMouseControl.snapToVertex = true;\n * angleMeasurementsMouseControl.snapToEdge = true;\n *\n * angleMeasurementsMouseControl.activate();\n * ````\n *\n * ## Example 4: Attaching Mouse Handlers\n *\n * In our fourth example, we'll attach even handlers to our plugin, to catch when the user\n * hovers or right-clicks over our measurements.\n *\n * [[Run example](/examples/measurement/#angle_modelWithMeasurements)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, AngleMeasurementsPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-2.37, 18.97, -26.12];\n * viewer.scene.camera.look = [10.97, 5.82, -11.22];\n * viewer.scene.camera.up = [0.36, 0.83, 0.40];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const angleMeasurements = new AngleMeasurementsPlugin(viewer);\n *\n * angleMeasurements.on(\"mouseOver\", (e) => {\n *     e.measurement.setHighlighted(true);\n * });\n *\n * angleMeasurements.on(\"mouseLeave\", (e) => {\n *     e.measurement.setHighlighted(false);\n * });\n *\n * angleMeasurements.on(\"contextMenu\", (e) => {\n *     // Show context menu\n *     e.event.preventDefault();\n * });\n *\n * const model = xktLoader.load({\n *      src: \"./models/xkt/duplex/duplex.xkt\"\n * });\n *\n * model.on(\"loaded\", () => {\n *\n *       angleMeasurementsPlugin.createMeasurement({\n *             id: \"angleMeasurement1\",\n *             origin: {\n *                 entity: viewer.scene.objects[\"1CZILmCaHETO8tf3SgGEXu\"],\n *                 worldPos: [0.4158603637281142, 2.5193106917110457, 17.79972838299403]\n *             },\n *             corner: {\n *                 entity: viewer.scene.objects[\"1CZILmCaHETO8tf3SgGEXu\"],\n *                 worldPos: [0.41857741956197625,0.0987169929481646,17.799763071093395]\n *             },\n *             target: {\n *                 entity: viewer.scene.objects[\"1CZILmCaHETO8tf3SgGEXu\"],\n *                 worldPos: [5.235526066859247, 0.11580773869801986, 17.824891550941565]\n *             },\n *             visible: true\n *         });\n *\n *         angleMeasurementsPlugin.createMeasurement({\n *             id: \"angleMeasurement2\",\n *             origin: {\n *                 entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FNr2\"],\n *                 worldPos: [-0.00003814187850181838, 5.9996748076205115,17.79996871551525]\n *             },\n *             corner: {\n *                 entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FNqI\"],\n *                 worldPos: [-0.0005214119318139865, 3.1010044228517595, 17.787656604483363]\n *\n *             },\n *             target: {\n *                 entity: viewer.scene.objects[\"1s1jVhK8z0pgKYcr9jt7AB\"],\n *                 worldPos: [ 8.380657312957396, 3.1055697628459553, 17.799220108187185]\n *             },\n *             visible: true\n *         });\n * });\n * ````\n *\n * ## Example 5: Creating AngleMeasurements with Touch Input\n *\n * In our fifth example, we'll show how to create angle measurements with touch input, with snapping\n * to the nearest vertex or edge. While creating the measurements, a long-touch when setting the\n * start, corner or end point will cause the point to snap to the nearest vertex or edge. A quick\n * touch-release will immediately set the point at the tapped position on the object surface.\n *\n * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/measurement/#angle_createWithTouch_snapping)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, AngleMeasurementsPlugin, AngleMeasurementsTouchControl} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-2.37, 18.97, -26.12];\n * viewer.scene.camera.look = [10.97, 5.82, -11.22];\n * viewer.scene.camera.up = [0.36, 0.83, 0.40];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const angleMeasurements = new AngleMeasurementsPlugin(viewer);\n *\n * const model = xktLoader.load({\n *      src: \"./models/xkt/duplex/duplex.xkt\"\n * });\n *\n * const angleMeasurements = new AngleMeasurementsPlugin(viewer);\n *\n * const angleMeasurementsTouchControl  = new AngleMeasurementsTouchControl(angleMeasurements, {\n *     pointerLens : new PointerLens(viewer),\n *     snapToVertex: true,\n *     snapToEdge: true\n * })\n *\n * angleMeasurementsTouchControl.activate();\n * ````\n */\nclass AngleMeasurementsPlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} [cfg]  Plugin configuration.\n     * @param {String} [cfg.id=\"AngleMeasurements\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {HTMLElement} [cfg.container] Container DOM element for markers and labels. Defaults to ````document.body````.\n     * @param {string} [cfg.defaultColor=null] The default color of the dots, wire and label.\n     * @param {boolean} [cfg.defaultLabelsVisible=true] The default value of {@link AngleMeasurement.labelsVisible}.\n     * @param {number} [cfg.zIndex] If set, the wires, dots and labels will have this zIndex (+1 for dots and +2 for labels).\n     * @param {PointerCircle} [cfg.pointerLens] A PointerLens to help the user position the pointer. This can be shared with other plugins.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"AngleMeasurements\", viewer);\n\n        this._container = cfg.container || document.body;\n\n        this._defaultControl = null;\n\n        this._measurements = {};\n\n        this.defaultColor = cfg.defaultColor !== undefined ? cfg.defaultColor : \"#00BBFF\";\n        this.defaultLabelsVisible = cfg.defaultLabelsVisible !== false;\n        this.zIndex = cfg.zIndex || 10000;\n\n        this._onMouseOver = (event, measurement) => {\n            this.fire(\"mouseOver\", {\n                plugin: this,\n                angleMeasurement: measurement,\n                measurement,\n                event\n            });\n        };\n\n        this._onMouseLeave = (event, measurement) => {\n            this.fire(\"mouseLeave\", {\n                plugin: this,\n                angleMeasurement: measurement,\n                measurement,\n                event\n            });\n        };\n\n        this._onContextMenu = (event, measurement) => {\n            this.fire(\"contextMenu\", {\n                plugin: this,\n                angleMeasurement: measurement,\n                measurement,\n                event\n            });\n        };\n    }\n\n    /**\n     * Gets the plugin's HTML container element, if any.\n     * @returns {*|HTMLElement|HTMLElement}\n     */\n    getContainerElement() {\n        return this._container;\n    }\n\n\n    /**\n     * @private\n     */\n    send(name, value) {\n\n    }\n\n    /**\n     * Gets the default {@link AngleMeasurementsMouseControl}.\n     *\n     * @type {AngleMeasurementsMouseControl}\n     * @deprecated\n     */\n    get control() {\n        if (!this._defaultControl) {\n            this._defaultControl = new AngleMeasurementsMouseControl(this, {});\n        }\n        return this._defaultControl;\n    }\n\n    /**\n     * Gets the existing {@link AngleMeasurement}s, each mapped to its {@link AngleMeasurement#id}.\n     *\n     * @type {{String:AngleMeasurement}}\n     */\n    get measurements() {\n        return this._measurements;\n    }\n\n    /**\n     * Creates an {@link AngleMeasurement}.\n     *\n     * The AngleMeasurement is then registered by {@link AngleMeasurement#id} in {@link AngleMeasurementsPlugin#measurements}.\n     *\n     * @param {Object} params {@link AngleMeasurement} configuration.\n     * @param {String} params.id Unique ID to assign to {@link AngleMeasurement#id}. The AngleMeasurement will be registered by this in {@link AngleMeasurementsPlugin#measurements} and {@link Scene.components}. Must be unique among all components in the {@link Viewer}.\n     * @param {Number[]} params.origin.worldPos Origin World-space 3D position.\n     * @param {Entity} params.origin.entity Origin Entity.\n     * @param {Number[]} params.corner.worldPos Corner World-space 3D position.\n     * @param {Entity} params.corner.entity Corner Entity.\n     * @param {Number[]} params.target.worldPos Target World-space 3D position.\n     * @param {Entity} params.target.entity Target Entity.\n     * @param {Boolean} [params.visible=true] Whether to initially show the {@link AngleMeasurement}.\n     * @returns {AngleMeasurement} The new {@link AngleMeasurement}.\n     */\n    createMeasurement(params = {}) {\n        if (this.viewer.scene.components[params.id]) {\n            this.error(\"Viewer scene component with this ID already exists: \" + params.id);\n            delete params.id;\n        }\n        const origin = params.origin;\n        const corner = params.corner;\n        const target = params.target;\n        const measurement = new AngleMeasurement(this, {\n            id: params.id,\n            plugin: this,\n            container: this._container,\n            origin: {\n                entity: origin.entity,\n                worldPos: origin.worldPos\n            },\n            corner: {\n                entity: corner.entity,\n                worldPos: corner.worldPos\n            },\n            target: {\n                entity: target.entity,\n                worldPos: target.worldPos\n            },\n\n            visible: params.visible,\n            originVisible: true,\n            originWireVisible: true,\n            cornerVisible: true,\n            targetWireVisible: true,\n            targetVisible: true,\n            onMouseOver: this._onMouseOver,\n            onMouseLeave: this._onMouseLeave,\n            onContextMenu: this._onContextMenu\n        });\n        this._measurements[measurement.id] = measurement;\n        measurement.on(\"destroyed\", () => {\n            delete this._measurements[measurement.id];\n        });\n        measurement.clickable = true;\n        this.fire(\"measurementCreated\", measurement);\n        return measurement;\n    }\n\n    /**\n     * Destroys a {@link AngleMeasurement}.\n     *\n     * @param {String} id ID of AngleMeasurement to destroy.\n     */\n    destroyMeasurement(id) {\n        const measurement = this._measurements[id];\n        if (!measurement) {\n            this.log(\"AngleMeasurement not found: \" + id);\n            return;\n        }\n        measurement.destroy();\n        this.fire(\"measurementDestroyed\", measurement);\n    }\n\n    /**\n     * Shows all or hides the angle label of each {@link AngleMeasurement}.\n     *\n     * @param {Boolean} labelsShown Whether or not to show the labels.\n     */\n    setLabelsShown(labelsShown) {\n        for (const [key, measurement] of Object.entries(this.measurements)) {\n            measurement.labelShown = labelsShown;\n        }\n    }\n\n    /**\n     * Destroys all {@link AngleMeasurement}s.\n     */\n    clear() {\n        const ids = Object.keys(this._measurements);\n        for (var i = 0, len = ids.length; i < len; i++) {\n            this.destroyMeasurement(ids[i]);\n        }\n    }\n\n    /**\n     * Destroys this AngleMeasurementsPlugin.\n     *\n     * Destroys all {@link AngleMeasurement}s first.\n     */\n    destroy() {\n        this.clear();\n        super.destroy();\n    }\n}\n\nconst WAITING_FOR_ORIGIN_TOUCH_START$1 = 0;\nconst WAITING_FOR_ORIGIN_QUICK_TOUCH_END$1 = 1;\nconst WAITING_FOR_ORIGIN_LONG_TOUCH_END$1 = 2;\n\nconst WAITING_FOR_CORNER_TOUCH_START = 3;\nconst WAITING_FOR_CORNER_QUICK_TOUCH_END = 4;\nconst WAITING_FOR_CORNER_LONG_TOUCH_END = 5;\n\nconst WAITING_FOR_TARGET_TOUCH_START$1 = 6;\nconst WAITING_FOR_TARGET_QUICK_TOUCH_END$1 = 7;\nconst WAITING_FOR_TARGET_LONG_TOUCH_END$1 = 8;\n\nconst TOUCH_CANCELING$1 = 7;\n\nconst tmpVec2$1 = math.vec2();\n\n/**\n * Creates {@link AngleMeasurement}s from touch input.\n *\n * See {@link AngleMeasurementsPlugin} for more info.\n *\n */\nclass AngleMeasurementsTouchControl extends AngleMeasurementsControl {\n\n    /**\n     * Creates a AngleMeasurementsTouchControl bound to the given AngleMeasurementsPlugin.\n     */\n    constructor(angleMeasurementsPlugin, cfg = {}) {\n\n        super(angleMeasurementsPlugin.viewer.scene);\n\n        this.pointerLens = cfg.pointerLens;\n        this.pointerCircle = new PointerCircle(angleMeasurementsPlugin.viewer);\n\n        this._active = false;\n\n        const markerDiv = document.createElement('div');\n        const canvas = this.scene.canvas.canvas;\n        canvas.parentNode.insertBefore(markerDiv, canvas);\n\n        markerDiv.style.background = \"black\";\n        markerDiv.style.border = \"2px solid blue\";\n        markerDiv.style.borderRadius = \"10px\";\n        markerDiv.style.width = \"5px\";\n        markerDiv.style.height = \"5px\";\n        markerDiv.style.margin = \"-200px -200px\";\n        markerDiv.style.zIndex = \"100\";\n        markerDiv.style.position = \"absolute\";\n        markerDiv.style.pointerEvents = \"none\";\n\n        this.markerDiv = markerDiv;\n\n        this._currentAngleMeasurement = null;\n\n        this._longTouchTimeoutMs = 300;\n        this._snapping = cfg.snapping !== false;\n        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;\n\n        this._attachPlugin(angleMeasurementsPlugin, cfg);\n    }\n\n    _attachPlugin(angleMeasurementsPlugin) {\n\n        /**\n         * The {@link AngleMeasurementsPlugin} that owns this AngleMeasurementsTouchControl.\n         * @type {AngleMeasurementsPlugin}\n         */\n        this.angleMeasurementsPlugin = angleMeasurementsPlugin;\n\n        /**\n         * The {@link AngleMeasurementsPlugin} that owns this AngleMeasurementsTouchControl.\n         * @type {AngleMeasurementsPlugin}\n         */\n        this.plugin = angleMeasurementsPlugin;\n    }\n\n    /** Gets if this AngleMeasurementsTouchControl is currently active, where it is responding to input.\n     *\n     * @returns {Boolean}\n     */\n    get active() {\n        return this._active;\n    }\n\n    /**\n     * Sets whether snap-to-vertex and snap-to-edge are enabled for this AngleMeasurementsMouseControl.\n     *\n     * This is `true` by default.\n     *\n     * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this AngleMeasurementsMouseControl.\n     */\n    set snapping(snapping) {\n        this._snapping = snapping;\n    }\n\n    /**\n     * Gets whether snap-to-vertex and snap-to-edge are enabled for this AngleMeasurementsMouseControl.\n     *\n     * This is `true` by default.\n     *\n     * @returns {boolean} Whether snap-to-vertex and snap-to-edge are enabled for this AngleMeasurementsMouseControl.\n     */\n    get snapping() {\n        return this._snapping;\n    }\n\n    /**\n     * Activates this AngleMeasurementsTouchControl, ready to respond to input.\n     */\n    activate() {\n\n        if (this._active) {\n            return;\n        }\n\n        const plugin = this.plugin;\n        const scene = this.scene;\n        const canvas = scene.canvas.canvas;\n        plugin.pointerLens;\n        const pointerWorldPos = math.vec3();\n\n        const touchTolerance = 20;\n\n        let longTouchTimeout = null;\n\n        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;\n\n        const touchStartCanvasPos = math.vec2();\n        const touchMoveCanvasPos = math.vec2();\n        const touchEndCanvasPos = math.vec2();\n\n        let touchId = null;\n\n        const disableCameraNavigation = () => {\n            this.plugin.viewer.cameraControl.active = false;\n        };\n\n        const enableCameraNavigation = () => {\n            this.plugin.viewer.cameraControl.active = true;\n        };\n\n        const cancel = () => {\n            if (longTouchTimeout) {\n                clearTimeout(longTouchTimeout);\n                longTouchTimeout = null;\n            }\n            if (this._currentAngleMeasurement) {\n                this._currentAngleMeasurement.destroy();\n                this._currentAngleMeasurement = null;\n            }\n            enableCameraNavigation();\n            this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;\n        };\n\n        const copyCanvasPos = (event, dst) => {\n            dst[0] = event.clientX;\n            dst[1] = event.clientY;\n            transformToNode(canvas.ownerDocument.documentElement, canvas, dst);\n            return dst;\n        };\n\n        const toBodyPos = (pos, dst) => {\n            dst.set(pos);\n            transformToNode(canvas, canvas.ownerDocument.documentElement, dst);\n            return dst;\n        };\n\n        canvas.addEventListener(\"touchstart\", this._onCanvasTouchStart = (event) => {\n\n            const currentNumTouches = event.touches.length;\n\n            if (currentNumTouches !== 1) {\n                if (longTouchTimeout) {\n                    clearTimeout(longTouchTimeout);\n                    longTouchTimeout = null;\n                }\n                return;\n            }\n\n            const touch = event.touches[0];\n            copyCanvasPos(touch, touchStartCanvasPos);\n            touchMoveCanvasPos.set(touchStartCanvasPos);\n\n            switch (this._touchState) {\n\n                case WAITING_FOR_ORIGIN_TOUCH_START$1:\n                    if (currentNumTouches !== 1 && longTouchTimeout !== null) { // Two or more fingers down\n                        cancel();\n                        return;\n                    }\n                    const snapPickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        snapToVertex: this._snapping,\n                        snapToEdge: this._snapping\n                    });\n                    if (snapPickResult && snapPickResult.snapped) {\n                        pointerWorldPos.set(snapPickResult.worldPos);\n                        this.pointerCircle.start(toBodyPos(snapPickResult.snappedCanvasPos, tmpVec2$1));\n                    } else {\n                        const pickResult = scene.pick({\n                            canvasPos: touchMoveCanvasPos,\n                            pickSurface: true\n                        });\n                        if (pickResult && pickResult.worldPos) {\n                            pointerWorldPos.set(pickResult.worldPos);\n                            this.pointerCircle.start(toBodyPos(pickResult.canvasPos, tmpVec2$1));\n                        } else {\n                            return;\n                        }\n                    }\n                    longTouchTimeout = setTimeout(() => {\n                        if (currentNumTouches !== 1 ||\n                            touchMoveCanvasPos[0] > touchStartCanvasPos[0] + touchTolerance ||\n                            touchMoveCanvasPos[0] < touchStartCanvasPos[0] - touchTolerance ||\n                            touchMoveCanvasPos[1] > touchStartCanvasPos[1] + touchTolerance ||\n                            touchMoveCanvasPos[1] < touchStartCanvasPos[1] - touchTolerance) {\n                            return;   // Has moved\n                        }\n                        // Long touch\n                        if (this.pointerLens) {\n                            this.pointerLens.visible = true;\n                            this.pointerLens.canvasPos = touchStartCanvasPos;\n                            this.pointerLens.cursorPos = touchStartCanvasPos;\n                        }\n                        if (this.pointerLens) {\n                            this.pointerLens.canvasPos = touchMoveCanvasPos;\n                            this.pointerLens.snapped = false;\n                        }\n                        if (this.pointerLens) {\n                            this.pointerLens.cursorPos = snapPickResult.canvasPos;\n                            this.pointerLens.snapped = true;\n                        }\n                        // pointerWorldPos.set(snapPickResult.worldPos);\n                        if (!this._currentAngleMeasurement) {\n                            this._currentAngleMeasurement = plugin.createMeasurement({\n                                id: math.createUUID(),\n                                origin: {\n                                    worldPos: snapPickResult.worldPos,\n                                    entity: snapPickResult.entity\n                                },\n                                corner: {\n                                    worldPos: snapPickResult.worldPos,\n                                    entity: snapPickResult.entity\n                                },\n                                target: {\n                                    worldPos: snapPickResult.worldPos,\n                                    entity: snapPickResult.entity\n                                }\n                            });\n                            this._currentAngleMeasurement.clickable = false;\n                            this._currentAngleMeasurement.originVisible = true;\n                            this._currentAngleMeasurement.originWireVisible = false;\n                            this._currentAngleMeasurement.cornerVisible = false;\n                            this._currentAngleMeasurement.cornerWireVisible = false;\n                            this._currentAngleMeasurement.targetVisible = false;\n                            this._currentAngleMeasurement.targetWireVisible = false;\n                            this._currentAngleMeasurement.angleVisible = false;\n                        } else {\n                            this._currentAngleMeasurement.origin.worldPos = pointerWorldPos;\n                        }\n                        this.angleMeasurementsPlugin.fire(\"measurementStart\", this._currentAngleMeasurement);\n                        // if (this.pointerLens) {\n                        //     this.pointerLens.cursorPos = pickResult.canvasPos;\n                        //     this.pointerLens.snapped = false;\n                        // }\n                        this._touchState = WAITING_FOR_ORIGIN_LONG_TOUCH_END$1;\n                      //  console.log(\"touchstart: this._touchState= WAITING_FOR_ORIGIN_TOUCH_START -> WAITING_FOR_ORIGIN_LONG_TOUCH_END\")\n                        disableCameraNavigation();\n                    }, this._longTouchTimeoutMs);\n                    this._touchState = WAITING_FOR_ORIGIN_QUICK_TOUCH_END$1;\n                    //console.log(\"touchstart: this._touchState= WAITING_FOR_ORIGIN_TOUCH_START -> WAITING_FOR_ORIGIN_QUICK_TOUCH_END\")\n\n                    touchId = touch.identifier;\n\n                    break;\n\n                case WAITING_FOR_CORNER_TOUCH_START:\n\n                    if (currentNumTouches !== 1 && longTouchTimeout !== null) { // Two or more fingers down\n                        clearTimeout(longTouchTimeout);\n                        longTouchTimeout = null;\n                        return;\n                    }\n                    if (currentNumTouches === 1) { // One finger down\n                        longTouchTimeout = setTimeout(() => {\n                            longTouchTimeout = null;\n                            if (currentNumTouches !== 1 ||\n                                touchMoveCanvasPos[0] > touchStartCanvasPos[0] + touchTolerance ||\n                                touchMoveCanvasPos[0] < touchStartCanvasPos[0] - touchTolerance ||\n                                touchMoveCanvasPos[1] > touchStartCanvasPos[1] + touchTolerance ||\n                                touchMoveCanvasPos[1] < touchStartCanvasPos[1] - touchTolerance) {\n                                // Has moved\n                                return;\n                            }\n\n                            // Long touch\n                            if (this.pointerLens) {\n                                this.pointerLens.visible = true;\n                                this.pointerLens.canvasPos = touchStartCanvasPos;\n                                this.pointerLens.snapped = false;\n                            }\n\n                            const snapPickResult = scene.pick({\n                                canvasPos: touchMoveCanvasPos,\n                                snapToVertex: this._snapping,\n                                snapToEdge: this._snapping\n                            });\n                            if (snapPickResult && snapPickResult.snapped) {\n                                if (this.pointerLens) {\n                                    this.pointerLens.cursorPos = snapPickResult.snappedCanvasPos;\n                                    this.pointerLens.snapped = true;\n                                }\n                                this.pointerCircle.start(toBodyPos(snapPickResult.snappedCanvasPos, tmpVec2$1));\n                                pointerWorldPos.set(snapPickResult.worldPos);\n                                this._currentAngleMeasurement.corner.worldPos = snapPickResult.worldPos;\n                                this._currentAngleMeasurement.corner.entity = snapPickResult.entity;\n                                this._currentAngleMeasurement.originVisible = true;\n                                this._currentAngleMeasurement.originWireVisible = true;\n                                this._currentAngleMeasurement.cornerVisible = true;\n                                this._currentAngleMeasurement.cornerWireVisible = false;\n                                this._currentAngleMeasurement.targetVisible = false;\n                                this._currentAngleMeasurement.targetWireVisible = false;\n                                this._currentAngleMeasurement.angleVisible = false;\n                                this.angleMeasurementsPlugin.fire(\"measurementStart\", this._currentAngleMeasurement);\n                            } else {\n                                const pickResult = scene.pick({\n                                    canvasPos: touchMoveCanvasPos,\n                                    pickSurface: true\n                                });\n                                if (pickResult && pickResult.worldPos) {\n                                    if (this.pointerLens) {\n                                        this.pointerLens.cursorPos = pickResult.canvasPos;\n                                        this.pointerLens.snapped = false;\n                                    }\n                                    this.pointerCircle.start(toBodyPos(pickResult.canvasPos, tmpVec2$1));\n                                    pointerWorldPos.set(pickResult.worldPos);\n                                    this._currentAngleMeasurement.corner.worldPos = pickResult.worldPos;\n                                    this._currentAngleMeasurement.corner.entity = pickResult.entity;\n                                    this._currentAngleMeasurement.originVisible = true;\n                                    this._currentAngleMeasurement.originWireVisible = true;\n                                    this._currentAngleMeasurement.cornerVisible = true;\n                                    this._currentAngleMeasurement.cornerWireVisible = false;\n                                    this._currentAngleMeasurement.targetVisible = false;\n                                    this._currentAngleMeasurement.targetWireVisible = false;\n                                    this._currentAngleMeasurement.angleVisible = false;\n                                    this.angleMeasurementsPlugin.fire(\"measurementStart\", this._currentAngleMeasurement);\n                                } else {\n                                    if (this.pointerLens) {\n                                        this.pointerLens.cursorPos = null;\n                                        this.pointerLens.snapped = false;\n\n                                    }\n                                }\n                            }\n                            this._touchState = WAITING_FOR_CORNER_LONG_TOUCH_END;\n                           // console.log(\"touchstart: this._touchState= WAITING_FOR_CORNER_TOUCH_START -> WAITING_FOR_CORNER_LONG_TOUCH_END\")\n\n                            disableCameraNavigation();\n\n                        }, this._longTouchTimeoutMs);\n\n                        this._touchState = WAITING_FOR_CORNER_QUICK_TOUCH_END;\n                      //  console.log(\"touchstart: this._touchState= WAITING_FOR_CORNER_TOUCH_START -> WAITING_FOR_CORNER_QUICK_TOUCH_END\")\n                    }\n\n                    touchId = touch.identifier;\n\n                    break;\n\n                case WAITING_FOR_TARGET_TOUCH_START$1:\n\n                    if (currentNumTouches !== 1 && longTouchTimeout !== null) { // Two or more fingers down\n                        clearTimeout(longTouchTimeout);\n                        longTouchTimeout = null;\n                        return;\n                    }\n                    if (currentNumTouches === 1) { // One finger down\n                        longTouchTimeout = setTimeout(() => {\n                            longTouchTimeout = null;\n                            if (currentNumTouches !== 1 ||\n                                touchMoveCanvasPos[0] > touchStartCanvasPos[0] + touchTolerance ||\n                                touchMoveCanvasPos[0] < touchStartCanvasPos[0] - touchTolerance ||\n                                touchMoveCanvasPos[1] > touchStartCanvasPos[1] + touchTolerance ||\n                                touchMoveCanvasPos[1] < touchStartCanvasPos[1] - touchTolerance) {\n                                // Has moved\n                                return;\n                            }\n\n                            // Long touch\n                            if (this.pointerLens) {\n                                this.pointerLens.visible = true;\n                                this.pointerLens.canvasPos = touchStartCanvasPos;\n                                this.pointerLens.snapped = false;\n                            }\n\n                            const snapPickResult = scene.pick({\n                                canvasPos: touchMoveCanvasPos,\n                                snapToVertex: this._snapping,\n                                snapToEdge: this._snapping\n                            });\n                            if (snapPickResult && snapPickResult.snapped) {\n                                if (this.pointerLens) {\n                                    this.pointerLens.cursorPos = snapPickResult.snappedCanvasPos;\n                                    this.pointerLens.snapped = true;\n                                }\n                                this.pointerCircle.start(toBodyPos(snapPickResult.snappedCanvasPos, tmpVec2$1));\n                                pointerWorldPos.set(snapPickResult.worldPos);\n                                this._currentAngleMeasurement.target.worldPos = snapPickResult.worldPos;\n                                this._currentAngleMeasurement.target.entity = snapPickResult.entity;\n                                this._currentAngleMeasurement.originVisible = true;\n                                this._currentAngleMeasurement.originWireVisible = true;\n                                this._currentAngleMeasurement.cornerVisible = true;\n                                this._currentAngleMeasurement.cornerWireVisible = true;\n                                this._currentAngleMeasurement.targetVisible = true;\n                                this._currentAngleMeasurement.targetWireVisible = true;\n                                this._currentAngleMeasurement.angleVisible = true;\n                                this.angleMeasurementsPlugin.fire(\"measurementStart\", this._currentAngleMeasurement);\n                            } else {\n                                const pickResult = scene.pick({\n                                    canvasPos: touchMoveCanvasPos,\n                                    pickSurface: true\n                                });\n                                if (pickResult && pickResult.worldPos) {\n                                    if (this.pointerLens) {\n                                        this.pointerLens.cursorPos = pickResult.canvasPos;\n                                        this.pointerLens.snapped = false;\n                                    }\n                                    this.pointerCircle.start(toBodyPos(pickResult.canvasPos, tmpVec2$1));\n                                    pointerWorldPos.set(pickResult.worldPos);\n                                    this._currentAngleMeasurement.target.worldPos = pickResult.worldPos;\n                                    this._currentAngleMeasurement.target.entity = pickResult.entity;\n                                    this._currentAngleMeasurement.originVisible = true;\n                                    this._currentAngleMeasurement.originWireVisible = true;\n                                    this._currentAngleMeasurement.cornerVisible = true;\n                                    this._currentAngleMeasurement.cornerWireVisible = true;\n                                    this._currentAngleMeasurement.targetVisible = true;\n                                    this._currentAngleMeasurement.targetWireVisible = true;\n                                    this._currentAngleMeasurement.angleVisible = true;\n                                    this.angleMeasurementsPlugin.fire(\"measurementStart\", this._currentAngleMeasurement);\n                                } else {\n                                    if (this.pointerLens) {\n                                        this.pointerLens.cursorPos = null;\n                                        this.pointerLens.snapped = false;\n\n                                    }\n                                }\n                            }\n                            this._touchState = WAITING_FOR_TARGET_LONG_TOUCH_END$1;\n                           // console.log(\"touchstart: this._touchState= WAITING_FOR_TARGET_TOUCH_START -> WAITING_FOR_TARGET_LONG_TOUCH_END\")\n\n                            disableCameraNavigation();\n\n                        }, this._longTouchTimeoutMs);\n\n                        this._touchState = WAITING_FOR_TARGET_QUICK_TOUCH_END$1;\n                       // console.log(\"touchstart: this._touchState= WAITING_FOR_TARGET_TOUCH_START -> WAITING_FOR_TARGET_QUICK_TOUCH_END\")\n                    }\n\n                    touchId = touch.identifier;\n\n                    break;\n\n\n                default:\n                    if (longTouchTimeout !== null) {\n                        clearTimeout(longTouchTimeout);\n                        longTouchTimeout = null;\n                    }\n                    this._touchState = TOUCH_CANCELING$1;\n                  //  console.log(\"touchstart: this._touchState= default -> TOUCH_CANCELING\")\n                    return;\n            }\n\n        }, {passive: true});\n\n\n        canvas.addEventListener(\"touchmove\", (event) => {\n\n            this.pointerCircle.stop();\n\n            const currentNumTouches = event.touches.length;\n\n            if (currentNumTouches !== 1 || event.changedTouches.length !== 1) {\n                if (longTouchTimeout) {\n                    clearTimeout(longTouchTimeout);\n                    longTouchTimeout = null;\n                }\n                return;\n            }\n\n            const touch = event.touches[0];\n            if (touch.identifier !== touchId) {\n                return;\n            }\n\n            copyCanvasPos(touch, touchMoveCanvasPos);\n\n            let snapPickResult;\n            let pickResult;\n\n            switch (this._touchState) {\n\n                case WAITING_FOR_ORIGIN_LONG_TOUCH_END$1:\n                    if (this.pointerLens) {\n                        this.pointerLens.canvasPos = touchMoveCanvasPos;\n                    }\n                    snapPickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        snapToVertex: this._snapping,\n                        snapToEdge: this._snapping\n                    });\n                    if (snapPickResult && (snapPickResult.snapped)) {\n                        if (this.pointerLens) {\n                            this.pointerLens.snappedCanvasPos = snapPickResult.snappedCanvasPos;\n                            this.pointerLens.snapped = true;\n                        }\n                        pointerWorldPos.set(snapPickResult.worldPos);\n                        this._currentAngleMeasurement.origin.worldPos = snapPickResult.worldPos;\n                    } else {\n                        pickResult = scene.pick({\n                            canvasPos: touchMoveCanvasPos,\n                            pickSurface: true\n                        });\n                        if (pickResult && pickResult.worldPos) {\n                            if (this.pointerLens) {\n                                this.pointerLens.cursorPos = pickResult.canvasPos;\n                                this.pointerLens.snapped = false;\n                            }\n                            pointerWorldPos.set(pickResult.worldPos);\n                            this._currentAngleMeasurement.origin.worldPos = pickResult.worldPos;\n                        } else {\n                            if (this.pointerLens) {\n                                this.pointerLens.cursorPos = null;\n                                this.pointerLens.snapped = false;\n                            }\n                        }\n                    }\n                    this._touchState = WAITING_FOR_ORIGIN_LONG_TOUCH_END$1;\n                   // console.log(\"touchmove: this._touchState= WAITING_FOR_ORIGIN_LONG_TOUCH_END -> WAITING_FOR_ORIGIN_LONG_TOUCH_END\")\n                    break;\n\n                case WAITING_FOR_CORNER_LONG_TOUCH_END:\n                    if (currentNumTouches !== 1 && longTouchTimeout !== null) { // Two or more fingers down\n                        clearTimeout(longTouchTimeout);\n                        longTouchTimeout = null;\n                        if (this.pointerLens) {\n                            this.pointerLens.visible = false;\n                        }\n                        this._touchState = TOUCH_CANCELING$1;\n                     //   console.log(\"touchmove: this._touchState= QUICK_TOUCH_FINDING_CORNER -> TOUCH_CANCELING\")\n                        return;\n                    }\n                    if (this.pointerLens) {\n                        this.pointerLens.canvasPos = touchMoveCanvasPos;\n                    }\n                    snapPickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        snapToVertex: this._snapping,\n                        snapToEdge: this._snapping\n                    });\n                    if (snapPickResult && snapPickResult.worldPos) {\n                        if (this.pointerLens) {\n                            this.pointerLens.cursorPos = snapPickResult.snappedCanvasPos;\n                            this.pointerLens.snapped = true;\n                        }\n                        this._currentAngleMeasurement.corner.worldPos = snapPickResult.worldPos;\n                        this._currentAngleMeasurement.originVisible = true;\n                        this._currentAngleMeasurement.originWireVisible = true;\n                        this._currentAngleMeasurement.cornerVisible = true;\n                        this._currentAngleMeasurement.cornerWireVisible = false;\n                        this._currentAngleMeasurement.targetVisible = false;\n                        this._currentAngleMeasurement.targetWireVisible = false;\n                        this._currentAngleMeasurement.angleVisible = false;\n                    } else {\n                        pickResult = scene.pick({\n                            canvasPos: touchMoveCanvasPos,\n                            pickSurface: true\n                        });\n                        if (pickResult && pickResult.worldPos) {\n                            if (this.pointerLens) {\n                                this.pointerLens.cursorPos = pickResult.canvasPos;\n                                this.pointerLens.snapped = false;\n                            }\n                            this._currentAngleMeasurement.corner.worldPos = pickResult.worldPos;\n                            this._currentAngleMeasurement.originVisible = true;\n                            this._currentAngleMeasurement.originWireVisible = true;\n                            this._currentAngleMeasurement.cornerVisible = true;\n                            this._currentAngleMeasurement.cornerWireVisible = false;\n                            this._currentAngleMeasurement.targetVisible = false;\n                            this._currentAngleMeasurement.targetWireVisible = false;\n                            this._currentAngleMeasurement.angleVisible = false;\n                        }\n                    }\n                    this._touchState = WAITING_FOR_CORNER_LONG_TOUCH_END;\n                    break;\n\n\n                case WAITING_FOR_TARGET_LONG_TOUCH_END$1:\n                    if (currentNumTouches !== 1 && longTouchTimeout !== null) { // Two or more fingers down\n                        clearTimeout(longTouchTimeout);\n                        longTouchTimeout = null;\n                        if (this.pointerLens) {\n                            this.pointerLens.visible = false;\n                        }\n                        this._touchState = TOUCH_CANCELING$1;\n                      //  console.log(\"touchmove: this._touchState= QUICK_TOUCH_FINDING_TARGET -> TOUCH_CANCELING\")\n                        return;\n                    }\n                    if (this.pointerLens) {\n                        this.pointerLens.canvasPos = touchMoveCanvasPos;\n                    }\n                    snapPickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        snapToVertex: this._snapping,\n                        snapToEdge: this._snapping\n                    });\n                    if (snapPickResult && snapPickResult.worldPos) {\n                        if (this.pointerLens) {\n                            this.pointerLens.cursorPos = snapPickResult.snappedCanvasPos;\n                            this.pointerLens.snapped = true;\n                        }\n                        this._currentAngleMeasurement.target.worldPos = snapPickResult.worldPos;\n                        this._currentAngleMeasurement.originVisible = true;\n                        this._currentAngleMeasurement.originWireVisible = true;\n                        this._currentAngleMeasurement.cornerVisible = true;\n                        this._currentAngleMeasurement.cornerWireVisible = true;\n                        this._currentAngleMeasurement.targetVisible = true;\n                        this._currentAngleMeasurement.targetWireVisible = true;\n                        this._currentAngleMeasurement.angleVisible = true;\n                    } else {\n                        pickResult = scene.pick({\n                            canvasPos: touchMoveCanvasPos,\n                            pickSurface: true\n                        });\n                        if (pickResult && pickResult.worldPos) {\n                            if (this.pointerLens) {\n                                this.pointerLens.cursorPos = pickResult.canvasPos;\n                                this.pointerLens.snapped = false;\n                            }\n                            this._currentAngleMeasurement.target.worldPos = pickResult.worldPos;\n                            this._currentAngleMeasurement.originVisible = true;\n                            this._currentAngleMeasurement.originWireVisible = true;\n                            this._currentAngleMeasurement.cornerVisible = true;\n                            this._currentAngleMeasurement.cornerWireVisible = true;\n                            this._currentAngleMeasurement.targetVisible = true;\n                            this._currentAngleMeasurement.targetWireVisible = true;\n                            this._currentAngleMeasurement.angleVisible = true;\n                        }\n                    }\n                    this._touchState = WAITING_FOR_TARGET_LONG_TOUCH_END$1;\n                    break;\n            }\n        }, {passive: true});\n\n        canvas.addEventListener(\"touchend\", this._onCanvasTouchEnd = (event) => {\n\n            this.pointerCircle.stop();\n\n            const numChangedTouches = event.changedTouches.length;\n\n            if (numChangedTouches !== 1) {\n                return;\n            }\n\n            const touch = event.changedTouches[0];\n            if (touch.identifier !== touchId) {\n                return;\n            }\n\n            if (longTouchTimeout) {\n                clearTimeout(longTouchTimeout);\n                longTouchTimeout = null;\n            }\n\n            copyCanvasPos(touch, touchEndCanvasPos);\n\n            const touchX = touchEndCanvasPos[0];\n            const touchY = touchEndCanvasPos[1];\n\n            switch (this._touchState) {\n\n                case WAITING_FOR_ORIGIN_QUICK_TOUCH_END$1: {\n                    if (numChangedTouches !== 1 ||\n                        touchX > touchStartCanvasPos[0] + touchTolerance ||\n                        touchX < touchStartCanvasPos[0] - touchTolerance ||\n                        touchY > touchStartCanvasPos[1] + touchTolerance ||\n                        touchY < touchStartCanvasPos[1] - touchTolerance) {\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;\n                        return;\n                    }\n                    const pickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        pickSurface: true\n                    });\n                    if (pickResult && pickResult.worldPos) {\n                        this._currentAngleMeasurement = plugin.createMeasurement({\n                            id: math.createUUID(),\n                            origin: {\n                                worldPos: pickResult.worldPos\n                            },\n                            corner: {\n                                worldPos: pickResult.worldPos\n                            },\n                            target: {\n                                worldPos: pickResult.worldPos\n                            }\n                        });\n                        this._currentAngleMeasurement.clickable = false;\n                        this._currentAngleMeasurement.originVisible = true;\n                        this._currentAngleMeasurement.originWireVisible = false;\n                        this._currentAngleMeasurement.cornerVisible = false;\n                        this._currentAngleMeasurement.cornerWireVisible = false;\n                        this._currentAngleMeasurement.targetVisible = false;\n                        this._currentAngleMeasurement.targetWireVisible = false;\n                        this._currentAngleMeasurement.angleVisible = false;\n                        this._touchState = WAITING_FOR_CORNER_TOUCH_START;\n                      //  console.log(\"touchend: this._touchState= WAITING_FOR_ORIGIN_QUICK_TOUCH_END -> WAITING_FOR_CORNER_TOUCH_START\")\n                    } else {\n                        if (this._currentAngleMeasurement) {\n                            this._currentAngleMeasurement.destroy();\n                            this._currentAngleMeasurement = null;\n                        }\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;\n                      //  console.log(\"touchend: this._touchState= WAITING_FOR_ORIGIN_QUICK_TOUCH_END -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    }\n                }\n                    enableCameraNavigation();\n                    break;\n\n                case WAITING_FOR_ORIGIN_LONG_TOUCH_END$1:\n                    if (this.pointerLens) {\n                        this.pointerLens.visible = false;\n                    }\n                    if (!this._currentAngleMeasurement) {\n                        if (this.pointerLens) {\n                            this.pointerLens.snapped = false;\n                            this.pointerLens.visible = false;\n                        }\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;\n                      //  console.log(\"touchend: this._touchState= WAITING_FOR_ORIGIN_LONG_TOUCH_END (no measurement) -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    } else {\n                        this._touchState = WAITING_FOR_CORNER_TOUCH_START;\n                       // console.log(\"touchend: this._touchState= WAITING_FOR_ORIGIN_LONG_TOUCH_END (picked, begin measurement) -> WAITING_FOR_CORNER_TOUCH_START\")\n                    }\n                    enableCameraNavigation();\n                    break;\n\n                case WAITING_FOR_CORNER_QUICK_TOUCH_END: {\n                    if (numChangedTouches !== 1 ||\n                        touchX > touchStartCanvasPos[0] + touchTolerance ||\n                        touchX < touchStartCanvasPos[0] - touchTolerance ||\n                        touchY > touchStartCanvasPos[1] + touchTolerance ||\n                        touchY < touchStartCanvasPos[1] - touchTolerance) {\n                        this._touchState = WAITING_FOR_CORNER_TOUCH_START;\n                        return;\n                    }\n                    const pickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        pickSurface: true\n                    });\n                    if (pickResult && pickResult.worldPos) {\n                        this._currentAngleMeasurement.corner.worldPos = pickResult.worldPos;\n                        this._currentAngleMeasurement.originVisible = true;\n                        this._currentAngleMeasurement.originWireVisible = true;\n                        this._currentAngleMeasurement.cornerVisible = true;\n                        this._currentAngleMeasurement.cornerWireVisible = false;\n                        this._currentAngleMeasurement.targetVisible = false;\n                        this._currentAngleMeasurement.targetWireVisible = false;\n                        this._currentAngleMeasurement.angleVisible = false;\n                        this._touchState = WAITING_FOR_TARGET_TOUCH_START$1;\n                       // console.log(\"touchend: this._touchState= WAITING_FOR_CORNER_TOUCH_START -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    } else {\n                        if (this._currentAngleMeasurement) {\n                            this._currentAngleMeasurement.destroy();\n                            this._currentAngleMeasurement = null;\n                        }\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;\n                       // console.log(\"touchend: this._touchState= WAITING_FOR_CORNER_TOUCH_START -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    }\n\n                }\n                    enableCameraNavigation();\n                    break;\n\n                case WAITING_FOR_CORNER_LONG_TOUCH_END:\n                    if (this.pointerLens) {\n                        this.pointerLens.visible = false;\n                    }\n                    this._touchState = WAITING_FOR_TARGET_TOUCH_START$1;\n                  //  console.log(\"touchend: this._touchState= WAITING_FOR_CORNER_LONG_TOUCH_END  -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    enableCameraNavigation();\n                    break;\n\n                case WAITING_FOR_TARGET_QUICK_TOUCH_END$1: {\n                    if (numChangedTouches !== 1 ||\n                        touchX > touchStartCanvasPos[0] + touchTolerance ||\n                        touchX < touchStartCanvasPos[0] - touchTolerance ||\n                        touchY > touchStartCanvasPos[1] + touchTolerance ||\n                        touchY < touchStartCanvasPos[1] - touchTolerance) {\n                        this._touchState = WAITING_FOR_TARGET_TOUCH_START$1;\n                        return;\n                    }\n                    const pickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        pickSurface: true\n                    });\n                    if (pickResult && pickResult.worldPos) {\n                        this._currentAngleMeasurement.target.worldPos = pickResult.worldPos;\n                        this._currentAngleMeasurement.originVisible = true;\n                        this._currentAngleMeasurement.originWireVisible = true;\n                        this._currentAngleMeasurement.cornerVisible = true;\n                        this._currentAngleMeasurement.cornerWireVisible = true;\n                        this._currentAngleMeasurement.targetVisible = true;\n                        this._currentAngleMeasurement.targetWireVisible = true;\n                        this._currentAngleMeasurement.angleVisible = true;\n                        this.angleMeasurementsPlugin.fire(\"measurementEnd\", this._currentAngleMeasurement);\n                        this._currentAngleMeasurement = null;\n                    } else {\n                        if (this._currentAngleMeasurement) {\n                            this._currentAngleMeasurement.destroy();\n                            this._currentAngleMeasurement = null;\n                        }\n                    }\n                    this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;\n                   // console.log(\"touchend: this._touchState= WAITING_FOR_TARGET_TOUCH_START -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                }\n                    enableCameraNavigation();\n                    break;\n\n                case WAITING_FOR_TARGET_LONG_TOUCH_END$1:\n                    if (this.pointerLens) {\n                        this.pointerLens.visible = false;\n                    }\n                    if (!this._currentAngleMeasurement || !this._currentAngleMeasurement.targetVisible) {\n                        if (this._currentAngleMeasurement) {\n                            this._currentAngleMeasurement.destroy();\n                            this._currentAngleMeasurement = null;\n                        }\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;\n                       // console.log(\"touchend: this._touchState= WAITING_FOR_TARGET_LONG_TOUCH_END (no target found) -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    } else {\n                        this._currentAngleMeasurement.clickable = true;\n                        this.angleMeasurementsPlugin.fire(\"measurementEnd\", this._currentAngleMeasurement);\n                        this._currentAngleMeasurement = null;\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;\n                       // console.log(\"touchend: this._touchState= WAITING_FOR_TARGET_LONG_TOUCH_END  -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    }\n                    enableCameraNavigation();\n                    break;\n            }\n\n        }, {passive: true});\n\n        this._active = true;\n    }\n\n    /**\n     * Deactivates this AngleMeasurementsTouchControl, making it unresponsive to input.\n     *\n     * Destroys any {@link AngleMeasurement} under construction.\n     */\n    deactivate() {\n        if (!this._active) {\n            return;\n        }\n        if (this.plugin.pointerLens) {\n            this.plugin.pointerLens.visible = false;\n        }\n        this.reset();\n\n        const canvas = this.plugin.viewer.scene.canvas.canvas;\n        canvas.removeEventListener(\"touchstart\", this._onCanvasTouchStart);\n        canvas.removeEventListener(\"touchend\", this._onCanvasTouchEnd);\n\n        this._active = false;\n        this.plugin.viewer.cameraControl.active = true;\n    }\n\n    /**\n     * Resets this AngleMeasurementsTouchControl.\n     *\n     * Destroys any {@link AngleMeasurement} under construction.\n     *\n     * Does nothing if the AngleMeasurementsTouchControl is not active.\n     */\n    reset() {\n        if (!this._active) {\n            return;\n        }\n        if (this._currentAngleMeasurement) {\n            this.angleMeasurementsPlugin.fire(\"measurementCancel\", this._currentAngleMeasurement);\n            this._currentAngleMeasurement.destroy();\n            this._currentAngleMeasurement = null;\n        }\n    }\n\n    /**\n     * Gets the {@link AngleMeasurement} under construction by this AngleMeasurementsTouchControl, if any.\n     *\n     * @returns {null|AngleMeasurement}\n     */\n    get currentMeasurement() {\n        return this._currentAngleMeasurement;\n    }\n\n    /**\n     * Destroys this AngleMeasurementsTouchControl.\n     */\n    destroy() {\n        this.deactivate();\n        super.destroy();\n    }\n}\n\nclass AngleMeasurementEditControl extends Component {\n\n    /**\n     * Edits {@link AngleMeasurement} with mouse and/or touch input.\n     *\n     * @param {AngleMeasurement} [measurement] The AngleMeasurement to edit.\n     * @param [cfg] Configuration\n     * @param {PointerLens} [cfg.pointerLens] A PointerLens to use to provide a magnified view of the cursor.\n     * @param {boolean} [cfg.snapping] Whether to enable snap-to-vertex and snap-to-edge.\n     * @param {boolean} [handleMouseEvents] Whether to hangle mouse input.\n     * @param {boolean} [handleTouchEvents] Whether to hangle touch input.\n     */\n    constructor(measurement, cfg, handleMouseEvents, handleTouchEvents) {\n\n        const viewer = measurement.plugin.viewer;\n\n        super(viewer.scene);\n\n        const cleanup = activateDraggableDots({\n            viewer: viewer,\n            handleMouseEvents: handleMouseEvents,\n            handleTouchEvents: handleTouchEvents,\n            pointerLens: cfg.pointerLens,\n            dots: [ measurement.origin, measurement.corner, measurement.target ],\n            ray2WorldPos: (orig, dir, canvasPos) => {\n                const tryPickWorldPos = snap => {\n                    const pickResult = viewer.scene.pick({\n                        canvasPos: canvasPos,\n                        snapToEdge: snap,\n                        snapToVertex: snap,\n                        pickSurface: true  // <<------ This causes picking to find the intersection point on the entity\n                    });\n\n                    // If - when snapping - no pick found, then try w/o snapping\n                    return (pickResult && pickResult.worldPos) ? pickResult.worldPos : (snap && tryPickWorldPos(false));\n                };\n\n                return tryPickWorldPos(!!cfg.snapping);\n            },\n            onEnd: (initPos, dot) => {\n                const changed = ! math.compareVec3(initPos, dot.worldPos);\n                if (changed) {\n                    this.fire(\"edited\");\n                }\n                return changed;\n            }\n        });\n\n        const destroyCb = measurement.on(\"destroyed\", cleanup);\n\n        this._deactivate = function() {\n            measurement.off(\"destroyed\", destroyCb);\n            cleanup();\n        };\n    }\n\n    deactivate() {\n        this._deactivate();\n        super.destroy();\n    }\n}\n\nclass AngleMeasurementEditMouseControl extends AngleMeasurementEditControl {\n    constructor(zone, cfg) {\n        super(zone, cfg, true, false);\n    }\n}\n\nclass AngleMeasurementEditTouchControl extends AngleMeasurementEditControl {\n    constructor(zone, cfg) {\n        super(zone, cfg, false, true);\n    }\n}\n\nconst tempVec3a$6 = math.vec3();\nconst tempVec3b$3 = math.vec3();\nconst tempVec3c$2 = math.vec3();\n\nconst px = x => x + \"px\";\n\n/**\n * A {@link Marker} with an HTML label attached to it, managed by an {@link AnnotationsPlugin}.\n *\n * See {@link AnnotationsPlugin} for more info.\n */\nclass Annotation extends Marker {\n\n    /**\n     * @private\n     */\n    constructor(owner, cfg) {\n\n        super(owner, cfg);\n\n        /**\n         * The {@link AnnotationsPlugin} this Annotation was created by.\n         * @type {AnnotationsPlugin}\n         */\n        this.plugin = cfg.plugin;\n\n        this._container = cfg.container;\n        if (!this._container) {\n            throw \"config missing: container\";\n        }\n\n        if ((!cfg.markerElement) && (!cfg.markerHTML)) {\n            throw \"config missing: need either markerElement or markerHTML\";\n        }\n        if ((!cfg.labelElement) && (!cfg.labelHTML)) {\n            throw \"config missing: need either labelElement or labelHTML\";\n        }\n\n        this._htmlDirty = false;\n        this._curMarkerWidth = undefined;\n        this._curLabelWidth = 0;\n\n        if (cfg.markerElement) {\n            this._marker = cfg.markerElement;\n            this._marker.addEventListener(\"click\", this._onMouseClickedExternalMarker = () => {\n                this.plugin.fire(\"markerClicked\", this);\n            });\n            this._onContextMenuExternalMarker = () => {\n                this.plugin.fire(\"contextmenu\", this);\n            };\n            this._onContextMenuExternalMarkerRemover = addContextMenuListener(this._marker, this._onContextMenuExternalMarker);\n            this._marker.addEventListener(\"mouseenter\", this._onMouseEnterExternalMarker = () => {\n                this.plugin.fire(\"markerMouseEnter\", this);\n            });\n            this._marker.addEventListener(\"mouseleave\", this._onMouseLeaveExternalMarker = () => {\n                this.plugin.fire(\"markerMouseLeave\", this);\n            });\n            this._markerExternal = true; // Don't destroy marker when destroying Annotation\n        } else {\n            this._markerHTML = cfg.markerHTML;\n            this._htmlDirty = true;\n            this._markerExternal = false;\n        }\n\n        if (cfg.labelElement) {\n            this._label = cfg.labelElement;\n            this._labelExternal = true; // Don't destroy marker when destroying Annotation\n        } else {\n            this._labelHTML = cfg.labelHTML;\n            this._htmlDirty = true;\n            this._labelExternal = false;\n        }\n\n        this._markerShown = !!cfg.markerShown;\n        this._labelShown = !!cfg.labelShown;\n        this._values = cfg.values || {};\n        this._layoutDirty = true;\n        this._visibilityDirty = true;\n        this._labelPosition = 24;\n\n        this._buildHTML();\n\n        this._onTick = this.scene.on(\"tick\", () => {\n            if (this._htmlDirty) {\n                this._buildHTML();\n                this._htmlDirty = false;\n                this._layoutDirty = true;\n                this._visibilityDirty = true;\n            }\n            if (this._layoutDirty || this._visibilityDirty) {\n                if (this._markerShown || this._labelShown) {\n                    this._updatePosition();\n                    this._layoutDirty = false;\n                }\n            }\n            if (this._visibilityDirty) {\n                this._marker.style.visibility = (this.visible && this._markerShown) ? \"visible\" : \"hidden\";\n                this._label.style.visibility = (this.visible && this._markerShown && this._labelShown) ? \"visible\" : \"hidden\";\n                this._visibilityDirty = false;\n            }\n        });\n\n        this.on(\"canvasPos\", () => {\n            this._layoutDirty = true;\n        });\n\n        this.on(\"visible\", () => {\n            this._visibilityDirty = true;\n        });\n\n        this.setMarkerShown(cfg.markerShown !== false);\n        this.setLabelShown(cfg.labelShown);\n\n        /**\n         * Optional World-space position for {@link Camera#eye}, used when this Annotation is associated with a {@link Camera} position.\n         *\n         * Undefined by default.\n         *\n         * @type {Number[]} Eye position.\n         */\n        this.eye = cfg.eye ? cfg.eye.slice() : null;\n\n        /**\n         * Optional World-space position for {@link Camera#look}, used when this Annotation is associated with a {@link Camera} position.\n         *\n         * Undefined by default.\n         *\n         * @type {Number[]} The \"look\" vector.\n         */\n        this.look = cfg.look ? cfg.look.slice() : null;\n\n        /**\n         * Optional World-space position for {@link Camera#up}, used when this Annotation is associated with a {@link Camera} position.\n         *\n         * Undefined by default.\n         *\n         * @type {Number[]} The \"up\" vector.\n         */\n        this.up = cfg.up ? cfg.up.slice() : null;\n\n        /**\n         * Optional projection type for {@link Camera#projection}, used when this Annotation is associated with a {@link Camera} position.\n         *\n         * Undefined by default.\n         *\n         * @type {String} The projection type - \"perspective\" or \"ortho\"..\n         */\n        this.projection = cfg.projection;\n    }\n\n    /**\n     * @private\n     */\n    _buildHTML() {\n        if (!this._markerExternal) {\n            if (this._marker) {\n                this._container.removeChild(this._marker);\n                this._marker = null;\n            }\n            let markerHTML = this._markerHTML || \"<p></p>\"; // Make marker\n            if (utils.isArray(markerHTML)) {\n                markerHTML = markerHTML.join(\"\");\n            }\n            markerHTML = this._renderTemplate(markerHTML.trim());\n            const markerFragment = document.createRange().createContextualFragment(markerHTML);\n            this._marker = markerFragment.firstChild;\n            this._container.appendChild(this._marker);\n            this._marker.style.visibility = this._markerShown ? \"visible\" : \"hidden\";\n            this._marker.addEventListener(\"click\", () => {\n                this.plugin.fire(\"markerClicked\", this);\n            });\n            addContextMenuListener(this._marker, e => {\n                e.preventDefault();\n                this.plugin.fire(\"contextmenu\", this);\n            }, e => {\n                e.preventDefault();\n                this.plugin.fire(\"markerClicked\", this);\n            });\n            this._marker.addEventListener(\"mouseenter\", () => {\n                this.plugin.fire(\"markerMouseEnter\", this);\n            });\n            this._marker.addEventListener(\"mouseleave\", () => {\n                this.plugin.fire(\"markerMouseLeave\", this);\n            });\n            this._marker.addEventListener('wheel', (event) => {\n                this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new WheelEvent('wheel', event));\n            });\n        }\n        if (!this._labelExternal) {\n            if (this._label) {\n                this._container.removeChild(this._label);\n                this._label = null;\n            }\n            let labelHTML = this._labelHTML || \"<p></p>\"; // Make label\n            if (utils.isArray(labelHTML)) {\n                labelHTML = labelHTML.join(\"\");\n            }\n            labelHTML = this._renderTemplate(labelHTML.trim());\n            const labelFragment = document.createRange().createContextualFragment(labelHTML);\n            this._label = labelFragment.firstChild;\n            this._container.appendChild(this._label);\n            this._label.style.visibility = (this._markerShown && this._labelShown) ? \"visible\" : \"hidden\";\n            this._label.addEventListener('wheel', (event) => {\n                this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new WheelEvent('wheel', event));\n            });\n        }\n    }\n\n    /**\n     * @private\n     */\n    _updateWithCurWidths() {\n        const boundary = this.scene.canvas.boundary;\n        const left = boundary[0] + this.canvasPos[0];\n        const top  = boundary[1] + this.canvasPos[1];\n        this._marker.style.top = px(top - 12);\n        this._label.style.top  = px(top - 17);\n\n        if (this._markerAlign === \"legacy\") {\n            this._marker.style.left = px(left - 12);\n            this._label.style.left  = px(left + 40);\n        } else {\n            const markerWidth = this._curMarkerWidth;\n            const markerDir = (this._markerAlign === \"right\") ? -1 : ((this._markerAlign === \"center\") ? 0 : 1);\n            const markerCenter = left + markerDir * (markerWidth / 2 - 12);\n            this._marker.style.left = px(markerCenter - markerWidth / 2);\n\n            const labelWidth = this._curLabelWidth;\n            const labelDir = Math.sign(this._labelPosition);\n            this._label.style.left = px(markerCenter + labelDir * (markerWidth / 2 + Math.abs(this._labelPosition) + labelWidth / 2) - labelWidth / 2);\n        }\n\n        const zIndex = 90005 + Math.floor(this._viewPos[2]) + 1;\n        this._marker.style[\"z-index\"] = zIndex;\n        this._label.style[\"z-index\"]  = zIndex;\n    }\n\n    /**\n     * @private\n     */\n    _updateIfWidthsChanged() {\n        let needsUpdate = false;\n        const markerWidth = this._marker.getBoundingClientRect().width;\n        if (this._curMarkerWidth !== markerWidth) {\n            this._curMarkerWidth = markerWidth;\n            needsUpdate = true;\n        }\n        const labelDir = Math.sign(this._labelPosition);\n        // if (labelDir === 1) then don't perform relatively expensive label.getBoundingClientRect call\n        if (labelDir !== 1) {\n            const labelWidth = this._label.getBoundingClientRect().width;\n            if (this._curLabelWidth !== labelWidth) {\n                this._curLabelWidth = labelWidth;\n                needsUpdate = true;\n            }\n        }\n        if (needsUpdate) {\n            this._updateWithCurWidths();\n        }\n    }\n\n    /**\n     * @private\n     */\n    _updatePosition() {\n        const isLegacy = this._markerAlign === \"legacy\";\n        if ((! isLegacy) && (this._curMarkerWidth === undefined)) {\n            this._updateIfWidthsChanged();\n        } else {\n            // Update position with cached width values\n            // and postpone expensive Annotation's getBoundingClientRect calls\n            // so they don't interfere with e.g. interactive scene manipulation\n            this._updateWithCurWidths();\n            window.clearTimeout(this._widthTimeout);\n            if (! isLegacy) {\n                this._widthTimeout = window.setTimeout(() => this._updateIfWidthsChanged(), 500);\n            }\n        }\n    }\n\n    /**\n     * @private\n     */\n    _renderTemplate(template) {\n        for (var key in this._values) {\n            if (this._values.hasOwnProperty(key)) {\n                const value = this._values[key];\n                template = template.replace(new RegExp('{{' + key + '}}', 'g'), value);\n            }\n        }\n        return template;\n    }\n\n    /**\n     * Sets the Marker's worldPos and entity properties based on passed {@link PickResult}\n     *\n     * @param {PickResult} pickResult A PickResult to position the Marker at.\n     */\n    setFromPickResult(pickResult) {\n        if (!pickResult.worldPos || !pickResult.worldNormal) {\n            this.error(\"Param 'pickResult' does not have both worldPos and worldNormal\");\n        } else {\n            const normalizedWorldNormal = math.normalizeVec3(pickResult.worldNormal, tempVec3a$6);\n            const offset = (this.plugin && this.plugin.surfaceOffset) || 0;\n            const offsetVec = math.mulVec3Scalar(normalizedWorldNormal, offset, tempVec3b$3);\n            const offsetWorldPos = math.addVec3(pickResult.worldPos, offsetVec, tempVec3c$2);\n            this.entity = pickResult.entity;\n            this.worldPos = offsetWorldPos;\n        }\n    }\n\n    /**\n     * Sets the horizontal alignment of the Annotation's marker HTML.\n     *\n     * @param {String} align Either \"left\", \"center\", \"right\", \"legacy\" (default \"left\")\n     */\n    setMarkerAlign(align) {\n        const valid = [ \"left\", \"center\", \"right\", \"legacy\" ];\n        if (! valid.includes(align)) {\n            this.error(\"Param 'align' should be one of: \" + JSON.stringify(valid));\n        } else {\n            this._markerAlign = align;\n            this._updatePosition();\n        }\n    }\n\n    /**\n     * Sets the relative horizontal position of the Annotation's label HTML.\n     *\n     * @param {Number} position Negative - to the left, positive - to the right, otherwise ignore (default 24)\n     */\n    setLabelPosition(position) {\n        if (typeof position !== \"number\") {\n            this.error(\"Param 'position' is not a number\");\n        } else if (position === 0) {\n            this.error(\"Param 'position' is zero\");\n        } else {\n            this._labelPosition = position;\n            this._updatePosition();\n        }\n    }\n\n    /**\n     * Sets whether or not to show this Annotation's marker.\n     *\n     * The marker shows the Annotation's position.\n     *\n     * The marker is only visible when both this property and {@link Annotation#visible} are ````true````.\n     *\n     * See {@link AnnotationsPlugin} for more info.\n     *\n     * @param {Boolean} shown Whether to show the marker.\n     */\n    setMarkerShown(shown) {\n        shown = !!shown;\n        if (this._markerShown === shown) {\n            return;\n        }\n        this._markerShown = shown;\n        this._visibilityDirty = true;\n    }\n\n    /**\n     * Gets whether or not to show this Annotation's marker.\n     *\n     * The marker shows the Annotation's position.\n     *\n     * The marker is only visible when both this property and {@link Annotation#visible} are ````true````.\n     *\n     * See {@link AnnotationsPlugin} for more info.\n     *\n     * @returns {Boolean} Whether to show the marker.\n     */\n    getMarkerShown() {\n        return this._markerShown;\n    }\n\n    /**\n     * Sets whether or not to show this Annotation's label.\n     *\n     * The label is only visible when both this property and {@link Annotation#visible} are ````true````.\n     *\n     * See {@link AnnotationsPlugin} for more info.\n     *\n     * @param {Boolean} shown Whether to show the label.\n     */\n    setLabelShown(shown) {\n        shown = !!shown;\n        if (this._labelShown === shown) {\n            return;\n        }\n        this._labelShown = shown;\n        this._visibilityDirty = true;\n    }\n\n    /**\n     * Gets whether or not to show this Annotation's label.\n     *\n     * The label is only visible when both this property and {@link Annotation#visible} are ````true````.\n     *\n     * See {@link AnnotationsPlugin} for more info.\n     *\n     * @returns {Boolean} Whether to show the label.\n     */\n    getLabelShown() {\n        return this._labelShown;\n    }\n\n    /**\n     * Sets the value of a field within the HTML templates for either the Annotation's marker or label.\n     *\n     * See {@link AnnotationsPlugin} for more info.\n     *\n     * @param {String} key Identifies the field.\n     * @param {String} value The field's value.\n     */\n    setField(key, value) {\n        this._values[key] = value || \"\";\n        this._htmlDirty = true;\n    }\n\n    /**\n     * Gets the value of a field within the HTML templates for either the Annotation's marker or label.\n     *\n     * See {@link AnnotationsPlugin} for more info.\n     *\n     * @param {String} key Identifies the field.\n     * @returns {String} The field's value.\n     */\n    getField(key) {\n        return this._values[key];\n    }\n\n    /**\n     * Sets values for multiple placeholders within the Annotation's HTML templates for marker and label.\n     *\n     * See {@link AnnotationsPlugin} for more info.\n     *\n     * @param {{String:(String|Number)}} values Map of field values.\n     */\n    setValues(values) {\n        for (var key in values) {\n            if (values.hasOwnProperty(key)) {\n                const value = values[key];\n                this.setField(key, value);\n            }\n        }\n    }\n\n    /**\n     * Gets the values that were set for the placeholders within this Annotation's HTML marker and label templates.\n     *\n     * See {@link AnnotationsPlugin} for more info.\n     *\n     * @RETURNS {{String:(String|Number)}} Map of field values.\n     */\n    getValues() {\n        return this._values;\n    }\n\n    /**\n     * Destroys this Annotation.\n     *\n     * You can also call {@link AnnotationsPlugin#destroyAnnotation}.\n     */\n    destroy() {\n        window.clearTimeout(this._widthTimeout);\n        if (this._marker) {\n            if (!this._markerExternal) {\n                this._marker.parentNode.removeChild(this._marker);\n                this._marker = null;\n            } else {\n                this._marker.removeEventListener(\"click\", this._onMouseClickedExternalMarker);\n                this._onContextMenuExternalMarkerRemover();\n                this._marker.removeEventListener(\"mouseenter\", this._onMouseEnterExternalMarker);\n                this._marker.removeEventListener(\"mouseleave\", this._onMouseLeaveExternalMarker);\n                this._marker = null;\n            }\n        }\n        if (this._label) {\n            if (!this._labelExternal) {\n                this._label.parentNode.removeChild(this._label);\n            }\n            this._label = null;\n        }\n        this.scene.off(this._onTick);\n        super.destroy();\n    }\n}\n\n/**\n * {@link Viewer} plugin that creates {@link Annotation}s.\n *\n * [<img src=\"https://user-images.githubusercontent.com/83100/58403089-26589280-8062-11e9-8652-aed61a4e8c64.gif\">](https://xeokit.github.io/xeokit-sdk/examples/index.html#annotations_clickFlyToPosition)\n *\n * * [[Example 1: Create annotations with mouse](https://xeokit.github.io/xeokit-sdk/examples/index.html#annotations_createWithMouse)]\n * * [[Example 2: Click annotations to toggle labels](https://xeokit.github.io/xeokit-sdk/examples/index.html#annotations_clickShowLabels)]\n * * [[Example 3: Hover annotations to show labels](https://xeokit.github.io/xeokit-sdk/examples/index.html#annotations_hoverShowLabels)]\n * * [[Example 4: Click annotations to fly to viewpoint](https://xeokit.github.io/xeokit-sdk/examples/index.html#annotations_clickFlyToPosition)]\n * * [[Example 5: Create Annotations with externally-created elements](https://xeokit.github.io/xeokit-sdk/examples/index.html#annotations_externalElements)]\n *\n * ## Overview\n *\n * * An {@link Annotation} is a 3D position with a label attached.\n * * Annotations render themselves with HTML elements that float over the canvas; customize the appearance of\n * individual Annotations using HTML template; configure default appearance by setting templates on the AnnotationsPlugin.\n * * Dynamically insert data values into each Annotation's HTML templates; configure default values on the AnnotationsPlugin.\n * * Optionally configure Annotation with externally-created DOM elements for markers and labels; these override templates and data values.\n * * Optionally configure Annotations to hide themselves whenever occluded by {@link Entity}s.\n * * Optionally configure each Annotation with a position we can jump or fly the {@link Camera} to.\n *\n * ## Example 1: Loading a model and creating an annotation\n *\n * In the example below, we'll use an {@link XKTLoaderPlugin} to load a model, and an AnnotationsPlugin\n * to create an {@link Annotation} on it.\n *\n * We'll configure the AnnotationsPlugin with default HTML templates for each Annotation's position (its \"marker\") and\n * label, along with some default data values to insert into them.\n *\n * When we create our Annotation, we'll give it some specific data values to insert into the templates, overriding some of\n * the defaults we configured on the plugin. Note the correspondence between the placeholders in the templates\n * and the keys in the values map.\n *\n * We'll also configure the Annotation to hide itself whenever it's position is occluded by any {@link Entity}s (this is default behavior). The\n * {@link Scene} periodically occlusion-tests all Annotations on every 20th \"tick\" (which represents a rendered frame). We\n * can adjust that frequency via property {@link Scene#ticksPerOcclusionTest}.\n *\n * Finally, we'll query the Annotation's position occlusion/visibility status, and subscribe to change events on those properties.\n *\n * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#annotations_clickShowLabels)]\n *\n * ````JavaScript\n * import {Viewer, XKTLoaderPlugin,AnnotationsPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-2.37, 18.97, -26.12];\n * viewer.scene.camera.look = [10.97, 5.82, -11.22];\n * viewer.scene.camera.up = [0.36, 0.83, 0.40];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const annotations = new AnnotationsPlugin(viewer, {\n *\n *      // Default HTML template for marker position\n *      markerHTML: \"<div class='annotation-marker' style='background-color: {{markerBGColor}};'>{{glyph}}</div>\",\n *\n *      // Default HTML template for label\n *      labelHTML: \"<div class='annotation-label' style='background-color: {{labelBGColor}};'>\" +\n *      \"<div class='annotation-title'>{{title}}</div><div class='annotation-desc'>{{description}}</div></div>\",\n *\n *      // Default values to insert into the marker and label templates\n *      values: {\n *          markerBGColor: \"red\",\n *          labelBGColor: \"red\",\n *          glyph: \"X\",\n *          title: \"Untitled\",\n *          description: \"No description\"\n *      }\n * });\n *\n * const model = xktLoader.load({\n *      src: \"./models/xkt/duplex/geometry.xkt\"\n * });\n *\n * model.on(\"loaded\", () => {\n *\n *      const entity = viewer.scene.meshes[\"\"];\n *\n *      // Create an annotation\n *      const myAnnotation1 = annotations.createAnnotation({\n *\n *          id: \"myAnnotation\",\n *\n *          entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FLOH\"], // Optional, associate with an Entity\n *\n *          worldPos: [0, 0, 0],        // 3D World-space position\n *\n *          occludable: true,           // Optional, default, makes Annotation invisible when occluded by Entities\n *          markerShown: true,          // Optional, default is true, makes position visible (when not occluded)\n *          labelShown: true            // Optional, default is false, makes label visible (when not occluded)\n *\n *          values: {                   // Optional, overrides AnnotationPlugin's defaults\n *              glyph: \"A\",\n *              title: \"My Annotation\",\n *              description: \"This is my annotation.\"\n *          }\n *      });\n *\n *      // Listen for change of the Annotation's 3D World-space position\n *\n *      myAnnotation1.on(\"worldPos\", function(worldPos) {\n *          //...\n *      });\n *\n *      // Listen for change of the Annotation's 3D View-space position, which happens\n *      // when either worldPos was updated or the Camera was moved\n *\n *      myAnnotation1.on(\"viewPos\", function(viewPos) {\n *          //...\n *      });\n *\n *      // Listen for change of the Annotation's 2D Canvas-space position, which happens\n *      // when worldPos or viewPos was updated, or Camera's projection was updated\n *\n *      myAnnotation1.on(\"canvasPos\", function(canvasPos) {\n *          //...\n *      });\n *\n *      // Listen for change of Annotation visibility. The Annotation becomes invisible when it falls outside the canvas,\n *      // or its position is occluded by some Entity. Note that, when not occluded, the position is only\n *      // shown when Annotation#markerShown is true, and the label is only shown when Annotation#labelShown is true.\n *\n *      myAnnotation1.on(\"visible\", function(visible) { // Marker visibility has changed\n *          if (visible) {\n *              this.log(\"Annotation is visible\");\n *          } else {\n *              this.log(\"Annotation is invisible\");\n *          }\n *      });\n *\n *      // Listen for destruction of the Annotation\n *\n *      myAnnotation1.on(\"destroyed\", () => {\n *          //...\n *      });\n * });\n * ````\n *\n * Let's query our {@link Annotation}'s current position in the World, View and Canvas coordinate systems:\n *\n * ````javascript\n * const worldPos  = myAnnotation.worldPos;  // [x,y,z]\n * const viewPos   = myAnnotation.viewPos;   // [x,y,z]\n * const canvasPos = myAnnotation.canvasPos; // [x,y]\n * ````\n *\n * We can query it's current visibility, which is ````false```` when its position is occluded by some {@link Entity}:\n *\n * ````\n * const visible = myAnnotation1.visible;\n * ````\n *\n * To listen for change events on our Annotation's position and visibility:\n *\n * ````javascript\n * // World-space position changes when we assign a new value to Annotation#worldPos\n * myAnnotation1.on(\"worldPos\", (worldPos) => {\n *     //...\n * });\n *\n * // View-space position changes when either worldPos was updated or the Camera was moved\n * myAnnotation1.on(\"viewPos\", (viewPos) => {\n *     //...\n * });\n *\n * // Canvas-space position changes when worldPos or viewPos was updated, or Camera's projection was updated\n * myAnnotation1.on(\"canvasPos\", (canvasPos) => {\n *     //...\n * });\n *\n * // Annotation is invisible when its position falls off the canvas or is occluded by some Entity\n * myAnnotation1.on(\"visible\", (visible) => {\n *     //...\n * });\n * ````\n *\n * Finally, let's dynamically update the values for a couple of placeholders in our Annotation's label:\n *\n * ```` javascript\n * myAnnotation1.setValues({\n *      title: \"Here's a new title\",\n *      description: \"Here's a new description\"\n * });\n * ````\n *\n *\n * ## Example 2: Creating an Annotation with a unique appearance\n *\n * Now let's create a second {@link Annotation}, this time with its own custom HTML label template, which includes\n * an image. In the Annotation's values, we'll also provide a new title and description, custom colors for the marker\n * and label, plus a URL for the image in the label template. To render its marker, the Annotation will fall back\n * on the AnnotationPlugin's default marker template.\n *\n * ````javascript\n * const myAnnotation2 = annotations.createAnnotation({\n *\n *      id: \"myAnnotation2\",\n *\n *      worldPos: [-0.163, 1.810, 7.977],\n *\n *      occludable: true,\n *      markerShown: true,\n *      labelShown: true,\n *\n *      // Custom label template is the same as the Annotation's, with the addition of an image element\n *      labelHTML: \"<div class='annotation-label' style='background-color: {{labelBGColor}};'>\\\n *          <div class='annotation-title'>{{title}}</div>\\\n *          <div class='annotation-desc'>{{description}}</div>\\\n *          <br><img alt='myImage' width='150px' height='100px' src='{{imageSrc}}'>\\\n *          </div>\",\n *\n *      // Custom template values override all the AnnotationPlugin's defaults, and includes an additional value\n *      // for the image element's URL\n *      values: {\n *          glyph: \"A3\",\n *          title: \"The West wall\",\n *          description: \"Annotations can contain<br>custom HTML like this<br>image:\",\n *          markerBGColor: \"green\",\n *          labelBGColor: \"green\",\n *          imageSrc: \"https://xeokit.io/img/docs/BIMServerLoaderPlugin/schependomlaan.png\"\n *      }\n * });\n * ````\n *\n * ## Example 3: Creating an Annotation with a camera position\n *\n * We can optionally configure each {@link Annotation} with a position to fly or jump the {@link Camera} to.\n *\n * Let's create another Annotation, this time providing it with ````eye````, ````look```` and ````up```` properties\n * indicating a viewpoint on whatever it's annotating:\n *\n * ````javascript\n * const myAnnotation3 = annotations.createAnnotation({\n *\n *      id: \"myAnnotation3\",\n *\n *      worldPos: [-0.163, 3.810, 7.977],\n *\n *      eye: [0,0,-10],\n *      look: [-0.163, 3.810, 7.977],\n *      up: [0,1,0];\n *\n *      occludable: true,\n *      markerShown: true,\n *      labelShown: true,\n *\n *      labelHTML: \"<div class='annotation-label' style='background-color: {{labelBGColor}};'>\\\n *          <div class='annotation-title'>{{title}}</div>\\\n *          <div class='annotation-desc'>{{description}}</div>\\\n *          <br><img alt='myImage' width='150px' height='100px' src='{{imageSrc}}'>\\\n *          </div>\",\n *\n *      values: {\n *          glyph: \"A3\",\n *          title: \"The West wall\",\n *          description: \"Annotations can contain<br>custom HTML like this<br>image:\",\n *          markerBGColor: \"green\",\n *          labelBGColor: \"green\",\n *          imageSrc: \"https://xeokit.io/img/docs/BIMServerLoaderPlugin/schependomlaan.png\"\n *      }\n * });\n * ````\n *\n * Now we can fly the {@link Camera} to the Annotation's viewpoint, like this:\n *\n * ````javascript\n * viewer.cameraFlight.flyTo(myAnnotation3);\n * ````\n *\n * Or jump the Camera, like this:\n *\n * ````javascript\n * viewer.cameraFlight.jumpTo(myAnnotation3);\n * ````\n *\n * ## Example 4: Creating an Annotation using externally-created DOM elements\n *\n * Now let's create another {@link Annotation}, this time providing it with pre-existing DOM elements for its marker\n * and label. Note that AnnotationsPlugin will ignore any ````markerHTML````, ````labelHTML````\n * or ````values```` properties when provide  ````markerElementId```` or ````labelElementId````.\n *\n * ````javascript\n * const myAnnotation2 = annotations.createAnnotation({\n *\n *      id: \"myAnnotation2\",\n *\n *      worldPos: [-0.163, 1.810, 7.977],\n *\n *      occludable: true,\n *      markerShown: true,\n *      labelShown: true,\n *\n *      markerElementId: \"myMarkerElement\",\n *      labelElementId: \"myLabelElement\"\n * });\n * ````\n *\n * ## Example 5: Creating annotations by clicking on objects\n *\n * AnnotationsPlugin makes it easy to create {@link Annotation}s on the surfaces of {@link Entity}s as we click on them.\n *\n * The {@link AnnotationsPlugin#createAnnotation} method can accept a {@link PickResult} returned\n * by {@link Scene#pick}, from which it initializes the {@link Annotation}'s {@link Annotation#worldPos} and\n * {@link Annotation#entity}. Note that this only works when {@link Scene#pick} was configured to perform a 3D\n * surface-intersection pick (see {@link Scene#pick} for more info).\n *\n * Let's now extend our example to create an Annotation wherever we click on the surface of of our model:\n *\n * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#annotations_createWithMouse)]\n *\n * ````javascript\n * var i = 1; // Used to create unique Annotation IDs\n *\n * viewer.scene.input.on(\"mouseclicked\", (coords) => {\n *\n *     var pickRecord = viewer.scene.pick({\n *         canvasPos: coords,\n *         pickSurface: true  // <<------ This causes picking to find the intersection point on the entity\n *     });\n *\n *     if (pickRecord) {\n *\n *         const annotation = annotations.createAnnotation({\n *              id: \"myAnnotationOnClick\" + i,\n *              pickRecord: pickRecord,\n *              occludable: true,           // Optional, default is true\n *              markerShown: true,          // Optional, default is true\n *              labelShown: true,           // Optional, default is true\n *              values: {                   // HTML template values\n *                  glyph: \"A\" + i,\n *                  title: \"My annotation \" + i,\n *                  description: \"My description \" + i\n *              },\n           });\n *\n *         i++;\n *      }\n * });\n * ````\n *\n * Note that when the Annotation is occludable, there is potential for the {@link Annotation#worldPos} to become\n * visually embedded within the surface of its Entity when viewed from a distance. This happens as a result of limited\n * GPU accuracy GPU accuracy, especially when the near and far view-space clipping planes, specified by {@link Perspective#near}\n * and {@link Perspective#far}, or {@link Ortho#near} and {@link Perspective#far}, are far away from each other.\n *\n * To prevent this, we can offset Annotations from their Entity surfaces by an amount that we set\n * on {@link AnnotationsPlugin#surfaceOffset}:\n *\n * ````javascript\n * annotations.surfaceOffset = 0.3; // Default value\n * ````\n *\n * Annotations subsequently created with {@link AnnotationsPlugin#createAnnotation} using a {@link PickResult} will then\n * be offset by that amount.\n *\n * Another thing we can do to prevent this unwanted occlusion is keep the distance between the view-space clipping\n * planes to a minimum, which improves the accuracy of the Annotation occlusion test. In general, a good default\n * value for ````Perspective#far```` and ````Ortho#far```` is around ````2.000````.\n */\nclass AnnotationsPlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"Annotations\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {String} [cfg.markerHTML] HTML text template for Annotation markers. Defaults to ````<div></div>````. Ignored on {@link Annotation}s configured with a ````markerElementId````.\n     * @param {String} [cfg.labelHTML] HTML text template for Annotation labels. Defaults to ````<div></div>````.  Ignored on {@link Annotation}s configured with a ````labelElementId````.\n     * @param {HTMLElement} [cfg.container] Container DOM element for markers and labels. Defaults to ````document.body````.\n     * @param {{String:(String|Number)}} [cfg.values={}] Map of default values to insert into the HTML templates for the marker and label.\n     * @param {Number}  [cfg.surfaceOffset=0.3] The amount by which each {@link Annotation} is offset from the surface of\n     * its {@link Entity} when we create the Annotation by supplying a {@link PickResult} to {@link AnnotationsPlugin#createAnnotation}.\n     */\n    constructor(viewer, cfg) {\n\n        super(\"Annotations\", viewer);\n\n        this._labelHTML = cfg.labelHTML || \"<div></div>\";\n        this._markerHTML = cfg.markerHTML || \"<div></div>\";\n        this._container = cfg.container || document.body;\n        this._values = cfg.values || {};\n\n        /**\n         * The {@link Annotation}s created by {@link AnnotationsPlugin#createAnnotation}, each mapped to its {@link Annotation#id}.\n         * @type {{String:Annotation}}\n         */\n        this.annotations = {};\n\n        this.surfaceOffset = cfg.surfaceOffset;\n    }\n\n    /**\n     * Gets the plugin's HTML container element, if any.\n     * @returns {*|HTMLElement|HTMLElement}\n     */\n    getContainerElement() {\n        return this._container;\n    }\n\n    /**\n     * @private\n     */\n    send(name, value) {\n        switch (name) {\n            case \"clearAnnotations\":\n                this.clear();\n                break;\n        }\n    }\n\n    /**\n     * Sets the amount by which each {@link Annotation} is offset from the surface of its {@link Entity}, when we\n     * create the Annotation by supplying a {@link PickResult} to {@link AnnotationsPlugin#createAnnotation}.\n     *\n     * See the class comments for more info.\n     *\n     * This is ````0.3```` by default.\n     *\n     * @param {Number} surfaceOffset The surface offset.\n     */\n    set surfaceOffset(surfaceOffset) {\n        if (surfaceOffset === undefined || surfaceOffset === null) {\n            surfaceOffset = 0.3;\n        }\n        this._surfaceOffset = surfaceOffset;\n    }\n\n    /**\n     * Gets the amount by which an {@link Annotation} is offset from the surface of its {@link Entity} when\n     * created by {@link AnnotationsPlugin#createAnnotation}, when we\n     * create the Annotation by supplying a {@link PickResult} to {@link AnnotationsPlugin#createAnnotation}.\n     *\n     * This is ````0.3```` by default.\n     *\n     * @returns {Number} The surface offset.\n     */\n    get surfaceOffset() {\n        return this._surfaceOffset;\n    }\n\n    /**\n     * Creates an {@link Annotation}.\n     *\n     * The Annotation is then registered by {@link Annotation#id} in {@link AnnotationsPlugin#annotations}.\n     *\n     * @param {Object} params Annotation configuration.\n     * @param {String} params.id Unique ID to assign to {@link Annotation#id}. The Annotation will be registered by this in {@link AnnotationsPlugin#annotations} and {@link Scene.components}. Must be unique among all components in the {@link Viewer}.\n     * @param {String} [params.markerElementId] ID of pre-existing DOM element to render the marker. This overrides ````markerHTML```` and does not support ````values```` (data is baked into the label DOM element).\n     * @param {String} [params.labelElementId] ID of pre-existing DOM element to render the label. This overrides ````labelHTML```` and does not support ````values```` (data is baked into the label DOM element).\n     * @param {String} [params.markerHTML] HTML text template for the Annotation marker. Defaults to the marker HTML given to the AnnotationsPlugin constructor. Ignored if you provide ````markerElementId````.\n     * @param {String} [params.labelHTML] HTML text template for the Annotation label. Defaults to the label HTML given to the AnnotationsPlugin constructor. Ignored if you provide ````labelElementId````.\n     * @param {Number[]} [params.worldPos=[0,0,0]] World-space position of the Annotation marker, assigned to {@link Annotation#worldPos}.\n     * @param {Entity} [params.entity] Optional {@link Entity} to associate the Annotation with. Causes {@link Annotation#visible} to be ````false```` whenever {@link Entity#visible} is also ````false````.\n     * @param {PickResult} [params.pickResult] Sets the Annotation's World-space position and direction vector from the given {@link PickResult}'s {@link PickResult#worldPos} and {@link PickResult#worldNormal}, and the Annotation's Entity from {@link PickResult#entity}. Causes ````worldPos```` and ````entity```` parameters to be ignored, if they are also given.\n     * @param {Boolean} [params.occludable=false] Indicates whether or not the {@link Annotation} marker and label are hidden whenever the marker occluded by {@link Entity}s in the {@link Scene}. The\n     * {@link Scene} periodically occlusion-tests all Annotations on every 20th \"tick\" (which represents a rendered frame). We can adjust that frequency via property {@link Scene#ticksPerOcclusionTest}.\n     * @param  {{String:(String|Number)}} [params.values={}] Map of values to insert into the HTML templates for the marker and label. These will be inserted in addition to any values given to the AnnotationsPlugin constructor.\n     * @param {Boolean} [params.markerShown=true] Whether to initially show the {@link Annotation} marker.\n     * @param {Boolean} [params.labelShown=false] Whether to initially show the {@link Annotation} label.\n     * @param {Number[]} [params.eye] Optional World-space position for {@link Camera#eye}, used when this Annotation is associated with a {@link Camera} position.\n     * @param {Number[]} [params.look] Optional World-space position for {@link Camera#look}, used when this Annotation is associated with a {@link Camera} position.\n     * @param {Number[]} [params.up] Optional World-space position for {@link Camera#up}, used when this Annotation is associated with a {@link Camera} position.\n     * @param {String} [params.projection] Optional projection type for {@link Camera#projection}, used when this Annotation is associated with a {@link Camera} position.\n     * @returns {Annotation} The new {@link Annotation}.\n     */\n    createAnnotation(params) {\n        if (this.viewer.scene.components[params.id]) {\n            this.error(\"Viewer component with this ID already exists: \" + params.id);\n            delete params.id;\n        }\n\n        var markerElement = null;\n        if (params.markerElementId) {\n            markerElement = document.getElementById(params.markerElementId);\n            if (!markerElement) {\n                this.error(\"Can't find DOM element for 'markerElementId' value '\" + params.markerElementId + \"' - defaulting to internally-generated empty DIV\");\n            }\n        }\n\n        var labelElement = null;\n        if (params.labelElementId) {\n            labelElement = document.getElementById(params.labelElementId);\n            if (!labelElement) {\n                this.error(\"Can't find DOM element for 'labelElementId' value '\" + params.labelElementId + \"' - defaulting to internally-generated empty DIV\");\n            }\n        }\n\n        const annotation = new Annotation(this.viewer.scene, {\n            id: params.id,\n            plugin: this,\n            container: this._container,\n            markerElement: markerElement,\n            labelElement: labelElement,\n            markerHTML: params.markerHTML || this._markerHTML,\n            labelHTML: params.labelHTML || this._labelHTML,\n            occludable: params.occludable,\n            values: utils.apply(params.values, utils.apply(this._values, {})),\n            markerShown: params.markerShown,\n            labelShown: params.labelShown,\n            eye: params.eye,\n            look: params.look,\n            up: params.up,\n            projection: params.projection,\n            visible: (params.visible !== false)\n        });\n\n        params.pickResult = params.pickResult || params.pickRecord;\n        if (params.pickResult) {\n            annotation.setFromPickResult(params.pickResult);\n        } else {\n            annotation.entity = params.entity;\n            annotation.worldPos = params.worldPos;\n        }\n\n        this.annotations[annotation.id] = annotation;\n        annotation.on(\"destroyed\", () => {\n            delete this.annotations[annotation.id];\n            this.fire(\"annotationDestroyed\", annotation.id);\n        });\n        this.fire(\"annotationCreated\", annotation.id);\n        return annotation;\n    }\n\n    /**\n     * Destroys an {@link Annotation}.\n     *\n     * @param {String} id ID of Annotation to destroy.\n     */\n    destroyAnnotation(id) {\n        var annotation = this.annotations[id];\n        if (!annotation) {\n            this.log(\"Annotation not found: \" + id);\n            return;\n        }\n        annotation.destroy();\n    }\n\n    /**\n     * Destroys all {@link Annotation}s.\n     */\n    clear() {\n        const ids = Object.keys(this.annotations);\n        for (var i = 0, len = ids.length; i < len; i++) {\n            this.destroyAnnotation(ids[i]);\n        }\n    }\n\n    /**\n     * Destroys this AnnotationsPlugin.\n     *\n     * Destroys all {@link Annotation}s first.\n     */\n    destroy() {\n        this.clear();\n        super.destroy();\n    }\n}\n\n/**\n * {@link Viewer} plugin that shows the axii of the World-space coordinate system.\n *\n * ## Usage\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#gizmos_AxisGizmoPlugin)]\n *\n * ````JavaScript````\n * import {Viewer, XKTLoaderPlugin, AxisGizmoPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [-2.56, 8.38, 8.27];\n * viewer.camera.look = [13.44, 3.31, -14.83];\n * viewer.camera.up = [0.10, 0.98, -0.14];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * new AxisGizmoPlugin(viewer, {\n *     canvasId: \"myAxisGizmoCanvas\"\n * });\n *\n * const model = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"../assets/models/xkt/Schependomlaan.xkt\",\n *     edges: true\n * });\n * ````\n */\nclass AxisGizmoPlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"AxisGizmo\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {String} [cfg.canvasId] ID of an existing HTML canvas to display the AxisGizmo - either this or canvasElement is mandatory. When both values are given, the element reference is always preferred to the ID.\n     * @param {HTMLCanvasElement} [cfg.canvasElement] Reference of an existing HTML canvas to display the AxisGizmo - either this or canvasId is mandatory. When both values are given, the element reference is always preferred to the ID.\n     */\n    constructor(viewer, cfg) {\n\n        cfg = cfg || {};\n\n        super(\"AxisGizmo\", viewer, cfg);\n\n        const camera = viewer.scene.camera;\n\n        if (!cfg.canvasId && !cfg.canvasElement) {\n            this.error(\"Config expected: either 'canvasId' or 'canvasElement'\");\n        }\n\n        try {\n            this._axisGizmoScene = new Scene(viewer, {\n                canvasId: cfg.canvasId,\n                canvasElement: cfg.canvasElement,\n                transparent: true\n            });\n        } catch (error) {\n            this.error(error);\n            return;\n        }\n\n        const axisGizmoScene = this._axisGizmoScene;\n\n        axisGizmoScene.clearLights();\n\n        new AmbientLight(axisGizmoScene, {color: [0.45, 0.45, 0.5], intensity: 0.9});\n        new DirLight(axisGizmoScene, {dir: [-0.5, 0.5, -0.6], color: [0.8, 0.8, 0.7], intensity: 1.0, space: \"view\"});\n        new DirLight(axisGizmoScene, {dir: [0.5, -0.5, -0.6], color: [0.8, 0.8, 0.8], intensity: 1.0, space: \"view\"});\n\n        // Rotate helper in synch with target camera\n\n        const helperCamera = axisGizmoScene.camera;\n\n        camera.on(\"matrix\", function () {\n\n            const eye = camera.eye;\n            const look = camera.look;\n            const up = camera.up;\n\n            const eyeLook = math.mulVec3Scalar(math.normalizeVec3(math.subVec3(eye, look, [])), 22);\n\n            helperCamera.look = [0, 0, 0];\n            helperCamera.eye = eyeLook;\n            helperCamera.up = up;\n        });\n\n        // ----------------- Components that are shared among more than one mesh ---------------\n\n        const arrowHead = new ReadableGeometry(axisGizmoScene, buildCylinderGeometry({\n            radiusTop: 0.01,\n            radiusBottom: 0.6,\n            height: 1.7,\n            radialSegments: 20,\n            heightSegments: 1,\n            openEnded: false\n        }));\n\n        const arrowShaft = new ReadableGeometry(axisGizmoScene, buildCylinderGeometry({\n            radiusTop: 0.2,\n            radiusBottom: 0.2,\n            height: 4.5,\n            radialSegments: 20,\n            heightSegments: 1,\n            openEnded: false\n        }));\n\n        const xAxisMaterial = new PhongMaterial(axisGizmoScene, { // Red by convention\n            diffuse: [1, 0.3, 0.3],\n            ambient: [0.0, 0.0, 0.0],\n            specular: [.6, .6, .3],\n            shininess: 80,\n            lineWidth: 2\n        });\n\n        const xAxisLabelMaterial = new PhongMaterial(axisGizmoScene, { // Red by convention\n            emissive: [1, 0.3, 0.3],\n            ambient: [0.0, 0.0, 0.0],\n            specular: [.6, .6, .3],\n            shininess: 80,\n            lineWidth: 2\n        });\n\n        const yAxisMaterial = new PhongMaterial(axisGizmoScene, { // Green by convention\n            diffuse: [0.3, 1, 0.3],\n            ambient: [0.0, 0.0, 0.0],\n            specular: [.6, .6, .3],\n            shininess: 80,\n            lineWidth: 2\n        });\n\n        const yAxisLabelMaterial = new PhongMaterial(axisGizmoScene, { // Green by convention\n            emissive: [0.3, 1, 0.3],\n            ambient: [0.0, 0.0, 0.0],\n            specular: [.6, .6, .3],\n            shininess: 80,\n            lineWidth: 2\n        });\n\n        const zAxisMaterial = new PhongMaterial(axisGizmoScene, { // Blue by convention\n            diffuse: [0.3, 0.3, 1],\n            ambient: [0.0, 0.0, 0.0],\n            specular: [.6, .6, .3],\n            shininess: 80,\n            lineWidth: 2\n        });\n\n        const zAxisLabelMaterial = new PhongMaterial(axisGizmoScene, {\n            emissive: [0.3, 0.3, 1],\n            ambient: [0.0, 0.0, 0.0],\n            specular: [.6, .6, .3],\n            shininess: 80,\n            lineWidth: 2\n        });\n\n        const ballMaterial = new PhongMaterial(axisGizmoScene, {\n            diffuse: [0.5, 0.5, 0.5],\n            ambient: [0.0, 0.0, 0.0],\n            specular: [.6, .6, .3],\n            shininess: 80,\n            lineWidth: 2\n        });\n\n        // ----------------- Meshes ------------------------------\n\n        this._meshes = [\n\n            // Sphere behind gnomon\n\n            new Mesh(axisGizmoScene, {\n                geometry: new ReadableGeometry(axisGizmoScene, buildSphereGeometry({\n                    radius: 9.0,\n                    heightSegments: 60,\n                    widthSegments: 60\n                })),\n                material: new PhongMaterial(axisGizmoScene, {\n                    diffuse: [0.0, 0.0, 0.0],\n                    emissive: [0.1, 0.1, 0.1],\n                    ambient: [0.1, 0.1, 0.2],\n                    specular: [0, 0, 0],\n                    alpha: 0.4,\n                    alphaMode: \"blend\",\n                    frontface: \"cw\"\n                }),\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false\n            }),\n\n            // Ball at center of axis\n\n            new Mesh(axisGizmoScene, {  // Arrow\n                geometry: new ReadableGeometry(axisGizmoScene, buildSphereGeometry({\n                    radius: 1.0\n                })),\n                material: ballMaterial,\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false\n            }),\n\n            // X-axis arrow, shaft and label\n\n            new Mesh(axisGizmoScene, {  // Arrow\n                geometry: arrowHead,\n                material: xAxisMaterial,\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false,\n                position: [5, 0, 0],\n                rotation: [0, 0, -90]\n            }),\n\n            new Mesh(axisGizmoScene, {  // Shaft\n                geometry: arrowShaft,\n                material: xAxisMaterial,\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false,\n                position: [2, 0, 0],\n                rotation: [0, 0, 90]\n            }),\n\n            new Mesh(axisGizmoScene, {  // Label\n                geometry: new ReadableGeometry(axisGizmoScene, buildVectorTextGeometry({text: \"X\", size: 1.5})),\n                material: xAxisLabelMaterial,\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false,\n                position: [7, 0, 0],\n                billboard: \"spherical\"\n            }),\n\n            // Y-axis arrow, shaft and label\n\n            new Mesh(axisGizmoScene, {  // Arrow\n                geometry: arrowHead,\n                material: yAxisMaterial,\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false,\n                position: [0, 5, 0]\n            }),\n\n            new Mesh(axisGizmoScene, {  // Shaft\n                geometry: arrowShaft,\n                material: yAxisMaterial,\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false,\n                position: [0, 2, 0]\n            }),\n\n            new Mesh(axisGizmoScene, {  // Label\n                geometry: new ReadableGeometry(axisGizmoScene, buildVectorTextGeometry({text: \"Y\", size: 1.5})),\n                material: yAxisLabelMaterial,\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false,\n                position: [0, 7, 0],\n                billboard: \"spherical\"\n            }),\n\n            // Z-axis arrow, shaft and label\n\n            new Mesh(axisGizmoScene, {  // Arrow\n                geometry: arrowHead,\n                material: zAxisMaterial,\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false,\n                position: [0, 0, 5],\n                rotation: [90, 0, 0]\n            }),\n\n            new Mesh(axisGizmoScene, {  // Shaft\n                geometry: arrowShaft,\n                material: zAxisMaterial,\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false,\n                position: [0, 0, 2],\n                rotation: [90, 0, 0]\n            }),\n\n            new Mesh(axisGizmoScene, {  // Label\n                geometry: new ReadableGeometry(axisGizmoScene, buildVectorTextGeometry({text: \"Z\", size: 1.5})),\n                material: zAxisLabelMaterial,\n                pickable: false,\n                collidable: false,\n                visible: cfg.visible !== false,\n                position: [0, 0, 7],\n                billboard: \"spherical\"\n            })\n        ];\n    }\n\n    /** Shows or hides this AxisGizmoPlugin.\n     *\n     * @param visible\n     */\n    setVisible(visible) {\n        for (let i = 0; i < this._meshes.length; i++) {\n            this._meshes[i].visible = visible;\n        }\n    }\n\n    /**\n     * Destroys this AxisGizmoPlugin.\n     */\n    destroy() {\n        this._axisGizmoCanvas = null;\n        this._axisGizmoScene.destroy();\n        this._axisGizmoScene = null;\n        super.destroy();\n    }\n}\n\nconst tempVec3$2 = math.vec3();\nconst tempVec3a$5 = math.vec3();\nconst tempVec3b$2 = math.vec3();\nconst tempVec3c$1 = math.vec3();\n\n/**\n * {@link Viewer} plugin that saves and loads BCF viewpoints as JSON objects.\n *\n * [<img src=\"http://xeokit.github.io/xeokit-sdk/assets/images/BCFViewpointsPlugin.png\">](/examples/index.html#BCF_SaveViewpoint)\n *\n * * [[Example 1: Saving viewer state to a BCF viewpoint](https://xeokit.github.io/xeokit-sdk/examples/index.html#BCF_SaveViewpoint)]\n * * [[Example 2: Loading viewer state from a BCF viewpoint](https://xeokit.github.io/xeokit-sdk/examples/index.html#BCF_LoadViewpoint)]\n *\n * ## Overview\n *\n * BCF is an open standard that enables workflow communications between BIM software tools. An XML schema, called\n * Building Collaboration Format (BCF), encodes messages that inform one BIM tool of issues found by another.\n *\n * A BCF viewpoint captures a viewpoint of a model that highlights an issue. The viewpoint can then be loaded by another\n * viewer to examine the issue.\n *\n * Using this plugin, a xeokit {@link Viewer} can exchange BCF-encoded viewpoints with other BIM software,\n * allowing us to use the Viewer to report and view issues in BIM models.\n *\n * This plugin's viewpoints conform to the <a href=\"https://github.com/buildingSMART/BCF-API\">BCF Version 2.1</a> specification.\n *\n * ## Supported BCF Elements\n *\n * BCFViewpointsPlugin saves and loads the following state in BCF viewpoints:\n *\n * * {@link Camera} position, orientation and projection\n * * {@link Entity} visibilities and selection states\n * * {@link SectionPlane}s to slice the model\n * * {@link LineSet}s to show 3D lines\n * * {@link Bitmap}s to show images\n *\n * ## Saving a BCF Viewpoint\n *\n * In the example below we'll create a {@link Viewer}, load an ````.XKT```` model into it using an {@link XKTLoaderPlugin},\n * slice the model in half using a {@link SectionPlanesPlugin}, create a grid ground plane using a {@link LineSet} and a 2D\n * plan view using a {@link Bitmap}, then use a {@link BCFViewpointsPlugin#getViewpoint}\n * to save a viewpoint to JSON, which we'll log to the JavaScript developer console.\n *\n * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#BCF_SaveViewpoint)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, SectionPlanesPlugin,\n *      LineSet, Bitmap, buildGridGeometry, BCFViewpointsPlugin} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * // Set camera position and orientation\n * viewer.scene.camera.eye = [-48.93, 54.54, 50.41];\n * viewer.scene.camera.look = [0.55, -0.61, -0.55];\n * viewer.scene.camera.up = [0, -1, 0];\n * viewer.scene.camera.perspective.fov = 60;\n *\n * // Add a XKTLoaderPlugin\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * // Add a SectionPlanesPlugin\n * const sectionPlanes = new SectionPlanesPlugin(viewer);\n *\n * // Add a BCFViewpointsPlugin\n * const bcfViewpoints = new BCFViewpointsPlugin(viewer);\n *\n * // Load an .XKT model\n * const modelNode = xktLoader.load({\n *      id: \"myModel\",\n *      src: \"./models/xkt/Schependomlaan.xkt\",\n *      edges: true // Emphasise edges\n * });\n *\n * // Slice it in half\n * sectionPlanes.createSectionPlane({\n *      id: \"myClip\",\n *      pos: [0, 0, 0],\n *      dir: [0.5, 0.0, 0.5]\n * });\n *\n * // Create a bitmap\n * const bitmap = new Bitmap(viewer.scene, {\n *     src: \"../assets/images/schependomlaanPlanView.png\",\n *      visible: true,\n *      height: 24.0,\n *      pos: [-15, 0, -10],\n *      normal: [0, -1, 0],\n *      up: [0, 0, 1],\n *      collidable: false,\n *      opacity: 1.0,\n *      clippable: false,\n *      pickable: true\n *  });\n *\n * // Create a grid ground plane\n * const geometryArrays = buildGridGeometry({\n *      size: 60,\n *      divisions: 10\n *  });\n *\n * new LineSet(viewer.scene, {\n *      positions: geometryArrays.positions,\n *      indices: geometryArrays.indices,\n *      position: [10,0,10],\n *      clippable: false\n *  });\n *\n * // When model is loaded, select some objects and capture a BCF viewpoint to the console\n * modelNode.on(\"loaded\", () => {\n *\n *      const scene = viewer.scene;\n *\n *      scene.setObjectsSelected([\n *          \"3b2U496P5Ebhz5FROhTwFH\",\n *          \"2MGtJUm9nD$Re1_MDIv0g2\",\n *          \"3IbuwYOm5EV9Q6cXmwVWqd\",\n *          \"3lhisrBxL8xgLCRdxNG$2v\",\n *          \"1uDn0xT8LBkP15zQc9MVDW\"\n *      ], true);\n *\n *      const viewpoint = bcfViewpoints.getViewpoint();\n *      const viewpointStr = JSON.stringify(viewpoint, null, 4);\n *\n *      console.log(viewpointStr);\n * });\n * ````\n *\n * The saved BCF viewpoint would look something like below. Note that some elements are truncated for brevity.\n *\n * ````json\n * {\n *      \"perspective_camera\": {\n *          \"camera_view_point\": { \"x\": -48.93, \"y\": 54.54, \"z\": 50.41 },\n *          \"camera_direction\": { \"x\": 0.55, \"y\": -0.61, \"z\": -0.55},\n *          \"camera_up_vector\": { \"x\": 0.37, \"y\": -0.41, \"z\": 0.83 },\n *          \"field_of_view\": 60.0\n *      },\n *      \"lines\": [{\n *          \"start_point\": { \"x\": 1.0, \"y\": 1.0, \"z\": 1.0 },\n *          \"end_point\": { \"x\": 0.0, \"y\": 0.0, \"z\": 0.0 },\n *          //...(truncated)\n *      }],\n *      \"bitmaps\": [{\n *          \"bitmap_type\": \"png\",\n *          \"bitmap_data\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB9AAAAdp...\", //...(truncated)\n *          \"location\": { \"x\": -15, \"y\": 10, \"z\": 0 },\n *          \"normal\": { \"x\": 0, \"y\": 0, \"z\": -1 },\n *          \"up\": { \"x\": 0, \"y\": -1, \"z\": 0 },\n *          \"height\": 24\n *      }],\n *      \"clipping_planes\": [{\n *          \"location\": { \"x\": 0.0, \"y\": 0.0, \"z\": 0.0 },\n *          \"direction\": { \"x\": 0.5, \"y\": 0.0, \"z\": 0.5 }\n *      }],\n *      \"snapshot\": {\n *          \"snapshot_type\": \"png\",\n *          \"snapshot_data\": \"data:image/png;base64,......\"\n *      },\n *      \"components\": {\n *          \"visibility\": {\n *              \"default_visibility\": false,\n *              \"exceptions\": [{\n *                      \"ifc_guid\": \"4$cshxZO9AJBebsni$z9Yk\",\n *                      \"originating_system\": \"xeokit.io\",\n *                      \"authoring_tool_id\": \"xeokit/v3.2\"\n *                  },\n *                  //...\n *              ]\n *          },\n *          \"selection\": [{\n *                  \"ifc_guid\": \"4$cshxZO9AJBebsni$z9Yk\",\n *              },\n *              //...\n *          ]\n *      }\n * }\n * ````\n *\n * ## Saving View Setup Hints\n *\n * BCFViewpointsPlugin can optionally save hints in the viewpoint, which indicate how to set up the view when\n * loading it again.\n *\n * Here's the {@link BCFViewpointsPlugin#getViewpoint} call again, this time saving some hints:\n *\n * ````javascript\n * const viewpoint = bcfViewpoints.getViewpoint({ // Options\n *     spacesVisible: true, // Force IfcSpace types visible in the viewpoint (default is false)\n *     spaceBoundariesVisible: false, // Show IfcSpace boundaries in the viewpoint (default is false)\n *     openingsVisible: true // Force IfcOpening types visible in the viewpoint (default is false)\n * });\n * ````\n *\n * ## Loading a BCF Viewpoint\n *\n * Assuming that we have our BCF viewpoint in a JSON object, let's now restore it with {@link BCFViewpointsPlugin#setViewpoint}:\n *\n * ````javascript\n * bcfViewpoints.setViewpoint(viewpoint);\n * ````\n *\n * ## Handling BCF Incompatibility with xeokit's Camera\n *\n * xeokit's {@link Camera#look} is the current 3D *point-of-interest* (POI).\n *\n * A BCF viewpoint, however, has a direction vector instead of a POI, and so {@link BCFViewpointsPlugin#getViewpoint} saves\n * xeokit's POI as a normalized vector from {@link Camera#eye} to {@link Camera#look}, which unfortunately loses\n * that positional information. Loading the viewpoint with {@link BCFViewpointsPlugin#setViewpoint} will restore {@link Camera#look} to\n * the viewpoint's camera position, offset by the normalized vector.\n *\n * As shown below, providing a ````rayCast```` option to ````setViewpoint```` will set {@link Camera#look} to the closest\n * surface intersection on the direction vector. Internally, ````setViewpoint```` supports this option by firing a ray\n * along the vector, and if that hits an {@link Entity}, sets {@link Camera#look} to ray's intersection point with the\n * Entity's surface.\n *\n * ````javascript\n * bcfViewpoints.setViewpoint(viewpoint, {\n *      rayCast: true // <<--------------- Attempt to set Camera#look to surface intersection point (default)\n * });\n * ````\n *\n * ## Dealing With Loaded Models that are not in the Viewpoint\n *\n * If, for example, we load model \"duplex\", hide some objects, then save a BCF viewpoint with\n * ````BCFViewpointsPlugin#getViewpoint````, then load another model, \"schependomlaan\", then load the viewpoint again\n * with ````BCFViewpointsPlugin#setViewpoint````, then sometimes all of the objects in model \"schependomlaan\" become\n * visible, along with the visible objects in the viewpoint, which belong to model \"duplex\".\n *\n * The reason is that, when saving a BCF viewpoint, BCF logic works like the following pseudo code:\n *\n * ````\n * If numVisibleObjects < numInvisibleObjects\n *      save IDs of visible objects in BCF\n *      exceptions = \"visible objects\"\n * else\n *      save IDS of invisible objects in BCF\n *      exceptions = \"invisible objects\"\n * ````\n *\n * When loading the viewpoint again:\n *\n * ````\n * If exceptions = \"visible objects\"\n *      hide all objects\n *      show visible objects in BCF\n * else\n *      show all objects\n *      hide invisible objects in BCF\n * ````\n *\n * When the exception is \"visible objects\", loading the viewpoint shows all the objects in the first, which includes\n * objects in \"schependomlaan\", which can be confusing, because those were not even loaded when we first\n * saved the viewpoint..\n *\n * To solve this, we can supply a ````defaultInvisible```` option to {@link BCFViewpointsPlugin#getViewpoint}, which\n * will force the plugin to save the IDs of all visible objects while making invisible objects the exception.\n *\n * That way, when we load the viewpoint again, after loading model \"schependomlaan\", the plugin will hide all objects\n * in the scene first (which will include objects belonging to model \"schependomlaan\"), then make the objects in the\n * viewpoint visible (which will only be those of object \"duplex\").\n *\n * ````javascript\n * const viewpoint = bcfViewpoints.getViewpoint({ // Options\n *     //..\n *     defaultInvisible: true\n * });\n * ````\n *\n * [[Run an example](/examples/index.html#BCF_LoadViewpoint_defaultInvisible)]\n *\n * ## Behaviour with XKTLoaderPlugin globalizeObjectIds\n *\n * Whenever we use {@link XKTLoaderPlugin} to load duplicate copies of the same model, after configuring\n * {@link XKTLoaderPlugin#globalizeObjectIds} ````true```` to avoid ````Entity```` ID clashes, this has consequences\n * for BCF viewpoints created by {@link BCFViewpointsPlugin#getViewpoint}.\n *\n * When no duplicate copies of a model are loaded like this, viewpoints created by {@link BCFViewpointsPlugin#getViewpoint} will\n * continue to load as usual in other BIM viewers. Conversely, a viewpoint created for a single model in other BIM viewers\n * will continue to load as usual with ````BCFViewpointsPlugin````.\n *\n * When duplicate copies of a model are loaded, however, viewpoints created by {@link BCFViewpointsPlugin#getViewpoint}\n * will contain certain changes that will affect the viewpoint's portability, however. Such viewpoints will\n * use ````authoring_tool_id```` fields to save the globalized ````Entity#id```` values, which enables the viewpoints to\n * capture the states of the individual ````Entitys```` that represent the duplicate IFC elements. Take a look at the\n * following two examples to learn more.\n *\n * * [Example: Saving a BCF viewpoint containing duplicate models](https://xeokit.github.io/xeokit-sdk/examples/index.html#BCF_SaveViewpoint_MultipleModels)\n * * [Example: Loading a BCF viewpoint containing duplicate models](https://xeokit.github.io/xeokit-sdk/examples/index.html#BCF_LoadViewpoint_MultipleModels)\n *\n * **Caveat:** when loading a BCF viewpoint, we always assume that we have loaded in our target BIM viewer the same models that were\n * loaded in the viewpoint's original authoring application when the viewpoint was created.  In the case of multi-model\n * viewpoints, the target BIM viewer, whether it be xeokit or another BIM viewer, will need to first have those exact\n * models loaded, with their objects having globalized IDs, following the same prefixing scheme we're using in\n * xeokit. Then, the viewpoint's ````authoring_tool_id```` fields will be able to resolve to their objects within the\n * target viewer.\n *\n * @class BCFViewpointsPlugin\n */\nclass BCFViewpointsPlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"BCFViewpoints\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {String} [cfg.originatingSystem] Identifies the originating system for BCF records.\n     * @param {String} [cfg.authoringTool] Identifies the authoring tool for BCF records.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"BCFViewpoints\", viewer, cfg);\n\n        /**\n         * Identifies the originating system to include in BCF viewpoints saved by this plugin.\n         * @property originatingSystem\n         * @type {string}\n         */\n        this.originatingSystem = cfg.originatingSystem || \"xeokit.io\";\n\n        /**\n         * Identifies the authoring tool to include in BCF viewpoints saved by this plugin.\n         * @property authoringTool\n         * @type {string}\n         */\n        this.authoringTool = cfg.authoringTool || \"xeokit.io\";\n    }\n\n    /**\n     * Saves viewer state to a BCF viewpoint.\n     *\n     * See ````BCFViewpointsPlugin```` class comments for more info.\n     *\n     * @param {*} [options] Options for getting the viewpoint.\n     * @param {Boolean} [options.spacesVisible=false] Indicates whether ````IfcSpace```` types should be forced visible in the viewpoint.\n     * @param {Boolean} [options.openingsVisible=false] Indicates whether ````IfcOpening```` types should be forced visible in the viewpoint.\n     * @param {Boolean} [options.spaceBoundariesVisible=false] Indicates whether the boundaries of ````IfcSpace```` types should be visible in the viewpoint.\n     * @param {Boolean} [options.spacesTranslucent=false] Indicates whether ````IfcSpace```` types should be forced translucent in the viewpoint.\n     * @param {Boolean} [options.spaceBoundariesTranslucent=false] Indicates whether the boundaries of ````IfcSpace```` types should be forced translucent in the viewpoint.\n     * @param {Boolean} [options.openingsTranslucent=true] Indicates whether ````IfcOpening```` types should be forced translucent in the viewpoint.\n     * @param {Boolean} [options.snapshot=true] Indicates whether the snapshot should be included in the viewpoint.\n     * @param {Boolean} [options.defaultInvisible=false] When ````true````, will save the default visibility of all objects\n     * as ````false````. This means that when we load the viewpoint again, and there are additional models loaded that\n     * were not saved in the viewpoint, those models will be hidden when we load the viewpoint, and that only the\n     * objects in the viewpoint will be visible.\n     * @param {Boolean} [options.reverseClippingPlanes=false] When ````true````, clipping planes are reversed (https://github.com/buildingSMART/BCF-XML/issues/193)\n     * @returns {*} BCF JSON viewpoint object\n     */\n    getViewpoint(options = {}) {\n        const scene = this.viewer.scene;\n        const camera = scene.camera;\n        const realWorldOffset = scene.realWorldOffset;\n        const reverseClippingPlanes = (options.reverseClippingPlanes === true);\n        let bcfViewpoint = {};\n\n        // Camera\n        let lookDirection = math.normalizeVec3(math.subVec3(camera.look, camera.eye, math.vec3()));\n        let eye = camera.eye;\n        let up = camera.up;\n\n        if (camera.yUp) {\n            // BCF is Z up\n            lookDirection = YToZ(lookDirection);\n            eye = YToZ(eye);\n            up = YToZ(up);\n        }\n\n        const camera_view_point = xyzArrayToObject(math.addVec3(eye, realWorldOffset));\n\n        if (camera.projection === \"ortho\") {\n            bcfViewpoint.orthogonal_camera = {\n                camera_view_point: camera_view_point,\n                camera_direction: xyzArrayToObject(lookDirection),\n                camera_up_vector: xyzArrayToObject(up),\n                view_to_world_scale: camera.ortho.scale,\n            };\n        } else {\n            bcfViewpoint.perspective_camera = {\n                camera_view_point: camera_view_point,\n                camera_direction: xyzArrayToObject(lookDirection),\n                camera_up_vector: xyzArrayToObject(up),\n                field_of_view: camera.perspective.fov,\n            };\n        }\n\n        // Section planes\n\n        const sectionPlanes = scene.sectionPlanes;\n        for (let id in sectionPlanes) {\n            if (sectionPlanes.hasOwnProperty(id)) {\n                let sectionPlane = sectionPlanes[id];\n                if (!sectionPlane.active) {\n                    continue;\n                }\n                let location = sectionPlane.pos;\n\n                let direction;\n                if (reverseClippingPlanes) {\n                    direction = math.negateVec3(sectionPlane.dir, math.vec3());\n                } else {\n                    direction = sectionPlane.dir;\n                }\n\n                if (camera.yUp) {\n                    // BCF is Z up\n                    location = YToZ(location);\n                    direction = YToZ(direction);\n                }\n                math.addVec3(location, realWorldOffset);\n\n                location = xyzArrayToObject(location);\n                direction = xyzArrayToObject(direction);\n                if (!bcfViewpoint.clipping_planes) {\n                    bcfViewpoint.clipping_planes = [];\n                }\n                bcfViewpoint.clipping_planes.push({location, direction});\n            }\n        }\n\n        // Lines\n\n        const lineSets = scene.lineSets;\n        for (let id in lineSets) {\n            if (lineSets.hasOwnProperty(id)) {\n                const lineSet = lineSets[id];\n                if (!bcfViewpoint.lines) {\n                    bcfViewpoint.lines = [];\n                }\n                const positions = lineSet.positions;\n                const indices = lineSet.indices;\n                for (let i = 0, len = indices.length / 2; i < len; i++) {\n                    const a = indices[i * 2];\n                    const b = indices[(i * 2) + 1];\n                    bcfViewpoint.lines.push({\n                        start_point: {\n                            x: positions[a * 3 + 0],\n                            y: positions[a * 3 + 1],\n                            z: positions[a * 3 + 2]\n                        },\n                        end_point: {\n                            x: positions[b * 3 + 0],\n                            y: positions[b * 3 + 1],\n                            z: positions[b * 3 + 2]\n                        }\n                    });\n                }\n\n            }\n        }\n\n        // Bitmaps\n\n        const bitmaps = scene.bitmaps;\n        for (let id in bitmaps) {\n            if (bitmaps.hasOwnProperty(id)) {\n                let bitmap = bitmaps[id];\n                let location = bitmap.pos;\n                let normal = bitmap.normal;\n                let up = bitmap.up;\n                if (camera.yUp) {\n                    // BCF is Z up\n                    location = YToZ(location);\n                    normal = YToZ(normal);\n                    up = YToZ(up);\n                }\n                math.addVec3(location, realWorldOffset);\n                if (!bcfViewpoint.bitmaps) {\n                    bcfViewpoint.bitmaps = [];\n                }\n                bcfViewpoint.bitmaps.push({\n                    bitmap_type: bitmap.type,\n                    bitmap_data: bitmap.imageData,\n                    location: xyzArrayToObject(location),\n                    normal: xyzArrayToObject(normal),\n                    up: xyzArrayToObject(up),\n                    height: bitmap.height\n                });\n            }\n        }\n\n        // Entity states\n\n        bcfViewpoint.components = {\n            visibility: {\n                view_setup_hints: {\n                    spaces_visible: !!options.spacesVisible,\n                    space_boundaries_visible: !!options.spaceBoundariesVisible,\n                    openings_visible: !!options.openingsVisible,\n                    spaces_translucent: !!options.spaces_translucent,\n                    space_boundaries_translucent: !!options.space_boundaries_translucent,\n                    openings_translucent: !!options.openings_translucent\n                }\n            }\n        };\n\n        const opacityObjectIds = new Set(scene.opacityObjectIds);\n        const xrayedObjectIds = new Set(scene.xrayedObjectIds);\n        const colorizedObjectIds = new Set(scene.colorizedObjectIds);\n\n        const coloringMap = Object.values(scene.objects)\n            .filter(entity => opacityObjectIds.has(entity.id) || colorizedObjectIds.has(entity.id) || xrayedObjectIds.has(entity.id))\n            .reduce((coloringMap, entity) => {\n\n                let color = colorizeToRGB(entity.colorize);\n                let alpha;\n\n                if (entity.xrayed) {\n                    if (scene.xrayMaterial.fillAlpha === 0.0 && scene.xrayMaterial.edgeAlpha !== 0.0) {\n                        // BCF can't deal with edges. If xRay is implemented only with edges, set an arbitrary opacity\n                        alpha = 0.1;\n                    } else {\n                        alpha = scene.xrayMaterial.fillAlpha;\n                    }\n                    alpha = Math.round(alpha * 255).toString(16).padStart(2, \"0\");\n                    color = alpha + color;\n                } else if (opacityObjectIds.has(entity.id)) {\n                    alpha = Math.round(entity.opacity * 255).toString(16).padStart(2, \"0\");\n                    color = alpha + color;\n                }\n\n                if (!coloringMap[color]) {\n                    coloringMap[color] = [];\n                }\n\n                const objectId = entity.id;\n                const originalSystemId = entity.originalSystemId;\n                const component = {\n                    ifc_guid: originalSystemId,\n                    originating_system: this.originatingSystem\n                };\n                if (originalSystemId !== objectId) {\n                    component.authoring_tool_id = objectId;\n                }\n\n                coloringMap[color].push(component);\n\n                return coloringMap;\n\n            }, {});\n\n        const coloringArray = Object.entries(coloringMap).map(([color, components]) => {\n            return {color, components};\n        });\n\n        bcfViewpoint.components.coloring = coloringArray;\n\n        const objectIds = scene.objectIds;\n        const visibleObjects = scene.visibleObjects;\n        const visibleObjectIds = scene.visibleObjectIds;\n        const invisibleObjectIds = objectIds.filter(id => !visibleObjects[id]);\n        const selectedObjectIds = scene.selectedObjectIds;\n\n        if (options.defaultInvisible || visibleObjectIds.length < invisibleObjectIds.length) {\n            bcfViewpoint.components.visibility.exceptions = this._createBCFComponents(visibleObjectIds);\n            bcfViewpoint.components.visibility.default_visibility = false;\n        } else {\n            bcfViewpoint.components.visibility.exceptions = this._createBCFComponents(invisibleObjectIds);\n            bcfViewpoint.components.visibility.default_visibility = true;\n        }\n\n        bcfViewpoint.components.selection = this._createBCFComponents(selectedObjectIds);\n\n        bcfViewpoint.components.translucency = this._createBCFComponents(scene.xrayedObjectIds);\n\n        if (options.snapshot !== false) {\n            bcfViewpoint.snapshot = {\n                snapshot_type: \"png\",\n                snapshot_data: this.viewer.getSnapshot({format: \"png\"})\n            };\n        }\n\n        return bcfViewpoint;\n    }\n\n    _createBCFComponents(objectIds) {\n        const scene = this.viewer.scene;\n        const components = [];\n        for (let i = 0, len = objectIds.length; i < len; i++) {\n            const objectId = objectIds[i];\n            const entity = scene.objects[objectId];\n            if (entity) {\n                const component = {\n                    ifc_guid: entity.originalSystemId,\n                    originating_system: this.originatingSystem\n                };\n                if (entity.originalSystemId !== objectId) {\n                    component.authoring_tool_id = objectId;\n                }\n                components.push(component);\n            }\n        }\n        return components;\n    }\n\n    /**\n     * Sets viewer state to the given BCF viewpoint.\n     *\n     * Note that xeokit's {@link Camera#look} is the **point-of-interest**, whereas the BCF ````camera_direction```` is a\n     * direction vector. Therefore, when loading a BCF viewpoint, we set {@link Camera#look} to the absolute position\n     * obtained by offsetting the BCF ````camera_view_point````  along ````camera_direction````.\n     *\n     * When loading a viewpoint, we also have the option to find {@link Camera#look} as the closest point of intersection\n     * (on the surface of any visible and pickable {@link Entity}) with a 3D ray fired from ````camera_view_point```` in\n     * the direction of ````camera_direction````.\n     *\n     * @param {*} bcfViewpoint  BCF JSON viewpoint object,\n     * shows default visible entities and restores camera to initial default position.\n     * @param {*} [options] Options for setting the viewpoint.\n     * @param {Boolean} [options.rayCast=true] When ````true```` (default), will attempt to set {@link Camera#look} to the closest\n     * point of surface intersection with a ray fired from the BCF ````camera_view_point```` in the direction of ````camera_direction````.\n     * @param {Boolean} [options.immediate=true] When ````true```` (default), immediately set camera position.\n     * @param {Boolean} [options.duration] Flight duration in seconds.  Overrides {@link CameraFlightAnimation#duration}. Only applies when ````immediate```` is ````false````.\n     * @param {Boolean} [options.reset=true] When ````true```` (default), set {@link Entity#xrayed} and {@link Entity#highlighted} ````false```` on all scene objects.\n     * @param {Boolean} [options.reverseClippingPlanes=false] When ````true````, clipping planes are reversed (https://github.com/buildingSMART/BCF-XML/issues/193)\n     * @param {Boolean} [options.updateCompositeObjects=false] When ````true````, then when visibility and selection updates refer to composite objects (eg. an IfcBuildingStorey),\n     * then this method will apply the updates to objects within those composites.\n     */\n    setViewpoint(bcfViewpoint, options = {}) {\n        if (!bcfViewpoint) {\n            return;\n        }\n\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const camera = scene.camera;\n        const rayCast = (options.rayCast !== false);\n        const immediate = (options.immediate !== false);\n        const reset = (options.reset !== false);\n        const realWorldOffset = scene.realWorldOffset;\n        const reverseClippingPlanes = (options.reverseClippingPlanes === true);\n\n        scene.clearSectionPlanes();\n\n        if (bcfViewpoint.clipping_planes && bcfViewpoint.clipping_planes.length > 0) {\n            bcfViewpoint.clipping_planes.forEach(function (e) {\n                let pos = xyzObjectToArray(e.location, tempVec3$2);\n                let dir = xyzObjectToArray(e.direction, tempVec3$2);\n\n                if (reverseClippingPlanes) {\n                    math.negateVec3(dir);\n                }\n                math.subVec3(pos, realWorldOffset);\n\n                if (camera.yUp) {\n                    pos = ZToY(pos);\n                    dir = ZToY(dir);\n                }\n                new SectionPlane(scene, {pos, dir});\n            });\n        }\n\n        scene.clearLines();\n\n        if (bcfViewpoint.lines && bcfViewpoint.lines.length > 0) {\n            const positions = [];\n            const indices = [];\n            let i = 0;\n            bcfViewpoint.lines.forEach((e) => {\n                if (!e.start_point) {\n                    return;\n                }\n                if (!e.end_point) {\n                    return;\n                }\n                positions.push(e.start_point.x);\n                positions.push(e.start_point.y);\n                positions.push(e.start_point.z);\n                positions.push(e.end_point.x);\n                positions.push(e.end_point.y);\n                positions.push(e.end_point.z);\n                indices.push(i++);\n                indices.push(i++);\n            });\n            new LineSet(scene, {\n                positions,\n                indices,\n                clippable: false,\n                collidable: true\n            });\n        }\n\n        scene.clearBitmaps();\n\n        if (bcfViewpoint.bitmaps && bcfViewpoint.bitmaps.length > 0) {\n            bcfViewpoint.bitmaps.forEach(function (e) {\n                const bitmap_type = e.bitmap_type || \"jpg\"; // \"jpg\" | \"png\"\n                const bitmap_data = e.bitmap_data; // base64\n                let location = xyzObjectToArray(e.location, tempVec3a$5);\n                let normal = xyzObjectToArray(e.normal, tempVec3b$2);\n                let up = xyzObjectToArray(e.up, tempVec3c$1);\n                let height = e.height || 1;\n                if (!bitmap_type) {\n                    return;\n                }\n                if (!bitmap_data) {\n                    return;\n                }\n                if (!location) {\n                    return;\n                }\n                if (!normal) {\n                    return;\n                }\n                if (!up) {\n                    return;\n                }\n                if (camera.yUp) {\n                    location = ZToY(location);\n                    normal = ZToY(normal);\n                    up = ZToY(up);\n                }\n                new Bitmap(scene, {\n                    src: bitmap_data,\n                    type: bitmap_type,\n                    pos: location,\n                    normal: normal,\n                    up: up,\n                    clippable: false,\n                    collidable: true,\n                    height\n                });\n            });\n        }\n\n        if (reset) {\n            scene.setObjectsXRayed(scene.xrayedObjectIds, false);\n            scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n            scene.setObjectsSelected(scene.selectedObjectIds, false);\n        }\n\n        if (bcfViewpoint.components) {\n\n            if (bcfViewpoint.components.visibility) {\n\n                if (!bcfViewpoint.components.visibility.default_visibility) {\n                    scene.setObjectsVisible(scene.objectIds, false);\n                    if (bcfViewpoint.components.visibility.exceptions) {\n                        bcfViewpoint.components.visibility.exceptions.forEach((component) => this._withBCFComponent(options, component, entity => entity.visible = true));\n                    }\n                } else {\n                    scene.setObjectsVisible(scene.objectIds, true);\n                    if (bcfViewpoint.components.visibility.exceptions) {\n                        bcfViewpoint.components.visibility.exceptions.forEach((component) => this._withBCFComponent(options, component, entity => entity.visible = false));\n                    }\n                }\n\n                const view_setup_hints = bcfViewpoint.components.visibility.view_setup_hints;\n                if (view_setup_hints) {\n                    if (view_setup_hints.spaces_visible === false) {\n                        scene.setObjectsVisible(viewer.metaScene.getObjectIDsByType(\"IfcSpace\"), false);\n                    }\n                    if (view_setup_hints.spaces_translucent !== undefined) {\n                        scene.setObjectsXRayed(viewer.metaScene.getObjectIDsByType(\"IfcSpace\"), true);\n                    }\n                    if (view_setup_hints.space_boundaries_visible !== undefined) ;\n                    if (view_setup_hints.openings_visible === false) {\n                        scene.setObjectsVisible(viewer.metaScene.getObjectIDsByType(\"IfcOpening\"), true);\n                    }\n                    if (view_setup_hints.space_boundaries_translucent !== undefined) ;\n                    if (view_setup_hints.openings_translucent !== undefined) {\n                        scene.setObjectsXRayed(viewer.metaScene.getObjectIDsByType(\"IfcOpening\"), true);\n                    }\n                }\n            }\n\n            if (bcfViewpoint.components.selection) {\n                scene.setObjectsSelected(scene.selectedObjectIds, false);\n                bcfViewpoint.components.selection.forEach(component => this._withBCFComponent(options, component, entity => entity.selected = true));\n\n            }\n\n            if (bcfViewpoint.components.translucency) {\n                scene.setObjectsXRayed(scene.xrayedObjectIds, false);\n                bcfViewpoint.components.translucency.forEach(component => this._withBCFComponent(options, component, entity => entity.xrayed = true));\n            }\n\n            if (bcfViewpoint.components.coloring) {\n                scene.setObjectsColorized(scene.colorizedObjectIds, null);\n                bcfViewpoint.components.coloring.forEach(coloring => {\n\n                    let color = coloring.color;\n                    let alpha = 0;\n                    let alphaDefined = false;\n\n                    if (color.length === 8) {\n                        alpha = parseInt(color.substring(0, 2), 16) / 255;\n                        if (alpha <= 1.0 && alpha >= 0.95) {\n                            alpha = 1.0;\n                        }\n                        color = color.substring(2);\n                        alphaDefined = true;\n                    }\n\n                    const colorize = [\n                        parseInt(color.substring(0, 2), 16) / 255,\n                        parseInt(color.substring(2, 4), 16) / 255,\n                        parseInt(color.substring(4, 6), 16) / 255\n                    ];\n\n                    coloring.components.map(component =>\n                        this._withBCFComponent(options, component, entity => {\n                            entity.colorize = colorize;\n                            if (alphaDefined) {\n                                entity.opacity = alpha;\n                            }\n                        }));\n                });\n            }\n        }\n\n        if (bcfViewpoint.perspective_camera || bcfViewpoint.orthogonal_camera) {\n            let eye;\n            let look;\n            let up;\n            let projection;\n\n            if (bcfViewpoint.perspective_camera) {\n                eye = xyzObjectToArray(bcfViewpoint.perspective_camera.camera_view_point, tempVec3$2);\n                look = xyzObjectToArray(bcfViewpoint.perspective_camera.camera_direction, tempVec3$2);\n                up = xyzObjectToArray(bcfViewpoint.perspective_camera.camera_up_vector, tempVec3$2);\n\n                camera.perspective.fov = bcfViewpoint.perspective_camera.field_of_view;\n\n                projection = \"perspective\";\n            } else {\n                eye = xyzObjectToArray(bcfViewpoint.orthogonal_camera.camera_view_point, tempVec3$2);\n                look = xyzObjectToArray(bcfViewpoint.orthogonal_camera.camera_direction, tempVec3$2);\n                up = xyzObjectToArray(bcfViewpoint.orthogonal_camera.camera_up_vector, tempVec3$2);\n\n                camera.ortho.scale = bcfViewpoint.orthogonal_camera.view_to_world_scale;\n\n                projection = \"ortho\";\n            }\n\n            math.subVec3(eye, realWorldOffset);\n\n            if (camera.yUp) {\n                eye = ZToY(eye);\n                look = ZToY(look);\n                up = ZToY(up);\n            }\n\n            if (rayCast) {\n                const hit = scene.pick({\n                    pickSurface: true,  // <<------ This causes picking to find the intersection point on the entity\n                    origin: eye,\n                    direction: look\n                });\n                look = (hit ? hit.worldPos : math.addVec3(eye, look, tempVec3$2));\n            } else {\n                look = math.addVec3(eye, look, tempVec3$2);\n            }\n\n            if (immediate) {\n                camera.eye = eye;\n                camera.look = look;\n                camera.up = up;\n                camera.projection = projection;\n            } else {\n                viewer.cameraFlight.flyTo({eye, look, up, duration: options.duration, projection});\n            }\n        }\n    }\n\n    _withBCFComponent(options, component, callback) {\n\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n\n        if (component.authoring_tool_id && component.originating_system === this.originatingSystem) {\n\n            const id = component.authoring_tool_id;\n            const entity = scene.objects[id];\n\n            if (entity) {\n                callback(entity);\n                return\n            }\n\n            if (options.updateCompositeObjects) {\n                const metaObject = viewer.metaScene.metaObjects[id];\n                if (metaObject) {\n                    scene.withObjects(viewer.metaScene.getObjectIDsInSubtree(id), callback);\n                    return;\n                }\n            }\n        }\n\n        if (component.ifc_guid) {\n\n            const originalSystemId = component.ifc_guid;\n            const entity = scene.objects[originalSystemId];\n\n            if (entity) {\n                callback(entity);\n                return;\n            }\n\n            if (options.updateCompositeObjects) {\n                const metaObject = viewer.metaScene.metaObjects[originalSystemId];\n                if (metaObject) {\n                    scene.withObjects(viewer.metaScene.getObjectIDsInSubtree(originalSystemId), callback);\n                    return;\n                }\n            }\n\n            Object.keys(scene.models).forEach((modelId) => {\n\n                const id = math.globalizeObjectId(modelId, originalSystemId);\n                const entity = scene.objects[id];\n\n                if (entity) {\n                    callback(entity);\n                    return;\n                }\n\n                if (options.updateCompositeObjects) {\n                    const metaObject = viewer.metaScene.metaObjects[id];\n                    if (metaObject) {\n                        scene.withObjects(viewer.metaScene.getObjectIDsInSubtree(id), callback);\n\n                    }\n                }\n            });\n        }\n    }\n\n    /**\n     * Destroys this BCFViewpointsPlugin.\n     */\n    destroy() {\n        super.destroy();\n    }\n}\n\nfunction xyzArrayToObject(arr) {\n    return {\"x\": arr[0], \"y\": arr[1], \"z\": arr[2]};\n}\n\nfunction xyzObjectToArray(xyz, arry) {\n    arry = new Float64Array(3);\n    arry[0] = xyz.x;\n    arry[1] = xyz.y;\n    arry[2] = xyz.z;\n    return arry;\n}\n\nfunction YToZ(vec) {\n    return new Float64Array([vec[0], -vec[2], vec[1]]);\n}\n\nfunction ZToY(vec) {\n    return new Float64Array([vec[0], vec[2], -vec[1]]);\n}\n\nfunction colorizeToRGB(color) {\n    let rgb = \"\";\n    rgb += Math.round(color[0] * 255).toString(16).padStart(2, \"0\");\n    rgb += Math.round(color[1] * 255).toString(16).padStart(2, \"0\");\n    rgb += Math.round(color[2] * 255).toString(16).padStart(2, \"0\");\n    return rgb;\n}\n\nconst tmpVec3a = math.vec3();\nconst tmpVec3b = math.vec3();\nconst tmpVec3c = math.vec3();\nmath.vec4();\nmath.vec4();\nmath.vec4();\n\n/**\n * @desc Measures the distance between two 3D points.\n *\n * See {@link DistanceMeasurementsPlugin} for more info.\n */\nclass DistanceMeasurement extends Component {\n\n    /**\n     * @private\n     */\n    constructor(plugin, cfg = {}) {\n\n        const scene = plugin.viewer.scene;\n\n        super(scene, cfg);\n\n        /**\n         * The {@link DistanceMeasurementsPlugin} that owns this DistanceMeasurement.\n         * @type {DistanceMeasurementsPlugin}\n         */\n        this.plugin = plugin;\n\n        const container = cfg.container;\n        if (!container) {\n            throw \"config missing: container\";\n        }\n\n        this._color = cfg.color || plugin.defaultColor;\n\n        const channel = function(v, defaultIfUndefined) {\n            const listeners = [ ];\n            let value = v !== undefined ? Boolean(v) : defaultIfUndefined;\n            return {\n                reg: (l) => listeners.push(l),\n                get: () => value,\n                set: (v) => {\n                    value = v !== undefined ? Boolean(v) : defaultIfUndefined;\n                    listeners.forEach(l => l(value));\n                }\n            };\n        };\n\n        this._visible               = channel(cfg.visible,               plugin.defaultVisible);\n        this._originVisible         = channel(cfg.originVisible,         plugin.defaultOriginVisible);\n        this._targetVisible         = channel(cfg.targetVisible,         plugin.defaultTargetVisible);\n        this._axisVisible           = channel(cfg.axisVisible,           plugin.defaultAxisVisible);\n        this._xAxisVisible          = channel(cfg.xAxisVisible,          plugin.defaultAxisVisible);\n        this._yAxisVisible          = channel(cfg.yAxisVisible,          plugin.defaultAxisVisible);\n        this._zAxisVisible          = channel(cfg.zAxisVisible,          plugin.defaultAxisVisible);\n        this._axisEnabled           = channel(true,                      plugin.defaultAxisVisible);\n        this._wireVisible           = channel(cfg.wireVisible,           plugin.defaultWireVisible);\n        this._xLabelEnabled         = channel(cfg.xLabelEnabled,         plugin.defaultXLabelEnabled);\n        this._yLabelEnabled         = channel(cfg.yLabelEnabled,         plugin.defaultYLabelEnabled);\n        this._zLabelEnabled         = channel(cfg.zLabelEnabled,         plugin.defaultZLabelEnabled);\n        this._lengthLabelEnabled    = channel(cfg.lengthLabelEnabled,    plugin.defaultLengthLabelEnabled);\n        this._labelsVisible         = channel(cfg.labelsVisible,         plugin.defaultLabelsVisible);\n        this._clickable             = channel(false,                     false);\n        this._labelsOnWires         = channel(cfg.labelsOnWires,         plugin.defaultLabelsOnWires);\n        this._useRotationAdjustment = channel(cfg.useRotationAdjustment, plugin.useRotationAdjustment);\n\n        this._axesBasis = math.identityMat4();\n        this.approximate = cfg.approximate;\n\n        this._labelStringFormat = (len) => {\n            const metrics = this.plugin.viewer.scene.metrics;\n            const scale = metrics.scale;\n            const unit = metrics.unitsInfo[metrics.units].abbrev;\n\n            return (this.approximate ? \" ~ \" : \" = \") + (len * scale).toFixed(2) + unit;\n        };\n\n        const canvas = scene.canvas.canvas;\n\n        const onMouseOver = cfg.onMouseOver ? (event) => {\n            cfg.onMouseOver(event, this);\n            canvas.dispatchEvent(new MouseEvent('mouseover', event));\n        } : null;\n\n        const onMouseLeave = cfg.onMouseLeave ? (event) => {\n            cfg.onMouseLeave(event, this);\n            canvas.dispatchEvent(new MouseEvent('mouseleave', event));\n        } : null;\n\n        const onContextMenu = cfg.onContextMenu ? (event) => {\n            cfg.onContextMenu(event, this);\n        } : null;\n\n        const onMouseDown  = (event) => canvas.dispatchEvent(new MouseEvent('mousedown', event));\n        const onMouseUp    = (event) => canvas.dispatchEvent(new MouseEvent('mouseup', event));\n        const onMouseMove  = (event) => canvas.dispatchEvent(new MouseEvent('mousemove', event));\n        const onMouseWheel = (event) => canvas.dispatchEvent(new WheelEvent('wheel', event));\n\n\n        this._cleanups = [ ];\n\n        [ \"units\", \"scale\" ].forEach(evt => {\n            const handler = scene.metrics.on(\"units\", () => this._update());\n            this._cleanups.push(() => scene.metrics.off(handler));\n        });\n\n        this._drawables = [ ];\n\n        const registerDrawable = (drawable, visibilityChannels) => {\n            const updateVisibility = () => drawable.setVisible(visibilityChannels.every(ch => ch.get()));\n            visibilityChannels.forEach(ch => ch.reg(updateVisibility));\n            this._drawables.push(drawable);\n            this._cleanups.push(() => drawable.destroy());\n        };\n\n        const makeWire = (color, thickness, visibilityChannels) => {\n            const wire = new Wire3D(scene, container, {\n                color: color,\n                thickness: thickness,\n                thicknessClickable: 6,\n                zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1 : undefined,\n                onMouseOver,\n                onMouseLeave,\n                onMouseWheel,\n                onMouseDown,\n                onMouseUp,\n                onMouseMove,\n                onContextMenu\n            });\n            registerDrawable(wire, visibilityChannels);\n            return {\n                setEnds: (p0, p1) => wire.setEnds(p0, p1),\n                setColor: value => wire.setColor(value)\n            };\n        };\n        this._lengthWire = makeWire(this._color, 2, [ this._visible, this._wireVisible ]);\n        this._xAxisWire  = makeWire(\"red\",       1, [ this._visible, this._axisEnabled, this._axisVisible, this._xAxisVisible ]);\n        this._yAxisWire  = makeWire(\"green\",     1, [ this._visible, this._axisEnabled, this._axisVisible, this._yAxisVisible ]);\n        this._zAxisWire  = makeWire(\"blue\",      1, [ this._visible, this._axisEnabled, this._axisVisible, this._zAxisVisible ]);\n\n        const makeLabel = (color, zIndexOffset, visibilityChannels) => {\n            const label = new Label3D(scene, container, {\n                fillColor: color,\n                zIndex: plugin.zIndex !== undefined ? plugin.zIndex + zIndexOffset : undefined,\n                onMouseOver,\n                onMouseLeave,\n                onMouseWheel,\n                onMouseDown,\n                onMouseUp,\n                onMouseMove,\n                onContextMenu\n            });\n            registerDrawable(label, visibilityChannels);\n            return {\n                setFillColor:  value => label.setFillColor(value),\n                setPosOnWire:  (p0, p1, offset, labelMinAxisLength) => label.setPosOnWire(p0, p1, offset, labelMinAxisLength),\n                setPosBetween: (p0, p1, p2) => label.setPosBetween(p0, p1, p2),\n                setText:       str => label.setText(str.replace(/ /g, \"&nbsp;\"))\n            };\n        };\n        this._lengthLabel = makeLabel(this._color, 4, [ this._visible, this._wireVisible, this._labelsVisible, this._clickable, this._axisEnabled, this._lengthLabelEnabled ]);\n        this._xAxisLabel  = makeLabel(\"red\",       3, [ this._visible, this._axisEnabled, this._axisVisible, this._xAxisVisible, this._labelsVisible, this._clickable, this._xLabelEnabled ]);\n        this._yAxisLabel  = makeLabel(\"green\",     3, [ this._visible, this._axisEnabled, this._axisVisible, this._yAxisVisible, this._labelsVisible, this._clickable, this._yLabelEnabled ]);\n        this._zAxisLabel  = makeLabel(\"blue\",      3, [ this._visible, this._axisEnabled, this._axisVisible, this._zAxisVisible, this._labelsVisible, this._clickable, this._zLabelEnabled ]);\n\n        const makeDot = (cfg, visibilityChannels) => {\n            const dot = new Dot3D(scene, cfg, container, {\n                fillColor: this._color,\n                zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 2 : undefined,\n                onMouseOver,\n                onMouseLeave,\n                onMouseWheel,\n                onMouseDown,\n                onMouseUp,\n                onMouseMove,\n                onContextMenu\n            });\n            dot.on(\"worldPos\", () => this._update());\n            registerDrawable(dot, visibilityChannels);\n            return dot;\n        };\n        this._originDot = makeDot(cfg.origin, [ this._visible, this._originVisible ]);\n        this._targetDot = makeDot(cfg.target, [ this._visible, this._targetVisible ]);\n\n        this._update();\n    }\n\n    _update() {\n        if (! this._targetDot) {\n            return;\n        }\n\n        const p0 = this._originDot.worldPos;\n        const p1 = this._targetDot.worldPos;\n        const axesBasis = this._axesBasis;\n        const delta = math.subVec3(p1, p0, tmpVec3a);\n        const factors = math.transformVec3(axesBasis, delta, delta);\n\n        const measurementOrientationVertical = this._useRotationAdjustment.get() && Math.abs(delta[1]) > 0;\n\n        const setWireCoordinates = (xEnd, zStart) => {\n\n            const metrics = this.plugin.viewer.scene.metrics;\n            const scale = metrics.scale;\n            metrics.unitsInfo[metrics.units].abbrev;\n\n            const setAxisLabelCoords = (label, a, b, offsetIdx) => {\n                if (this._labelsOnWires.get()) {\n                    label.setPosOnWire(a, b, 0, this.plugin.labelMinAxisLength);\n                } else {\n                    label.setPosOnWire(p0, p1, offsetIdx * 35, 0);\n                }\n            };\n\n            this._xAxisWire.setEnds(p0, xEnd);\n            setAxisLabelCoords(this._xAxisLabel, p0, xEnd, 1);\n            this._xAxisLabel.setText(\"X\" + this._labelStringFormat(math.distVec3(p0, xEnd)));\n\n            this._yAxisWire.setEnds(xEnd, zStart);\n            setAxisLabelCoords(this._yAxisLabel, xEnd, zStart, 2);\n            this._yAxisLabel.setText(\"Y\" + this._labelStringFormat(math.distVec3(xEnd, zStart)));\n\n            this._zAxisWire.setEnds(zStart, p1);\n            setAxisLabelCoords(this._zAxisLabel, zStart, p1, 3);\n            this._zAxisLabel.setText((measurementOrientationVertical ? \"\" : \"Z\") + this._labelStringFormat(math.distVec3(zStart, p1)));\n\n            this._lengthWire.setEnds(p0, p1);\n            setAxisLabelCoords(this._lengthLabel, p0, p1, 0);\n            const length = math.distVec3(p0, p1);\n            this._length = length * scale;\n            this._lengthLabel.setText(this._labelStringFormat(length));\n        };\n\n        if (measurementOrientationVertical) {\n            tmpVec3c[0] = p0[0];\n            tmpVec3c[1] = p1[1];\n            tmpVec3c[2] = p0[2];\n\n            setWireCoordinates(p0, tmpVec3c);\n        }\n        else {\n            tmpVec3b[0] = p0[0] + axesBasis[0] * factors[0];\n            tmpVec3b[1] = p0[1] + axesBasis[4] * factors[0];\n            tmpVec3b[2] = p0[2] + axesBasis[8] * factors[0];\n\n            tmpVec3c[0] = tmpVec3b[0] + axesBasis[1] * factors[1];\n            tmpVec3c[1] = tmpVec3b[1] + axesBasis[5] * factors[1];\n            tmpVec3c[2] = tmpVec3b[2] + axesBasis[9] * factors[1];\n\n            setWireCoordinates(tmpVec3b, tmpVec3c);\n        }\n    }\n\n    /**\n     * Sets the axes basis for the measurement.\n     *\n     * The value is a 4x4 matrix where each column-vector defines an axis and must have unit length.\n     *\n     * This is the ```identity``` matrix by default, meaning the measurement axes are the same as the world axes.\n     *\n     * @param {number[]} value\n     */\n    set axesBasis(value) {\n        this._axesBasis.set(value);\n        this._update();\n    }\n\n    /**\n     * Gets the axes basis for the measurement.\n     *\n     * The value is a 4x4 matrix where each column-vector defines an axis and must have unit length.\n     *\n     * This is the ```identity``` matrix by default, meaning the measurement axes are the same as the world axes.\n     *\n     * @type {number[]}\n     */\n    get axesBasis() {\n        return this._axesBasis;\n    }\n\n    /**\n     * Sets whether this DistanceMeasurement indicates that its measurement is approximate.\n     *\n     * This is ````true```` by default.\n     *\n     * @type {Boolean}\n     */\n    set approximate(approximate) {\n        approximate = approximate !== false;\n        if (this._approximate === approximate) {\n            return;\n        }\n        this._approximate = approximate;\n        this._update();\n    }\n\n    /**\n     * Gets whether this DistanceMeasurement indicates that its measurement is approximate.\n     *\n     * This is ````true```` by default.\n     *\n     * @type {Boolean}\n     */\n    get approximate() {\n        return this._approximate;\n    }\n\n    /**\n     * Gets the origin {@link Dot3D}.\n     *\n     * @type {Dot3D}\n     */\n    get origin() {\n        return this._originDot;\n    }\n\n    /**\n     * Gets the target {@link Dot3D}.\n     *\n     * @type {Dot3D}\n     */\n    get target() {\n        return this._targetDot;\n    }\n\n    /**\n     * Gets the World-space direct point-to-point distance between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.\n     *\n     * @type {Number}\n     */\n    get length() {\n        return this._length;\n    }\n\n    get color() {\n        return this._color;\n    }\n\n    set color(value) {\n        this._color = value;\n        this._originDot.setFillColor(value);\n        this._targetDot.setFillColor(value);\n        this._lengthWire.setColor(value);\n        this._lengthLabel.setFillColor(value);\n    }\n\n    /**\n     * Sets whether this DistanceMeasurement is visible or not.\n     *\n     * @type {Boolean}\n     */\n    set visible(value) {\n        this._visible.set(value);\n    }\n\n    /**\n     * Gets whether this DistanceMeasurement is visible or not.\n     *\n     * @type {Boolean}\n     */\n    get visible() {\n        return this._visible.get();\n    }\n\n    /**\n     * Sets if the origin {@link Dot3D} is visible.\n     *\n     * @type {Boolean}\n     */\n    set originVisible(value) {\n        this._originVisible.set(value);\n    }\n\n    /**\n     * Gets if the origin {@link Dot3D} is visible.\n     *\n     * @type {Boolean}\n     */\n    get originVisible() {\n        return this._originVisible.get();\n    }\n\n    /**\n     * Sets if the target {@link Dot3D} is visible.\n     *\n     * @type {Boolean}\n     */\n    set targetVisible(value) {\n        this._targetVisible.set(value);\n    }\n\n    /**\n     * Gets if the target {@link Dot3D} is visible.\n     *\n     * @type {Boolean}\n     */\n    get targetVisible() {\n        return this._targetVisible.get();\n    }\n\n    /**\n     * Sets if the measurement is adjusted based on rotation\n     *\n     * @type {Boolean}\n     */\n    set useRotationAdjustment(value) {\n        this._useRotationAdjustment.set(value);\n        this._update();\n    }\n\n    /**\n     * Gets if the measurement is adjusted based on rotation\n     *\n     * @type {Boolean}\n     */\n    get useRotationAdjustment() {\n        return this._useRotationAdjustment.get();\n    }\n\n    /**\n     * Sets if the axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} are enabled.\n     *\n     * Wires are only shown if enabled and visible.\n     *\n     * @type {Boolean}\n     */\n    set axisEnabled(value) {\n        this._axisEnabled.set(value);\n    }\n\n    /**\n     * Gets if the axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} are enabled.\n     *\n     * Wires are only shown if enabled and visible.\n     *\n     * @type {Boolean}\n     */\n    get axisEnabled() {\n        return this._axisEnabled.get();\n    }\n\n    /**\n     * Sets if the axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} are visible.\n     *\n     * Wires are only shown if enabled and visible.\n     *\n     * @type {Boolean}\n     */\n    set axisVisible(value) {\n        this._axisVisible.set(value);\n    }\n\n    /**\n     * Gets if the axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} are visible.\n     *\n     * Wires are only shown if enabled and visible.\n     *\n     * @type {Boolean}\n     */\n    get axisVisible() {\n        return this._axisVisible.get();\n    }\n\n    /**\n     * Sets if the X-axis-aligned wire between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} is visible.\n     *\n     * Wires are only shown if enabled and visible.\n     *\n     * @type {Boolean}\n     */\n    set xAxisVisible(value) {\n        this._xAxisVisible.set(value);\n    }\n\n    /**\n     * Gets if the X-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} are visible.\n     *\n     * Wires are only shown if enabled and visible.\n     *\n     * @type {Boolean}\n     */\n    get xAxisVisible() {\n        return this._xAxisVisible.get();\n    }\n\n    /**\n     * Sets if the Y-axis-aligned wire between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} is visible.\n     *\n     * Wires are only shown if enabled and visible.\n     *\n     * @type {Boolean}\n     */\n    set yAxisVisible(value) {\n        this._yAxisVisible.set(value);\n    }\n\n    /**\n     * Gets if the Y-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} are visible.\n     *\n     * Wires are only shown if enabled and visible.\n     *\n     * @type {Boolean}\n     */\n    get yAxisVisible() {\n        return this._yAxisVisible.get();\n    }\n\n    /**\n     * Sets if the Z-axis-aligned wire between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} is visible.\n     *\n     * Wires are only shown if enabled and visible.\n     *\n     * @type {Boolean}\n     */\n    set zAxisVisible(value) {\n        this._zAxisVisible.set(value);\n    }\n\n    /**\n     * Gets if the Z-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} are visible.\n     *\n     * Wires are only shown if enabled and visible.\n     *\n     * @type {Boolean}\n     */\n    get zAxisVisible() {\n        return this._zAxisVisible.get();\n    }\n\n    /**\n     * Sets if the direct point-to-point wire between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} is visible.\n     *\n     * @type {Boolean}\n     */\n    set wireVisible(value) {\n        this._wireVisible.set(value);\n    }\n\n    /**\n     * Gets if the direct point-to-point wire between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target} is visible.\n     *\n     * @type {Boolean}\n     */\n    get wireVisible() {\n        return this._wireVisible.get();\n    }\n\n    /**\n     * Sets if the labels are visible except the length label.\n     *\n     * @type {Boolean}\n     */\n    set labelsVisible(value) {\n        this._labelsVisible.set(value);\n    }\n\n    /**\n     * Gets if the labels are visible.\n     *\n     * @type {Boolean}\n     */\n    get labelsVisible() {\n        return this._labelsVisible.get();\n    }\n\n    /**\n     * Sets if the x label is enabled.\n     *\n     * @type {Boolean}\n     */\n    set xLabelEnabled(value) {\n        this._xLabelEnabled.set(value);\n    }\n\n    /**\n     * Gets if the x label is enabled.\n     *\n     * @type {Boolean}\n     */\n    get xLabelEnabled(){\n        return this._xLabelEnabled.get();\n    }\n\n    /**\n     * Sets if the y label is enabled.\n     *\n     * @type {Boolean}\n     */\n    set yLabelEnabled(value) {\n        this._yLabelEnabled.set(value);\n    }\n\n    /**\n     * Gets if the y label is enabled.\n     *\n     * @type {Boolean}\n     */\n    get yLabelEnabled(){\n        return this._yLabelEnabled.get();\n    }\n\n    /**\n     * Sets if the z label is enabled.\n     *\n     * @type {Boolean}\n     */\n    set zLabelEnabled(value) {\n        this._zLabelEnabled.set(value);\n    }\n\n    /**\n     * Gets if the z label is enabled.\n     *\n     * @type {Boolean}\n     */\n    get zLabelEnabled(){\n        return this._zLabelEnabled.get();\n    }\n\n    /**\n     * Sets if the length label is enabled.\n     *\n     * @type {Boolean}\n     */\n    set lengthLabelEnabled(value) {\n        this._lengthLabelEnabled.set(value);\n    }\n\n    /**\n     * Gets if the length label is enabled.\n     *\n     * @type {Boolean}\n     */\n    get lengthLabelEnabled(){\n        return this._lengthLabelEnabled.get();\n    }\n\n    /**\n     * Sets if labels should be positioned on the wires.\n     *\n     * @type {Boolean}\n     */\n    set labelsOnWires(value) {\n        this._labelsOnWires.set(value);\n        this._update();\n    }\n\n    /**\n     * Gets if labels should be positioned on the wires.\n     *\n     * @type {Boolean}\n     */\n    get labelsOnWires() {\n        return this._labelsOnWires.get();\n    }\n\n    /**\n     * Sets if this DistanceMeasurement appears highlighted.\n     * @param highlighted\n     */\n    setHighlighted(highlighted) {\n        this._drawables.forEach(d => d.setHighlighted(highlighted));\n    }\n\n    /**\n     * Sets if the wires, dots ad labels will fire \"mouseOver\" \"mouseLeave\" and \"contextMenu\" events, or ignore mouse events altogether.\n     *\n     * @type {Boolean}\n     */\n    set clickable(value) {\n        this._clickable.set(!!value);\n        this._drawables.forEach(d => d.setClickable(this._clickable.get()));\n    }\n\n    /**\n     * Gets if the wires, dots ad labels will fire \"mouseOver\" \"mouseLeave\" and \"contextMenu\" events.\n     *\n     * @type {Boolean}\n     */\n    get clickable() {\n        return this._clickable.get();\n    }\n\n    /**\n     * Sets the function to format unit strings.\n     *\n     * @type {Function}\n     */\n    set labelStringFormat(value) {\n        this._labelStringFormat = value;\n        this._update();\n    }\n\n    /**\n     * Gets the function to format unit strings.\n     *\n     * @type {Function}\n     */\n    get labelStringFormat() {\n        return this._labelStringFormat;\n    }\n\n    /**\n     * @private\n     */\n    destroy() {\n        this._cleanups.forEach(cleanup => cleanup());\n        super.destroy();\n    }\n}\n\n/**\n * Creates {@link DistanceMeasurement}s in a {@link DistanceMeasurementsPlugin} from user input.\n *\n * @interface\n * @abstract\n */\nclass DistanceMeasurementsControl extends Component {\n\n    /**\n     * Gets if this DistanceMeasurementsControl is currently active, where it is responding to input.\n     *\n     * @returns {boolean} True if this DistanceMeasurementsControl is active.\n     * @abstract\n     */\n    get active() {\n    }\n\n    /**\n     * Sets whether snap-to-vertex and snap-to-edge are enabled for this DistanceMeasurementsControl.\n     *\n     * This is `true` by default.\n     *\n     * Internally, this deactivates then activates the DistanceMeasurementsControl when changed, which means that\n     * it will destroy any DistanceMeasurements currently under construction, and incurs some overhead, since it unbinds\n     * and rebinds various input handlers.\n     *\n     * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this DistanceMeasurementsControl.\n     */\n    set snapping(snapping) {\n    }\n\n    /**\n     * Gets whether snap-to-vertex and snap-to-edge are enabled for this DistanceMeasurementsControl.\n     *\n     * This is `true` by default.\n     *\n     * @returns {boolean} Whether snap-to-vertex and snap-to-edge are enabled for this DistanceMeasurementsControl.\n     */\n    get snapping() {\n        return true;\n    }\n\n    /**\n     * Activates this DistanceMeasurementsControl, ready to respond to input.\n     *\n     * @abstract\n     */\n    activate() {\n    }\n\n    /**\n     * Deactivates this DistanceMeasurementsControl, making it unresponsive to input.\n     *\n     * Destroys any {@link DistanceMeasurement} under construction by this DistanceMeasurementsControl.\n     *\n     * @abstract\n     */\n    deactivate() {\n    }\n\n    /**\n     * Resets this DistanceMeasurementsControl.\n     *\n     * Destroys any {@link DistanceMeasurement} under construction by this DistanceMeasurementsControl.\n     *\n     * Does nothing if the DistanceMeasurementsControl is not active.\n     *\n     * @abstract\n     */\n    reset() {\n    }\n\n    /**\n     * Gets the {@link DistanceMeasurement} under construction by this DistanceMeasurementsControl, if any.\n     *\n     * @returns {null|DistanceMeasurement}\n     *\n     * @abstract\n     */\n    get currentMeasurement() {\n        return null;\n    }\n\n    /**\n     * Destroys this DistanceMeasurementsControl.\n     *\n     * Destroys any {@link DistanceMeasurement} under construction by this DistanceMeasurementsControl.\n     *\n     * @abstract\n     */\n    destroy() {\n    }\n}\n\nconst MOUSE_FIRST_CLICK_EXPECTED = 0;\n\n/**\n * Creates {@link DistanceMeasurement}s in a {@link DistanceMeasurementsPlugin} from mouse input.\n *\n * ## Usage\n *\n * [[Run example](/examples/measurement/#distance_createWithMouse_snapping)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, DistanceMeasurementsPlugin, DistanceMeasurementsMouseControl, PointerLens} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n * });\n *\n * viewer.camera.eye = [-3.93, 2.85, 27.01];\n * viewer.camera.look = [4.40, 3.72, 8.89];\n * viewer.camera.up = [-0.01, 0.99, 0.039];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const sceneModel = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"Duplex.xkt\"\n * });\n *\n * const distanceMeasurements = new DistanceMeasurementsPlugin(viewer);\n *\n * const distanceMeasurementsControl  = new DistanceMeasurementsMouseControl(DistanceMeasurements, {\n *     pointerLens: new PointerLens(viewer)\n * })\n *\n * distanceMeasurementsControl.snapping = true;\n *\n * distanceMeasurementsControl.activate();\n * ````\n */\nclass DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {\n\n    /**\n     * Creates a DistanceMeasurementsMouseControl bound to the given DistanceMeasurementsPlugin.\n     *\n     * @param {DistanceMeasurementsPlugin} distanceMeasurementsPlugin The AngleMeasurementsPlugin to control.\n     * @param [cfg] Configuration\n     * @param {function} [cfg.canvasToPagePos] Optional function to map canvas-space coordinates to page coordinates.\n     * @param {PointerLens} [cfg.pointerLens] A PointerLens to use to provide a magnified view of the cursor when snapping is enabled.\n     * @param {boolean} [cfg.snapping=true] Whether to initially enable snap-to-vertex and snap-to-edge for this DistanceMeasurementsMouseControl.\n     */\n    constructor(distanceMeasurementsPlugin, cfg = {}) {\n\n        super(distanceMeasurementsPlugin.viewer.scene);\n\n        this._canvasToPagePos = cfg.canvasToPagePos;\n\n        this.pointerLens = cfg.pointerLens;\n\n        this._active = false;\n\n        this._currentDistanceMeasurement = null;\n\n        this._currentDistanceMeasurementInitState = {\n            wireVisible: null,\n            axisVisible: null,\n            xAxisVisible: null,\n            yaxisVisible: null,\n            zAxisVisible: null,\n            targetVisible: null,\n        };\n\n        this._initMarkerDiv();\n\n        this._snapping = cfg.snapping !== false;\n        this._mouseState = MOUSE_FIRST_CLICK_EXPECTED;\n\n        this._attachPlugin(distanceMeasurementsPlugin, cfg);\n    }\n\n    _initMarkerDiv() {\n        const markerDiv = document.createElement('div');\n        const canvas = this.scene.canvas.canvas;\n        canvas.parentNode.insertBefore(markerDiv, canvas);\n        markerDiv.style.background = \"black\";\n        markerDiv.style.border = \"2px solid blue\";\n        markerDiv.style.borderRadius = \"10px\";\n        markerDiv.style.width = \"5px\";\n        markerDiv.style.height = \"5px\";\n        markerDiv.style.top = \"-200px\";\n        markerDiv.style.left = \"-200px\";\n        markerDiv.style.margin = \"0 0\";\n        markerDiv.style.zIndex = \"100\";\n        markerDiv.style.position = \"absolute\";\n        markerDiv.style.pointerEvents = \"none\";\n\n        this._markerDiv = markerDiv;\n    }\n\n    _destroyMarkerDiv() {\n        if (this._markerDiv) {\n            this._markerDiv.parentNode.removeChild(this._markerDiv);\n            this._markerDiv = null;\n        }\n    }\n\n    _attachPlugin(distanceMeasurementsPlugin, cfg = {}) {\n\n        /**\n         * The {@link DistanceMeasurementsPlugin} that owns this DistanceMeasurementsMouseControl.\n         * @type {DistanceMeasurementsPlugin}\n         */\n        this.distanceMeasurementsPlugin = distanceMeasurementsPlugin;\n\n        /**\n         * The {@link DistanceMeasurementsPlugin} that owns this DistanceMeasurementsMouseControl.\n         * @type {DistanceMeasurementsPlugin}\n         */\n        this.plugin = distanceMeasurementsPlugin;\n    }\n\n    /**\n     * Gets if this DistanceMeasurementsMouseControl is currently active, where it is responding to input.\n     *\n     * @returns {boolean} True if this DistanceMeasurementsMouseControl is active.\n     */\n    get active() {\n        return this._active;\n    }\n\n    /**\n     * Sets whether snap-to-vertex and snap-to-edge are enabled for this DistanceMeasurementsMouseControl.\n     *\n     * This is `true` by default.\n     *\n     * @param snapping\n     */\n    set snapping(snapping) {\n        this._snapping = snapping;\n    }\n\n    /**\n     * Gets whether snap-to-vertex and snap-to-edge are enabled for this DistanceMeasurementsMouseControl.\n     *\n     * This is `true` by default.\n     * @returns {*}\n     */\n    get snapping() {\n        return this._snapping;\n    }\n\n    /**\n     * Activates this DistanceMeasurementsMouseControl, ready to respond to input.\n     */\n    activate() {\n\n        if (this._active) {\n            return;\n        }\n\n        if (!this._markerDiv) {\n            this._initMarkerDiv();\n        }\n\n        this.fire(\"activated\", true);\n\n        const distanceMeasurementsPlugin = this.distanceMeasurementsPlugin;\n        const scene = this.scene;\n        const cameraControl = distanceMeasurementsPlugin.viewer.cameraControl;\n        const canvas = scene.canvas.canvas;\n        scene.input;\n        let mouseHovering = false;\n        const pointerWorldPos = math.vec3();\n        const pointerCanvasPos = math.vec2();\n        let pointerDownCanvasX;\n        let pointerDownCanvasY;\n        const clickTolerance = 20;\n        let hoveredEntity = null;\n\n        this._mouseState = MOUSE_FIRST_CLICK_EXPECTED;\n\n        const pagePos = math.vec2();\n\n        const hoverOn = event => {\n                const canvasPos = event.snappedCanvasPos || event.canvasPos;\n                mouseHovering = true;\n                pointerWorldPos.set(event.worldPos);\n                pointerCanvasPos.set(event.canvasPos);\n                if (this._mouseState === MOUSE_FIRST_CLICK_EXPECTED) {\n\n                    if (this._canvasToPagePos) {\n                        this._canvasToPagePos(canvas, canvasPos, pagePos);\n                        this._markerDiv.style.left = `${pagePos[0] - 5}px`;\n                        this._markerDiv.style.top = `${pagePos[1] - 5}px`;\n                    } else {\n                        const markerPos = math.vec2(canvasPos);\n                        transformToNode(canvas, this._markerDiv.parentNode, markerPos);\n                        this._markerDiv.style.left = `${markerPos[0] - 5}px`;\n                        this._markerDiv.style.top = `${markerPos[1] - 5}px`;\n                    }\n\n                    this._markerDiv.style.background = \"pink\";\n                    if (event.snappedToVertex || event.snappedToEdge) {\n                        if (this.pointerLens) {\n                            this.pointerLens.visible = true;\n                            this.pointerLens.canvasPos = event.canvasPos;\n                            this.pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;\n                            this.pointerLens.snapped = true;\n                        }\n                        this._markerDiv.style.background = \"greenyellow\";\n                        this._markerDiv.style.border = \"2px solid green\";\n                    } else {\n                        if (this.pointerLens) {\n                            this.pointerLens.visible = true;\n                            this.pointerLens.canvasPos = event.canvasPos;\n                            this.pointerLens.snappedCanvasPos = event.canvasPos;\n                            this.pointerLens.snapped = false;\n                        }\n                        this._markerDiv.style.background = \"pink\";\n                        this._markerDiv.style.border = \"2px solid red\";\n                    }\n                    hoveredEntity = event.entity;\n                } else {\n                    this._markerDiv.style.left = `-10000px`;\n                    this._markerDiv.style.top = `-10000px`;\n                }\n                canvas.style.cursor = \"pointer\";\n                if (this._currentDistanceMeasurement) {\n                    this._currentDistanceMeasurement.wireVisible = this._currentDistanceMeasurementInitState.wireVisible;\n                    this._currentDistanceMeasurement.axisVisible = this._currentDistanceMeasurementInitState.axisVisible && this.distanceMeasurementsPlugin.defaultAxisVisible;\n                    this._currentDistanceMeasurement.xAxisVisible = this._currentDistanceMeasurementInitState.xAxisVisible && this.distanceMeasurementsPlugin.defaultXAxisVisible;\n                    this._currentDistanceMeasurement.yAxisVisible = this._currentDistanceMeasurementInitState.yAxisVisible && this.distanceMeasurementsPlugin.defaultYAxisVisible;\n                    this._currentDistanceMeasurement.zAxisVisible = this._currentDistanceMeasurementInitState.zAxisVisible && this.distanceMeasurementsPlugin.defaultZAxisVisible;\n                    this._currentDistanceMeasurement.targetVisible = this._currentDistanceMeasurementInitState.targetVisible;\n                    this._currentDistanceMeasurement.target.worldPos = pointerWorldPos.slice();\n                    this._markerDiv.style.left = `-10000px`;\n                    this._markerDiv.style.top = `-10000px`;\n                }\n        };\n        this._onHoverSnapOrSurface = cameraControl.on(\"hoverSnapOrSurface\", e => { if (this._snapping)   hoverOn(e); });\n        this._onHoverSurface       = cameraControl.on(\"hoverSurface\",       e => { if (! this._snapping) hoverOn(e); });\n\n        canvas.addEventListener('mousedown', this._onMouseDown = (e) => {\n            if (e.which !== 1) {\n                return;\n            }\n            pointerDownCanvasX = e.clientX;\n            pointerDownCanvasY = e.clientY;\n        });\n\n        canvas.addEventListener(\"mouseup\", this._onMouseUp = (e) => {\n            if (e.which !== 1) {\n                return;\n            }\n            if (e.clientX > pointerDownCanvasX + clickTolerance ||\n                e.clientX < pointerDownCanvasX - clickTolerance ||\n                e.clientY > pointerDownCanvasY + clickTolerance ||\n                e.clientY < pointerDownCanvasY - clickTolerance) {\n                return;\n            }\n            if (this._currentDistanceMeasurement) {\n                if (mouseHovering) {\n                    this._currentDistanceMeasurement.target.entity = hoveredEntity;\n                    hoveredEntity = null;\n                    this._currentDistanceMeasurement.clickable = true;\n                    this.distanceMeasurementsPlugin.fire(\"measurementEnd\", this._currentDistanceMeasurement);\n                    this._currentDistanceMeasurement = null;\n                } else {\n                    this._currentDistanceMeasurement.destroy();\n                    this.distanceMeasurementsPlugin.fire(\"measurementCancel\", this._currentDistanceMeasurement);\n                    this._currentDistanceMeasurement = null;\n                    hoveredEntity = null;\n                }\n            } else {\n                if (mouseHovering) {\n                    this._currentDistanceMeasurement = distanceMeasurementsPlugin.createMeasurement({\n                        id: math.createUUID(),\n                        origin: {\n                            worldPos: pointerWorldPos.slice(),\n                            entity: hoveredEntity\n                        },\n                        target: {\n                            worldPos: pointerWorldPos.slice(),\n                            entity: hoveredEntity\n                        },\n                        approximate: true\n                    });\n                    this._currentDistanceMeasurementInitState.axisVisible = this._currentDistanceMeasurement.axisVisible && this.distanceMeasurementsPlugin.defaultAxisVisible;\n                    this._currentDistanceMeasurementInitState.xAxisVisible = this._currentDistanceMeasurement.xAxisVisible && this.distanceMeasurementsPlugin.defaultXAxisVisible;\n                    this._currentDistanceMeasurementInitState.yAxisVisible = this._currentDistanceMeasurement.yAxisVisible && this.distanceMeasurementsPlugin.defaultYAxisVisible;\n                    this._currentDistanceMeasurementInitState.zAxisVisible = this._currentDistanceMeasurement.zAxisVisible && this.distanceMeasurementsPlugin.defaultZAxisVisible;\n                    this._currentDistanceMeasurementInitState.wireVisible = this._currentDistanceMeasurement.wireVisible;\n                    this._currentDistanceMeasurementInitState.targetVisible = this._currentDistanceMeasurement.targetVisible;\n                    this._currentDistanceMeasurement.clickable = false;\n                    this._currentDistanceMeasurement.origin.entity = hoveredEntity;\n                    hoveredEntity = null;\n                    this.distanceMeasurementsPlugin.fire(\"measurementStart\", this._currentDistanceMeasurement);\n                }\n            }\n        });\n\n        const hoverOff = event => {\n                if (this.pointerLens) {\n                    this.pointerLens.visible = true;\n                    this.pointerLens.canvasPos = event.canvasPos;\n                    this.pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;\n                }\n                mouseHovering = false;\n                this._markerDiv.style.left = `-100px`;\n                this._markerDiv.style.top = `-100px`;\n                if (this._currentDistanceMeasurement) {\n                    this._currentDistanceMeasurement.wireVisible = false;\n                    this._currentDistanceMeasurement.targetVisible = false;\n                    this._currentDistanceMeasurement.axisVisible = false;\n                }\n                canvas.style.cursor = \"default\";\n        };\n        this._onHoverSnapOrSurfaceOff = cameraControl.on(\"hoverSnapOrSurfaceOff\", e => { if (this._snapping)   hoverOff(e); });\n        this._onHoverOff              = cameraControl.on(\"hoverOff\",              e => { if (! this._snapping) hoverOff(e); });\n\n        this._active = true;\n    }\n\n    /**\n     * Deactivates this DistanceMeasurementsMouseControl, making it unresponsive to input.\n     *\n     * Destroys any {@link DistanceMeasurement} under construction by this DistanceMeasurementsMouseControl.\n     */\n    deactivate() {\n        if (!this._active) {\n            return;\n        }\n\n        this.fire(\"activated\", false);\n\n        if (this.pointerLens) {\n            this.pointerLens.visible = false;\n        }\n\n        this.reset();\n\n        const canvas = this.scene.canvas.canvas;\n        canvas.removeEventListener(\"mousedown\", this._onMouseDown);\n        canvas.removeEventListener(\"mouseup\", this._onMouseUp);\n        const cameraControl = this.distanceMeasurementsPlugin.viewer.cameraControl;\n        cameraControl.off(this._onHoverSnapOrSurface);\n        cameraControl.off(this._onHoverSurface);\n        cameraControl.off(this._onHoverSnapOrSurfaceOff);\n        cameraControl.off(this._onHoverOff);\n\n        this._active = false;\n    }\n\n    /**\n     * Resets this DistanceMeasurementsMouseControl.\n     *\n     * Destroys any {@link DistanceMeasurement} under construction by this DistanceMeasurementsMouseControl.\n     *\n     * Does nothing if the DistanceMeasurementsMouseControl is not active.\n     */\n    reset() {\n        if (!this._active) {\n            return;\n        }\n\n        this._destroyMarkerDiv();\n        this._initMarkerDiv();\n\n        if (this._currentDistanceMeasurement) {\n            this.distanceMeasurementsPlugin.fire(\"measurementCancel\", this._currentDistanceMeasurement);\n            this._currentDistanceMeasurement.destroy();\n            this._currentDistanceMeasurement = null;\n        }\n\n        this._mouseState = MOUSE_FIRST_CLICK_EXPECTED;\n    }\n\n    /**\n     * Gets the {@link DistanceMeasurement} under construction by this DistanceMeasurementsMouseControl, if any.\n     *\n     * @returns {null|DistanceMeasurement}\n     */\n    get currentMeasurement() {\n        return this._currentDistanceMeasurement;\n    }\n\n    /**\n     * Destroys this DistanceMeasurementsMouseControl.\n     *\n     * Destroys any {@link DistanceMeasurement} under construction by this DistanceMeasurementsMouseControl.\n     */\n    destroy() {\n        this.deactivate();\n        super.destroy();\n    }\n}\n\n/**\n * {@link Viewer} plugin for measuring point-to-point distances.\n *\n * [<img src=\"https://user-images.githubusercontent.com/83100/63047331-867a0a80-bed4-11e9-892f-398740013c5f.gif\">](https://xeokit.github.io/xeokit-sdk/examples/index.html#measurements_distance_createWithMouse)\n *\n * * [[Example 1: Model with distance measurements](https://xeokit.github.io/xeokit-sdk/examples/index.html#measurements_distance_modelWithMeasurements)]\n * * [[Example 2: Create distance measurements with mouse](https://xeokit.github.io/xeokit-sdk/examples/measurement/#distance_createWithMouse_snapping)]\n * * [[Example 3: Configuring units and scale](https://xeokit.github.io/xeokit-sdk/examples/measurement/#distance_unitsAndScale)\n *\n * ## Overview\n *\n * * A {@link DistanceMeasurement} represents a point-to-point measurement between two 3D points on one or two {@link Entity}s.\n * * As shown on the screen capture above, a DistanceMeasurement has one wire (light blue) that shows the direct point-to-point measurement,\n * and three more wires (red, green and blue) that show the distance on each of the World-space X, Y and Z axis.\n * * Create DistanceMeasurements programmatically with {@link DistanceMeasurementsPlugin#createMeasurement}.\n * * Create DistanceMeasurements interactively using a {@link DistanceMeasurementsControl}.\n * * Existing DistanceMeasurements are registered by ID in {@link DistanceMeasurementsPlugin#measurements}.\n * * Destroy DistanceMeasurements using {@link DistanceMeasurementsPlugin#destroyMeasurement}.\n * * Configure global measurement units and scale via {@link Metrics}, located at {@link Scene#metrics}.\n *\n * ## Example 1: Creating DistanceMeasurements Programmatically\n *\n * In our first example, we'll use an {@link XKTLoaderPlugin} to load a model, and then use a DistanceMeasurementsPlugin to programmatically create two {@link DistanceMeasurement}s.\n *\n * Note how each DistanceMeasurement has ````origin```` and ````target```` endpoints, which each indicate a 3D World-space\n * position on the surface of an {@link Entity}. The endpoints can be attached to the same Entity, or to different Entitys.\n *\n * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/measurement/#distance_modelWithMeasurements)]\n *\n * ````JavaScript\n * import {Viewer, XKTLoaderPlugin, DistanceMeasurementsPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-2.37, 18.97, -26.12];\n * viewer.scene.camera.look = [10.97, 5.82, -11.22];\n * viewer.scene.camera.up = [0.36, 0.83, 0.40];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const distanceMeasurements = new DistanceMeasurementsPlugin(viewer);\n *\n * const model = xktLoader.load({\n *      src: \"./models/xkt/duplex/duplex.xkt\"\n * });\n *\n * model.on(\"loaded\", () => {\n *\n *      const myMeasurement1 = distanceMeasurements.createMeasurement({\n *          id: \"distanceMeasurement1\",\n *          origin: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FLOH\"],\n *              worldPos: [0.044, 5.998, 17.767]\n *          },\n *          target: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FLOH\"],\n *              worldPos: [4.738, 3.172, 17.768]\n *          },\n *          visible: true,\n *          wireVisible: true\n *      });\n *\n *      const myMeasurement2 = distanceMeasurements.createMeasurement({\n *          id: \"distanceMeasurement2\",\n *          origin: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FNr2\"],\n *              worldPos: [0.457, 2.532, 17.766]\n *          },\n *          target: {\n *              entity: viewer.scene.objects[\"1CZILmCaHETO8tf3SgGEXu\"],\n *              worldPos: [0.436, 0.001, 22.135]\n *          },\n *          visible: true,\n *          wireVisible: true\n *      });\n * });\n * ````\n *\n * ## Example 2: Creating DistanceMeasurements with Mouse Input\n *\n * In our second example, we'll use an {@link XKTLoaderPlugin} to load a model, then we'll use a\n * {@link DistanceMeasurementsMouseControl} to interactively create {@link DistanceMeasurement}s with mouse input.\n *\n * After we've activated the DistanceMeasurementsMouseControl, the first click on any {@link Entity} begins constructing a DistanceMeasurement, fixing its\n * origin to that Entity. The next click on any Entity will complete the DistanceMeasurement, fixing its target to that second Entity.\n *\n * The DistanceMeasurementsMouseControl will then wait for the next click on any Entity, to begin constructing\n * another DistanceMeasurement, and so on, until deactivated again.\n *\n * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/measurement/#distance_createWithMouse_snapping)]\n *\n * ````JavaScript\n * import {Viewer, XKTLoaderPlugin, DistanceMeasurementsPlugin, DistanceMeasurementsMouseControl, PointerLens} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-2.37, 18.97, -26.12];\n * viewer.scene.camera.look = [10.97, 5.82, -11.22];\n * viewer.scene.camera.up = [0.36, 0.83, 0.40];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const distanceMeasurements = new DistanceMeasurementsPlugin(viewer);\n *\n * const distanceMeasurementsControl  = new DistanceMeasurementsMouseControl(distanceMeasurements, {\n *     pointerLens : new PointerLens(viewer)\n * })\n *\n * distanceMeasurementsControl.snapToVertex = true;\n * distanceMeasurementsControl.snapToEdge = true;\n *\n * distanceMeasurementsControl.activate();\n *\n * const model = xktLoader.load({\n *     src: \"./models/xkt/duplex/duplex.xkt\"\n * });\n * ````\n *\n * ## Example 3: Configuring Measurement Units and Scale\n *\n * In our third example, we'll use the  {@link Scene}'s {@link Metrics} to set the global unit of measurement to ````\"meters\"````. We'll also specify that a unit within the World-space coordinate system represents ten meters.\n *\n * The wires belonging to our DistanceMeasurements show their lengths in Real-space coordinates, in the current unit of measurement. They will dynamically update as we set these configurations.\n *\n * * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#measurements_distance_unitsAndScale)]\n *\n * ````JavaScript\n * const metrics = viewer.scene.metrics;\n\n * metrics.units = \"meters\";\n * metrics.scale = 10.0;\n * ````\n *\n * ## Example 4: Attaching Mouse Handlers\n *\n * In our fourth example, we'll attach event handlers to our plugin, to catch when the user\n * hovers or right-clicks over our measurements.\n *\n * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#measurements_distance_modelWithMeasurements)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, DistanceMeasurementsPlugin, DistanceMeasurementsMouseControl, PointerLens} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-2.37, 18.97, -26.12];\n * viewer.scene.camera.look = [10.97, 5.82, -11.22];\n * viewer.scene.camera.up = [0.36, 0.83, 0.40];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const distanceMeasurements = new DistanceMeasurementsPlugin(viewer);\n *\n * const distanceMeasurementsControl  = new DistanceMeasurementsMouseControl(distanceMeasurements, {\n *     pointerLens : new PointerLens(viewer)\n * })\n *\n * distanceMeasurementsControl.snapToVertex = true;\n * distanceMeasurementsControl.snapToEdge = true;\n *\n * distanceMeasurementsControl.activate();\n *\n * distanceMeasurements.on(\"mouseOver\", (e) => {\n *     e.measurement.setHighlighted(true);\n * });\n *\n * distanceMeasurements.on(\"mouseLeave\", (e) => {\n *     e.measurement.setHighlighted(false);\n * });\n *\n * distanceMeasurements.on(\"contextMenu\", (e) => {\n *     // Show context menu\n *     e.event.preventDefault();\n * });\n *\n * const model = xktLoader.load({\n *      src: \"Duplex.xkt\"\n * });\n *\n * model.on(\"loaded\", () => {\n *\n *      const myMeasurement1 = distanceMeasurements.createMeasurement({\n *          id: \"distanceMeasurement1\",\n *          origin: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FLOH\"],\n *              worldPos: [0.044, 5.998, 17.767]\n *          },\n *          target: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FLOH\"],\n *              worldPos: [4.738, 3.172, 17.768]\n *          },\n *          visible: true,\n *          wireVisible: true\n *      });\n *\n *      const myMeasurement2 = distanceMeasurements.createMeasurement({\n *          id: \"distanceMeasurement2\",\n *          origin: {\n *              entity: viewer.scene.objects[\"2O2Fr$t4X7Zf8NOew3FNr2\"],\n *              worldPos: [0.457, 2.532, 17.766]\n *          },\n *          target: {\n *              entity: viewer.scene.objects[\"1CZILmCaHETO8tf3SgGEXu\"],\n *              worldPos: [0.436, 0.001, 22.135]\n *          },\n *          visible: true,\n *          wireVisible: true\n *      });\n * });\n * ````\n *\n * ## Example 5: Creating DistanceMeasurements with Touch Input\n *\n * In our fifth example, we'll show how to create distance measurements with touch input, with snapping\n * to the nearest vertex or edge. While creating the measurements, a long-touch when setting the\n * start or end point will cause the point to snap to the nearest vertex or edge. A quick\n * touch-release will immediately set the point at the tapped position on the object surface.\n *\n * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/measurement/#distance_createWithTouch_snapping)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, DistanceMeasurementsPlugin, DistanceMeasurementsTouchControl} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.scene.camera.eye = [-2.37, 18.97, -26.12];\n * viewer.scene.camera.look = [10.97, 5.82, -11.22];\n * viewer.scene.camera.up = [0.36, 0.83, 0.40];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const distanceMeasurements = new DistanceMeasurementsPlugin(viewer);\n *\n * const model = xktLoader.load({\n *      src: \"./models/xkt/duplex/duplex.xkt\"\n * });\n *\n * const distanceMeasurements = new DistanceMeasurementsPlugin(viewer);\n *\n * const distanceMeasurementsTouchControl  = new DistanceMeasurementsTouchControl(distanceMeasurements, {\n *     pointerLens : new PointerLens(viewer),\n *     snapToVertex: true,\n *     snapToEdge: true\n * })\n *\n * distanceMeasurementsTouchControl.activate();\n * ````\n */\nclass DistanceMeasurementsPlugin extends Plugin {\n  /**\n   * @constructor\n   * @param {Viewer} viewer The Viewer.\n   * @param {Object} [cfg]  Plugin configuration.\n   * @param {String} [cfg.id=\"DistanceMeasurements\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n   * @param {Number} [cfg.labelMinAxisLength=25] The minimum length, in pixels, of an axis wire beyond which its label is shown.\n   * @param {HTMLElement} [cfg.container] Container DOM element for markers and labels. Defaults to ````document.body````.\n   * @param {boolean} [cfg.defaultVisible=true] The default value of the DistanceMeasurements `visible` property.\n   * @param {boolean} [cfg.defaultOriginVisible=true] The default value of the DistanceMeasurements `originVisible` property.\n   * @param {boolean} [cfg.defaultTargetVisible=true] The default value of the DistanceMeasurements `targetVisible` property.\n   * @param {boolean} [cfg.defaultWireVisible=true] The default value of the DistanceMeasurements `wireVisible` property.\n   * @param {boolean} [cfg.defaultLabelsVisible=true] The default value of the DistanceMeasurements `labelsVisible` property.\n   * @param {boolean} [cfg.defaultXLabelEnabled=true] The default value of the DistanceMeasurements `xLabelEnabled` property.\n   * @param {boolean} [cfg.defaultYLabelEnabled=true] The default value of the DistanceMeasurements `yLabelEnabled` property.\n   * @param {boolean} [cfg.defaultZLabelEnabled=true] The default value of the DistanceMeasurements `zLabelEnabled` property.\n   * @param {boolean} [cfg.defaultLengthLabelEnabled=true] The default value of the DistanceMeasurements `lengthLabelEnabled` property.\n   * @param {boolean} [cfg.defaultAxisVisible=true] The default value of the DistanceMeasurements `axisVisible` property.\n   * @param {boolean} [cfg.defaultXAxisVisible=true] The default value of the DistanceMeasurements `xAxisVisible` property.\n   * @param {boolean} [cfg.defaultYAxisVisible=true] The default value of the DistanceMeasurements `yAxisVisible` property.\n   * @param {boolean} [cfg.defaultZAxisVisible=true] The default value of the DistanceMeasurements `zAxisVisible` property.\n   * @param {boolean} [cfg.useRotationAdjustment=false] The default value of DistanceMeasurements `useRotationAdjustment` property.\n   * @param {string} [cfg.defaultColor=#00BBFF] The default color of the length dots, wire and label.\n   * @param {number} [cfg.zIndex] If set, the wires, dots and labels will have this zIndex (+1 for dots and +2 for labels).\n   * @param {boolean} [cfg.defaultLabelsOnWires=true] The default value of the DistanceMeasurements `labelsOnWires` property.\n   * @param {PointerCircle} [cfg.pointerLens] A PointerLens to help the user position the pointer. This can be shared with other plugins.\n   */\n  constructor(viewer, cfg = {}) {\n    super(\"DistanceMeasurements\", viewer);\n\n    this._pointerLens = cfg.pointerLens;\n\n    this._container = cfg.container || document.body;\n\n    this._defaultControl = null;\n\n    this._measurements = {};\n\n    this.labelMinAxisLength = cfg.labelMinAxisLength;\n    this.defaultVisible = cfg.defaultVisible !== false;\n    this.defaultOriginVisible = cfg.defaultOriginVisible !== false;\n    this.defaultTargetVisible = cfg.defaultTargetVisible !== false;\n    this.defaultWireVisible = cfg.defaultWireVisible !== false;\n    this.defaultXLabelEnabled = cfg.defaultXLabelEnabled !== false;\n    this.defaultYLabelEnabled = cfg.defaultYLabelEnabled !== false;\n    this.defaultZLabelEnabled = cfg.defaultZLabelEnabled !== false;\n    this.defaultLengthLabelEnabled = cfg.defaultLengthLabelEnabled !== false;\n    this.defaultLabelsVisible = cfg.defaultLabelsVisible !== false;\n    this.defaultAxisVisible = cfg.defaultAxisVisible !== false;\n    this.defaultXAxisVisible = cfg.defaultXAxisVisible !== false;\n    this.defaultYAxisVisible = cfg.defaultYAxisVisible !== false;\n    this.defaultZAxisVisible = cfg.defaultZAxisVisible !== false;\n    this.defaultColor =cfg.defaultColor !== undefined ? cfg.defaultColor : \"#00BBFF\";\n    this.zIndex = cfg.zIndex || 10000;\n    this.defaultLabelsOnWires = cfg.defaultLabelsOnWires !== false;\n    this.useRotationAdjustment = cfg.useRotationAdjustment !== undefined ? cfg.useRotationAdjustment !== false : false;\n\n    this._onMouseOver = (event, measurement) => {\n      this.fire(\"mouseOver\", {\n        plugin: this,\n        distanceMeasurement: measurement,\n        measurement,\n        event,\n      });\n    };\n\n    this._onMouseLeave = (event, measurement) => {\n      this.fire(\"mouseLeave\", {\n        plugin: this,\n        distanceMeasurement: measurement,\n        measurement,\n        event,\n      });\n    };\n\n    this._onContextMenu = (event, measurement) => {\n      this.fire(\"contextMenu\", {\n        plugin: this,\n        distanceMeasurement: measurement,\n        measurement,\n        event,\n      });\n    };\n  }\n\n  /**\n   * Gets the plugin's HTML container element, if any.\n   * @returns {*|HTMLElement|HTMLElement}\n   */\n  getContainerElement() {\n    return this._container;\n  }\n\n  /**\n   * @private\n   */\n  send(name, value) {}\n\n  /**\n   * Gets the PointerLens attached to this DistanceMeasurementsPlugin.\n   * @returns {PointerCircle}\n   */\n  get pointerLens() {\n    return this._pointerLens;\n  }\n\n  /**\n   * Gets the default {@link DistanceMeasurementsControl}.\n   *\n   * @type {DistanceMeasurementsControl}\n   * @deprecated\n   */\n  get control() {\n    if (!this._defaultControl) {\n      this._defaultControl = new DistanceMeasurementsMouseControl(this, {});\n    }\n    return this._defaultControl;\n  }\n\n  /**\n   * Gets the existing {@link DistanceMeasurement}s, each mapped to its {@link DistanceMeasurement#id}.\n   *\n   * @type {{String:DistanceMeasurement}}\n   */\n  get measurements() {\n    return this._measurements;\n  }\n\n  /**\n   * Sets the minimum length, in pixels, of an axis wire beyond which its label is shown.\n   *\n   * The axis wire's label is not shown when its length is less than this value.\n   *\n   * This is ````25```` pixels by default.\n   *\n   * Must not be less than ````1````.\n   *\n   * @type {number}\n   */\n  set labelMinAxisLength(labelMinAxisLength) {\n    if (labelMinAxisLength < 1) {\n      this.error(\"labelMinAxisLength must be >= 1; defaulting to 25\");\n      labelMinAxisLength = 25;\n    }\n    this._labelMinAxisLength = labelMinAxisLength || 25;\n  }\n\n  /**\n   * Gets the minimum length, in pixels, of an axis wire beyond which its label is shown.\n   * @returns {number}\n   */\n  get labelMinAxisLength() {\n    return this._labelMinAxisLength;\n  }\n\n  /**\n   * Sets whether the measurement added is rotation adjusted or not.\n   *\n   * @type {boolean}\n   */\n  set useRotationAdjustment(_useRotationAdjustment) {\n    _useRotationAdjustment = _useRotationAdjustment !== undefined ? Boolean(_useRotationAdjustment) : false;\n    this._useRotationAdjustment = _useRotationAdjustment;\n  }\n\n  /**\n   * Gets whether the measurement added is rotation adjusted or not.\n   * @returns {number}\n   */\n  get useRotationAdjustment(){\n    return this._useRotationAdjustment;\n  }\n  /**\n   * Creates a {@link DistanceMeasurement}.\n   *\n   * The DistanceMeasurement is then registered by {@link DistanceMeasurement#id} in {@link DistanceMeasurementsPlugin#measurements}.\n   *\n   * @param {Object} params {@link DistanceMeasurement} configuration.\n   * @param {String} params.id Unique ID to assign to {@link DistanceMeasurement#id}. The DistanceMeasurement will be registered by this in {@link DistanceMeasurementsPlugin#measurements} and {@link Scene.components}. Must be unique among all components in the {@link Viewer}.\n   * @param {Number[]} params.origin.worldPos Origin World-space 3D position.\n   * @param {Entity} params.origin.entity Origin Entity.\n   * @param {Number[]} params.target.worldPos Target World-space 3D position.\n   * @param {Entity} params.target.entity Target Entity.\n   * @param {Boolean} [params.visible=true] Whether to initially show the {@link DistanceMeasurement}.\n   * @param {Boolean} [params.originVisible=true] Whether to initially show the {@link DistanceMeasurement} origin.\n   * @param {Boolean} [params.targetVisible=true] Whether to initially show the {@link DistanceMeasurement} target.\n   * @param {Boolean} [params.wireVisible=true] Whether to initially show the direct point-to-point wire between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.\n   * @param {Boolean} [params.axisVisible=true] Whether to initially show the axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.\n   * @param {Boolean} [params.xAxisVisible=true] Whether to initially show the X-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.\n   * @param {Boolean} [params.yAxisVisible=true] Whether to initially show the Y-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.\n   * @param {Boolean} [params.zAxisVisible=true] Whether to initially show the Z-axis-aligned wires between {@link DistanceMeasurement#origin} and {@link DistanceMeasurement#target}.\n   * @param {Boolean} [params.xLabelEnabled=true] Whether to initially show the x label.\n   * @param {Boolean} [params.yLabelEnabled=true] Whether to initially show the y label.\n   * @param {Boolean} [params.zLabelEnabled=true] Whether to initially show the z label.\n   * @param {Boolean} [params.lengthLabelEnabled=true] Whether to initially show the length label.\n   * @param {Boolean} [params.labelsVisible=true] Whether to initially show the labels.\n   * @param {Boolean} [params.lengthLabelVisible=true] Whether to initially show the labels.\n   * @param {string} [params.color] The color of the length dot, wire and label.\n   * @param {Boolean} [params.labelsOnWires=true] Determines if labels will be set on wires or one below the other.\n   * @returns {DistanceMeasurement} The new {@link DistanceMeasurement}.\n   */\n  createMeasurement(params = {}) {\n    if (this.viewer.scene.components[params.id]) {\n      this.error(\n        \"Viewer scene component with this ID already exists: \" + params.id\n      );\n      delete params.id;\n    }\n    const origin = params.origin;\n    const target = params.target;\n    const measurement = new DistanceMeasurement(this, {\n      id: params.id,\n      plugin: this,\n      container: this._container,\n      origin: {\n        entity: origin.entity,\n        worldPos: origin.worldPos,\n      },\n      target: {\n        entity: target.entity,\n        worldPos: target.worldPos,\n      },\n      visible: params.visible,\n      wireVisible: params.wireVisible,\n      axisVisible: params.axisVisible !== false && this.defaultAxisVisible !== false,\n      xAxisVisible: params.xAxisVisible !== false && this.defaultXAxisVisible !== false,\n      yAxisVisible: params.yAxisVisible !== false && this.defaultYAxisVisible !== false,\n      zAxisVisible: params.zAxisVisible !== false && this.defaultZAxisVisible !== false,\n      xLabelEnabled: params.xLabelEnabled !== false && this.defaultXLabelEnabled !== false,\n      yLabelEnabled: params.yLabelEnabled !== false && this.defaultYLabelEnabled !== false,\n      zLabelEnabled: params.zLabelEnabled !== false && this.defaultZLabelEnabled !== false,\n      lengthLabelEnabled: params.lengthLabelEnabled !== false && this.defaultLengthLabelEnabled !== false,\n      labelsVisible: params.labelsVisible !== false && this.defaultLabelsVisible !== false,\n      useRotationAdjustment: this.useRotationAdjustment,\n      originVisible: params.originVisible,\n      targetVisible: params.targetVisible,\n      color: params.color,\n      labelsOnWires:params.labelsOnWires !== false && this.defaultLabelsOnWires !== false,\n      onMouseOver: this._onMouseOver,\n      onMouseLeave: this._onMouseLeave,\n      onContextMenu: this._onContextMenu,\n    });\n    this._measurements[measurement.id] = measurement;\n    measurement.clickable = true;\n    measurement.on(\"destroyed\", () => {\n      delete this._measurements[measurement.id];\n    });\n    this.fire(\"measurementCreated\", measurement);\n    return measurement;\n  }\n\n  /**\n   * Destroys a {@link DistanceMeasurement}.\n   *\n   * @param {String} id ID of DistanceMeasurement to destroy.\n   */\n  destroyMeasurement(id) {\n    const measurement = this._measurements[id];\n    if (!measurement) {\n      this.log(\"DistanceMeasurement not found: \" + id);\n      return;\n    }\n    measurement.destroy();\n    this.fire(\"measurementDestroyed\", measurement);\n  }\n\n  /**\n   * Shows all or hides the distance label of each {@link DistanceMeasurement}.\n   *\n   * @param {Boolean} labelsShown Whether or not to show the labels.\n   */\n  setLabelsShown(labelsShown) {\n    for (const [key, measurement] of Object.entries(this.measurements)) {\n      measurement.labelShown = labelsShown;\n    }\n  }\n\n  /**\n   * Shows all or hides the axis wires of each {@link DistanceMeasurement}.\n   *\n   * @param {Boolean} labelsShown Whether or not to show the axis wires.\n   */\n  setAxisVisible(axisVisible) {\n    for (const [key, measurement] of Object.entries(this.measurements)) {\n      measurement.axisVisible = axisVisible;\n    }\n    this.defaultAxisVisible = axisVisible;\n  }\n\n  /**\n   * Gets if the axis wires of each {@link DistanceMeasurement} are visible.\n   *\n   * @returns {Boolean} Whether or not the axis wires are visible.\n   */\n  getAxisVisible() {\n    return this.defaultAxisVisible;\n  }\n\n  /**\n   * Destroys all {@link DistanceMeasurement}s.\n   */\n  clear() {\n    const ids = Object.keys(this._measurements);\n    for (var i = 0, len = ids.length; i < len; i++) {\n      this.destroyMeasurement(ids[i]);\n    }\n  }\n\n  /**\n   * Destroys this DistanceMeasurementsPlugin.\n   *\n   * Destroys all {@link DistanceMeasurement}s first.\n   */\n  destroy() {\n    this.clear();\n    super.destroy();\n  }\n}\n\nconst WAITING_FOR_ORIGIN_TOUCH_START = 0;\nconst WAITING_FOR_ORIGIN_QUICK_TOUCH_END = 1;\nconst WAITING_FOR_ORIGIN_LONG_TOUCH_END = 2;\n\nconst WAITING_FOR_TARGET_TOUCH_START = 3;\nconst WAITING_FOR_TARGET_QUICK_TOUCH_END = 4;\nconst WAITING_FOR_TARGET_LONG_TOUCH_END = 5;\n\nconst TOUCH_CANCELING = 7;\n\nconst tmpVec2 = math.vec2();\n\n/**\n * Creates {@link DistanceMeasurement}s from touch input.\n *\n * See {@link DistanceMeasurementsPlugin} for more info.\n *\n */\nclass DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {\n\n    /**\n     * Creates a DistanceMeasurementsTouchControl bound to the given DistanceMeasurementsPlugin.\n     */\n    constructor(distanceMeasurementsPlugin, cfg = {}) {\n\n        super(distanceMeasurementsPlugin.viewer.scene);\n\n        this.pointerLens = cfg.pointerLens;\n        this.pointerCircle = new PointerCircle(distanceMeasurementsPlugin.viewer);\n\n        this._active = false;\n\n        const markerDiv = document.createElement('div');\n        const canvas = this.scene.canvas.canvas;\n        canvas.parentNode.insertBefore(markerDiv, canvas);\n\n        markerDiv.style.background = \"black\";\n        markerDiv.style.border = \"2px solid blue\";\n        markerDiv.style.borderRadius = \"10px\";\n        markerDiv.style.width = \"5px\";\n        markerDiv.style.height = \"5px\";\n        markerDiv.style.margin = \"-200px -200px\";\n        markerDiv.style.zIndex = \"100\";\n        markerDiv.style.position = \"absolute\";\n        markerDiv.style.pointerEvents = \"none\";\n\n        this.markerDiv = markerDiv;\n\n        this._currentDistanceMeasurement = null;\n\n        this._currentDistanceMeasurementInitState = {\n            wireVisible: null,\n            axisVisible: null,\n            xAxisVisible: null,\n            yaxisVisible: null,\n            zAxisVisible: null,\n            targetVisible: null,\n        };\n\n        this._longTouchTimeoutMs = 300;\n        this._snapping = cfg.snapping !== false;\n\n        this._attachPlugin(distanceMeasurementsPlugin, cfg);\n    }\n\n    _attachPlugin(distanceMeasurementsPlugin) {\n\n        /**\n         * The {@link DistanceMeasurementsPlugin} that owns this DistanceMeasurementsTouchControl.\n         * @type {DistanceMeasurementsPlugin}\n         */\n        this.distanceMeasurementsPlugin = distanceMeasurementsPlugin;\n\n        /**\n         * The {@link DistanceMeasurementsPlugin} that owns this DistanceMeasurementsTouchControl.\n         * @type {DistanceMeasurementsPlugin}\n         */\n        this.plugin = distanceMeasurementsPlugin;\n    }\n\n    /** Gets if this DistanceMeasurementsTouchControl is currently active, where it is responding to input.\n     *\n     * @returns {Boolean}\n     */\n    get active() {\n        return this._active;\n    }\n\n    /**\n     * Sets whether snap-to-vertex and snap-to-edge are enabled for this DistanceMeasurementsTouchControl.\n     *\n     * This is `true` by default.\n     *\n     * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this DistanceMeasurementsTouchControl.\n     */\n    set snapping(snapping) {\n        this._snapping = snapping;\n    }\n\n    /**\n     * Gets whether snap-to-vertex and snap-to-edge are enabled for this DistanceMeasurementsTouchControl.\n     *\n     * This is `true` by default.\n     *\n     * @returns {boolean} Whether snap-to-vertex and snap-to-edge are enabled for this DistanceMeasurementsTouchControl.\n     */\n    get snapping() {\n        return this._snapping;\n    }\n\n    /**\n     * Activates this DistanceMeasurementsTouchControl, ready to respond to input.\n     */\n    activate() {\n\n        if (this._active) {\n            return;\n        }\n\n        const plugin = this.plugin;\n        const scene = this.scene;\n        const canvas = scene.canvas.canvas;\n        plugin.pointerLens;\n        const pointerWorldPos = math.vec3();\n\n        const touchTolerance = 20;\n\n        let longTouchTimeout = null;\n\n        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;\n\n        const touchStartCanvasPos = math.vec2();\n        const touchMoveCanvasPos = math.vec2();\n        const touchEndCanvasPos = math.vec2();\n\n        let touchId = null;\n\n        const disableCameraNavigation = () => {\n            this.plugin.viewer.cameraControl.active = false;\n        };\n\n        const enableCameraNavigation = () => {\n            this.plugin.viewer.cameraControl.active = true;\n        };\n\n        const cancel = () => {\n            if (longTouchTimeout) {\n                clearTimeout(longTouchTimeout);\n                longTouchTimeout = null;\n            }\n            if (this._currentDistanceMeasurement) {\n                this._currentDistanceMeasurement.destroy();\n                this._currentDistanceMeasurement = null;\n            }\n            enableCameraNavigation();\n            this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;\n        };\n\n        const copyCanvasPos = (event, dst) => {\n            dst[0] = event.clientX;\n            dst[1] = event.clientY;\n            transformToNode(canvas.ownerDocument.documentElement, canvas, dst);\n            return dst;\n        };\n\n        const toBodyPos = (pos, dst) => {\n            dst.set(pos);\n            transformToNode(canvas, canvas.ownerDocument.documentElement, dst);\n            return dst;\n        };\n\n        canvas.addEventListener(\"touchstart\", this._onCanvasTouchStart = (event) => {\n\n            const currentNumTouches = event.touches.length;\n\n            if (currentNumTouches !== 1) {\n                if (longTouchTimeout) {\n                    clearTimeout(longTouchTimeout);\n                    longTouchTimeout = null;\n                }\n                return;\n            }\n\n            const touch = event.touches[0];\n            copyCanvasPos(touch, touchStartCanvasPos);\n            touchMoveCanvasPos.set(touchStartCanvasPos);\n\n            switch (this._touchState) {\n\n                case WAITING_FOR_ORIGIN_TOUCH_START:\n                    if (currentNumTouches !== 1 && longTouchTimeout !== null) { // Two or more fingers down\n                        cancel();\n                        return;\n                    }\n                    const snapPickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        snapping: this._snapping,\n                        snapToEdge: this._snapping\n                    });\n                    if (snapPickResult && snapPickResult.snapped) {\n                        pointerWorldPos.set(snapPickResult.worldPos);\n                        this.pointerCircle.start(toBodyPos(snapPickResult.snappedCanvasPos, tmpVec2));\n                    } else {\n                        const pickResult = scene.pick({\n                            canvasPos: touchMoveCanvasPos,\n                            pickSurface: true\n                        });\n                        if (pickResult && pickResult.worldPos) {\n                            pointerWorldPos.set(pickResult.worldPos);\n                            this.pointerCircle.start(toBodyPos(pickResult.canvasPos, tmpVec2));\n                        } else {\n                            return;\n                        }\n                    }\n                    longTouchTimeout = setTimeout(() => {\n                        if (currentNumTouches !== 1 ||\n                            touchMoveCanvasPos[0] > touchStartCanvasPos[0] + touchTolerance ||\n                            touchMoveCanvasPos[0] < touchStartCanvasPos[0] - touchTolerance ||\n                            touchMoveCanvasPos[1] > touchStartCanvasPos[1] + touchTolerance ||\n                            touchMoveCanvasPos[1] < touchStartCanvasPos[1] - touchTolerance) {\n                            return;   // Has moved\n                        }\n                        // Long touch\n                        if (this.pointerLens) {\n                            this.pointerLens.visible = true;\n                            this.pointerLens.canvasPos = touchStartCanvasPos;\n                            this.pointerLens.cursorPos = touchStartCanvasPos;\n                        }\n                        if (this.pointerLens) {\n                            this.pointerLens.canvasPos = touchMoveCanvasPos;\n                            this.pointerLens.snapped = false;\n                        }\n                        if (this.pointerLens) {\n                            this.pointerLens.cursorPos = snapPickResult.canvasPos;\n                            this.pointerLens.snapped = true;\n                        }\n                        // pointerWorldPos.set(snapPickResult.snappedWorldPos);\n                        if (!this._currentDistanceMeasurement) {\n                            this._currentDistanceMeasurement = plugin.createMeasurement({\n                                id: math.createUUID(),\n                                origin: {\n                                    worldPos: pointerWorldPos,\n                                    entity: snapPickResult.entity\n                                },\n                                target: {\n                                    worldPos: pointerWorldPos,\n                                    entity: snapPickResult.entity\n                                }\n                            });\n                            this._currentDistanceMeasurement.labelsVisible = false;\n                            this._currentDistanceMeasurement.xAxisVisible = false;\n                            this._currentDistanceMeasurement.yAxisVisible = false;\n                            this._currentDistanceMeasurement.zAxisVisible = false;\n                            this._currentDistanceMeasurement.wireVisible = false;\n                            this._currentDistanceMeasurement.originVisible = true;\n                            this._currentDistanceMeasurement.targetVisible = false;\n                            this._currentDistanceMeasurement.clickable = false;\n                        } else {\n                            this._currentDistanceMeasurement.origin.worldPos = pointerWorldPos;\n                        }\n                        this.distanceMeasurementsPlugin.fire(\"measurementStart\", this._currentDistanceMeasurement);\n                        // if (this.pointerLens) {\n                        //     this.pointerLens.cursorPos = pickResult.canvasPos;\n                        //     this.pointerLens.snapped = false;\n                        // }\n                        this._touchState = WAITING_FOR_ORIGIN_LONG_TOUCH_END;\n                        // console.log(\"touchstart: this._touchState= WAITING_FOR_ORIGIN_TOUCH_START -> WAITING_FOR_ORIGIN_LONG_TOUCH_END\")\n                        disableCameraNavigation();\n                    }, this._longTouchTimeoutMs);\n                    this._touchState = WAITING_FOR_ORIGIN_QUICK_TOUCH_END;\n                    // console.log(\"touchstart: this._touchState= WAITING_FOR_ORIGIN_TOUCH_START -> WAITING_FOR_ORIGIN_QUICK_TOUCH_END\")\n\n                    touchId = touch.identifier;\n\n                    break;\n\n\n                case WAITING_FOR_TARGET_TOUCH_START:\n\n                    if (currentNumTouches !== 1 && longTouchTimeout !== null) { // Two or more fingers down\n                        clearTimeout(longTouchTimeout);\n                        longTouchTimeout = null;\n                        return;\n                    }\n                    if (currentNumTouches === 1) { // One finger down\n                        longTouchTimeout = setTimeout(() => {\n                            longTouchTimeout = null;\n                            if (currentNumTouches !== 1 ||\n                                touchMoveCanvasPos[0] > touchStartCanvasPos[0] + touchTolerance ||\n                                touchMoveCanvasPos[0] < touchStartCanvasPos[0] - touchTolerance ||\n                                touchMoveCanvasPos[1] > touchStartCanvasPos[1] + touchTolerance ||\n                                touchMoveCanvasPos[1] < touchStartCanvasPos[1] - touchTolerance) {\n                                // Has moved\n                                return;\n                            }\n\n                            // Long touch\n                            if (this.pointerLens) {\n                                this.pointerLens.visible = true;\n                                this.pointerLens.canvasPos = touchStartCanvasPos;\n                                this.pointerLens.snapped = false;\n                            }\n\n                            const snapPickResult = scene.pick({\n                                canvasPos: touchMoveCanvasPos,\n                                snapToVertex: this._snapping,\n                                snapToEdge: this._snapping\n                            });\n                            if (snapPickResult && snapPickResult.snapped) {\n                                if (this.pointerLens) {\n                                    this.pointerLens.cursorPos = snapPickResult.snappedCanvasPos;\n                                    this.pointerLens.snapped = true;\n                                }\n                                this.pointerCircle.start(toBodyPos(snapPickResult.snappedCanvasPos, tmpVec2));\n                                pointerWorldPos.set(snapPickResult.worldPos);\n                                this._currentDistanceMeasurement.target.worldPos = snapPickResult.worldPos;\n                                this._currentDistanceMeasurement.target.entity = snapPickResult.entity;\n                                this._currentDistanceMeasurement.targetVisible = true;\n                                this._currentDistanceMeasurement.wireVisible = true;\n                                this._currentDistanceMeasurement.labelsVisible = true;\n                                this.distanceMeasurementsPlugin.fire(\"measurementStart\", this._currentDistanceMeasurement);\n                            } else {\n                                const pickResult = scene.pick({\n                                    canvasPos: touchMoveCanvasPos,\n                                    pickSurface: true\n                                });\n                                if (pickResult && pickResult.worldPos) {\n                                    if (this.pointerLens) {\n                                        this.pointerLens.cursorPos = pickResult.canvasPos;\n                                        this.pointerLens.snapped = false;\n                                    }\n                                    this.pointerCircle.start(toBodyPos(pickResult.canvasPos, tmpVec2));\n                                    pointerWorldPos.set(pickResult.worldPos);\n                                    this._currentDistanceMeasurement.target.worldPos = pickResult.worldPos;\n                                    this._currentDistanceMeasurement.target.entity = pickResult.entity;\n                                    this._currentDistanceMeasurement.targetVisible = true;\n                                    this._currentDistanceMeasurement.wireVisible = true;\n                                    this._currentDistanceMeasurement.labelsVisible = true;\n                                    this.distanceMeasurementsPlugin.fire(\"measurementStart\", this._currentDistanceMeasurement);\n                                } else {\n                                    if (this.pointerLens) {\n                                        this.pointerLens.cursorPos = null;\n                                        this.pointerLens.snapped = false;\n\n                                    }\n                                }\n                            }\n                            this._touchState = WAITING_FOR_TARGET_LONG_TOUCH_END;\n                            // console.log(\"touchstart: this._touchState= WAITING_FOR_TARGET_TOUCH_START -> WAITING_FOR_TARGET_LONG_TOUCH_END\")\n\n                            disableCameraNavigation();\n\n                        }, this._longTouchTimeoutMs);\n\n                        this._touchState = WAITING_FOR_TARGET_QUICK_TOUCH_END;\n                        // console.log(\"touchstart: this._touchState= WAITING_FOR_TARGET_TOUCH_START -> WAITING_FOR_TARGET_QUICK_TOUCH_END\")\n                    }\n\n                    touchId = touch.identifier;\n\n                    break;\n\n                default:\n                    if (longTouchTimeout !== null) {\n                        clearTimeout(longTouchTimeout);\n                        longTouchTimeout = null;\n                    }\n                    this._touchState = TOUCH_CANCELING;\n                    // console.log(\"touchstart: this._touchState= default -> TOUCH_CANCELING\")\n                    return;\n            }\n\n        }, {passive: true});\n\n\n        canvas.addEventListener(\"touchmove\", (event) => {\n\n            this.pointerCircle.stop();\n\n            const currentNumTouches = event.touches.length;\n\n            if (currentNumTouches !== 1 || event.changedTouches.length !== 1) {\n                if (longTouchTimeout) {\n                    clearTimeout(longTouchTimeout);\n                    longTouchTimeout = null;\n                }\n                return;\n            }\n\n            const touch = event.touches[0];\n            if (touch.identifier !== touchId) {\n                return;\n            }\n\n            copyCanvasPos(touch, touchMoveCanvasPos);\n\n            let snapPickResult;\n            let pickResult;\n\n            switch (this._touchState) {\n\n                case WAITING_FOR_ORIGIN_LONG_TOUCH_END:\n                    if (this.pointerLens) {\n                        this.pointerLens.canvasPos = touchMoveCanvasPos;\n                    }\n                    snapPickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        snapToVertex: this._snapping,\n                        snapToEdge: this._snapping\n                    });\n                    if (snapPickResult && (snapPickResult.snapped)) {\n                        if (this.pointerLens) {\n                            this.pointerLens.snappedCanvasPos = snapPickResult.snappedCanvasPos;\n                            this.pointerLens.snapped = true;\n                        }\n                        pointerWorldPos.set(snapPickResult.worldPos);\n                        if (!this._currentDistanceMeasurement) {\n                            this._currentDistanceMeasurement = plugin.createMeasurement({\n                                id: math.createUUID(),\n                                origin: {\n                                    worldPos: snapPickResult.worldPos,\n                                    entity: snapPickResult.entity\n                                },\n                                target: {\n                                    worldPos: snapPickResult.worldPos,\n                                    entity: snapPickResult.entity\n                                }\n                            });\n                            this._currentDistanceMeasurement.labelsVisible = false;\n                            this._currentDistanceMeasurement.xAxisVisible = false;\n                            this._currentDistanceMeasurement.yAxisVisible = false;\n                            this._currentDistanceMeasurement.zAxisVisible = false;\n                            this._currentDistanceMeasurement.wireVisible = false;\n                            this._currentDistanceMeasurement.originVisible = true;\n                            this._currentDistanceMeasurement.targetVisible = false;\n                            this._currentDistanceMeasurement.clickable = false;\n                        } else {\n                            this._currentDistanceMeasurement.origin.worldPos = snapPickResult.worldPos;\n                        }\n\n                        this.distanceMeasurementsPlugin.fire(\"measurementStart\", this._currentDistanceMeasurement);\n                    } else {\n                        pickResult = scene.pick({\n                            canvasPos: touchMoveCanvasPos,\n                            pickSurface: true\n                        });\n                        if (pickResult && pickResult.worldPos) {\n                            if (this.pointerLens) {\n                                this.pointerLens.cursorPos = pickResult.canvasPos;\n                                this.pointerLens.snapped = false;\n                            }\n                            pointerWorldPos.set(pickResult.worldPos);\n                            if (!this._currentDistanceMeasurement) {\n                                this._currentDistanceMeasurement = plugin.createMeasurement({\n                                    id: math.createUUID(),\n                                    origin: {\n                                        worldPos: pickResult.worldPos,\n                                        entity: pickResult.entity\n                                    },\n                                    target: {\n                                        worldPos: pickResult.worldPos,\n                                        entity: pickResult.entity\n                                    }\n                                });\n                                this._currentDistanceMeasurement.labelsVisible = false;\n                                this._currentDistanceMeasurement.xAxisVisible = false;\n                                this._currentDistanceMeasurement.yAxisVisible = false;\n                                this._currentDistanceMeasurement.zAxisVisible = false;\n                                this._currentDistanceMeasurement.wireVisible = false;\n                                this._currentDistanceMeasurement.originVisible = true;\n                                this._currentDistanceMeasurement.targetVisible = false;\n                                this._currentDistanceMeasurement.clickable = false;\n                            } else {\n                                this._currentDistanceMeasurement.origin.worldPos = pickResult.worldPos;\n                            }\n\n                            this.distanceMeasurementsPlugin.fire(\"measurementStart\", this._currentDistanceMeasurement);\n                        } else {\n                            if (this.pointerLens) {\n                                this.pointerLens.cursorPos = null;\n                                this.pointerLens.snapped = false;\n                            }\n                        }\n                    }\n                    this._touchState = WAITING_FOR_ORIGIN_LONG_TOUCH_END;\n                    // console.log(\"touchmove: this._touchState= WAITING_FOR_ORIGIN_LONG_TOUCH_END -> WAITING_FOR_ORIGIN_LONG_TOUCH_END\")\n                    break;\n\n                // case WAITING_FOR_TARGET_TOUCH_START:\n                //     this._touchState = WAITING_FOR_TARGET_TOUCH_START;\n                //     console.log(\"touchmove: this._touchState= WAITING_FOR_TARGET_TOUCH_START -> WAITING_FOR_TARGET_TOUCH_START\")\n                //     break;\n\n                case WAITING_FOR_TARGET_LONG_TOUCH_END:\n                    if (currentNumTouches !== 1 && longTouchTimeout !== null) { // Two or more fingers down\n                        clearTimeout(longTouchTimeout);\n                        longTouchTimeout = null;\n                        if (this.pointerLens) {\n                            this.pointerLens.visible = false;\n                        }\n                        this._touchState = TOUCH_CANCELING;\n                        // console.log(\"touchmove: this._touchState= QUICK_TOUCH_FINDING_TARGET -> TOUCH_CANCELING\")\n                        return;\n                    }\n                    if (this.pointerLens) {\n                        this.pointerLens.canvasPos = touchMoveCanvasPos;\n                    }\n                    snapPickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        snapToVertex: this._snapping,\n                        snapToEdge: this._snapping\n                    });\n                    if (snapPickResult && snapPickResult.worldPos) {\n                        if (this.pointerLens) {\n                            this.pointerLens.cursorPos = snapPickResult.snappedCanvasPos;\n                            this.pointerLens.snapped = true;\n                        }\n                        this._currentDistanceMeasurement.target.worldPos = snapPickResult.worldPos;\n                        this._currentDistanceMeasurement.target.entity = snapPickResult.entity;\n                        this._currentDistanceMeasurement.targetVisible = true;\n                        this._currentDistanceMeasurement.wireVisible = true;\n                        this._currentDistanceMeasurement.labelsVisible = true;\n                    } else {\n                        pickResult = scene.pick({\n                            canvasPos: touchMoveCanvasPos,\n                            pickSurface: true\n                        });\n                        if (pickResult && pickResult.worldPos) {\n                            if (this.pointerLens) {\n                                this.pointerLens.cursorPos = pickResult.canvasPos;\n                                this.pointerLens.snapped = false;\n                            }\n                            this._currentDistanceMeasurement.target.worldPos = pickResult.worldPos;\n                            this._currentDistanceMeasurement.target.entity = pickResult.entity;\n                            this._currentDistanceMeasurement.targetVisible = true;\n                            this._currentDistanceMeasurement.wireVisible = true;\n                            this._currentDistanceMeasurement.labelsVisible = true;\n\n                        }\n                    }\n                    this._touchState = WAITING_FOR_TARGET_LONG_TOUCH_END;\n                    break;\n            }\n        }, {passive: true});\n\n        canvas.addEventListener(\"touchend\", this._onCanvasTouchEnd = (event) => {\n\n            this.pointerCircle.stop();\n\n            const numChangedTouches = event.changedTouches.length;\n\n            if (numChangedTouches !== 1) {\n                return;\n            }\n\n            const touch = event.changedTouches[0];\n            if (touch.identifier !== touchId) {\n                return;\n            }\n\n            if (longTouchTimeout) {\n                clearTimeout(longTouchTimeout);\n                longTouchTimeout = null;\n            }\n\n            copyCanvasPos(touch, touchEndCanvasPos);\n\n            const touchX = touchEndCanvasPos[0];\n            const touchY = touchEndCanvasPos[1];\n\n            switch (this._touchState) {\n\n                case WAITING_FOR_ORIGIN_QUICK_TOUCH_END: {\n                    if (numChangedTouches !== 1 ||\n                        touchX > touchStartCanvasPos[0] + touchTolerance ||\n                        touchX < touchStartCanvasPos[0] - touchTolerance ||\n                        touchY > touchStartCanvasPos[1] + touchTolerance ||\n                        touchY < touchStartCanvasPos[1] - touchTolerance) {\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;\n                        return;\n                    }\n                    const pickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        pickSurface: true\n                    });\n                    if (pickResult && pickResult.worldPos) {\n                        this._currentDistanceMeasurement = plugin.createMeasurement({\n                            id: math.createUUID(),\n                            origin: {\n                                worldPos: pickResult.worldPos,\n                                entity: pickResult.entity\n                            },\n                            target: {\n                                worldPos: pickResult.worldPos,\n                                entity: pickResult.entity\n                            }\n                        });\n                        this._currentDistanceMeasurement.labelsVisible = false;\n                        this._currentDistanceMeasurement.xAxisVisible = false;\n                        this._currentDistanceMeasurement.yAxisVisible = false;\n                        this._currentDistanceMeasurement.zAxisVisible = false;\n                        this._currentDistanceMeasurement.wireVisible = false;\n                        this._currentDistanceMeasurement.originVisible = true;\n                        this._currentDistanceMeasurement.targetVisible = false;\n                        this._currentDistanceMeasurement.clickable = false;\n                        this._touchState = WAITING_FOR_TARGET_TOUCH_START;\n                        this.distanceMeasurementsPlugin.fire(\"measurementStart\", this._currentDistanceMeasurement);\n                        //  console.log(\"touchend: this._touchState= WAITING_FOR_ORIGIN_QUICK_TOUCH_END -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    } else {\n                        if (this._currentDistanceMeasurement) {\n                            this._currentDistanceMeasurement.destroy();\n                        }\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;\n                        //  console.log(\"touchend: this._touchState= WAITING_FOR_ORIGIN_QUICK_TOUCH_END -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    }\n                }\n                    enableCameraNavigation();\n                    break;\n\n                case WAITING_FOR_ORIGIN_LONG_TOUCH_END:\n                    if (this.pointerLens) {\n                        this.pointerLens.visible = false;\n                    }\n                    if (!this._currentDistanceMeasurement) {\n                        if (this.pointerLens) {\n                            this.pointerLens.snapped = false;\n                            this.pointerLens.visible = false;\n                        }\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;\n                        //  console.log(\"touchend: this._touchState= WAITING_FOR_ORIGIN_LONG_TOUCH_END (no measurement) -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    } else {\n                        this._touchState = WAITING_FOR_TARGET_TOUCH_START;\n                        //  console.log(\"touchend: this._touchState= WAITING_FOR_ORIGIN_LONG_TOUCH_END (picked, begin measurement) -> WAITING_FOR_TARGET_TOUCH_START\")\n                    }\n                    enableCameraNavigation();\n                    break;\n\n                case WAITING_FOR_TARGET_QUICK_TOUCH_END: {\n                    if (numChangedTouches !== 1 ||\n                        touchX > touchStartCanvasPos[0] + touchTolerance ||\n                        touchX < touchStartCanvasPos[0] - touchTolerance ||\n                        touchY > touchStartCanvasPos[1] + touchTolerance ||\n                        touchY < touchStartCanvasPos[1] - touchTolerance) {\n                        this._touchState = WAITING_FOR_TARGET_TOUCH_START;\n                        return;\n                    }\n                    const pickResult = scene.pick({\n                        canvasPos: touchMoveCanvasPos,\n                        pickSurface: true\n                    });\n                    if (pickResult && pickResult.worldPos) {\n                        this._currentDistanceMeasurement.target.worldPos = pickResult.worldPos;\n                        this._currentDistanceMeasurement.target.entity = pickResult.entity;\n                        this._currentDistanceMeasurement.targetVisible = true;\n                        this._currentDistanceMeasurement.wireVisible = true;\n                        this._currentDistanceMeasurement.labelsVisible = true;\n                        this._currentDistanceMeasurement.xAxisVisible = true;\n                        this._currentDistanceMeasurement.yAxisVisible = true;\n                        this._currentDistanceMeasurement.zAxisVisible = true;\n                        this._currentDistanceMeasurement.clickable = true;\n                        this.distanceMeasurementsPlugin.fire(\"measurementEnd\", this._currentDistanceMeasurement);\n                        this._currentDistanceMeasurement = null;\n                    } else {\n                        if (this._currentDistanceMeasurement) {\n                            this._currentDistanceMeasurement.destroy();\n                            this._currentDistanceMeasurement = null;\n                        }\n                    }\n                    this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;\n                    //  console.log(\"touchend: this._touchState= WAITING_FOR_TARGET_TOUCH_START -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                }\n                    enableCameraNavigation();\n                    break;\n\n                case WAITING_FOR_TARGET_LONG_TOUCH_END:\n                    console.log('long touch');\n                    if (this.pointerLens) {\n                        this.pointerLens.visible = false;\n                    }\n                    if (!this._currentDistanceMeasurement || !this._currentDistanceMeasurement.targetVisible) {\n                        if (this._currentDistanceMeasurement) {\n                            this._currentDistanceMeasurement.destroy();\n                            this._currentDistanceMeasurement = null;\n                        }\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;\n                        //  console.log(\"touchend: this._touchState= WAITING_FOR_TARGET_LONG_TOUCH_END (no target found) -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    } else {\n                        this._currentDistanceMeasurement.clickable = true;\n                        this.distanceMeasurementsPlugin.fire(\"measurementEnd\", this._currentDistanceMeasurement);\n                        this._currentDistanceMeasurement = null;\n                        this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;\n                        //  console.log(\"touchend: this._touchState= WAITING_FOR_TARGET_LONG_TOUCH_END  -> WAITING_FOR_ORIGIN_TOUCH_START\")\n                    }\n                    enableCameraNavigation();\n                    break;\n            }\n\n        }, {passive: true});\n\n        this._active = true;\n    }\n\n    /**\n     * Deactivates this DistanceMeasurementsTouchControl, making it unresponsive to input.\n     *\n     * Destroys any {@link DistanceMeasurement} under construction.\n     */\n    deactivate() {\n        if (!this._active) {\n            return;\n        }\n        if (this.plugin.pointerLens) {\n            this.plugin.pointerLens.visible = false;\n        }\n        this.reset();\n\n        const canvas = this.plugin.viewer.scene.canvas.canvas;\n        canvas.removeEventListener(\"touchstart\", this._onCanvasTouchStart);\n        canvas.removeEventListener(\"touchend\", this._onCanvasTouchEnd);\n\n        this._active = false;\n        this.plugin.viewer.cameraControl.active = true;\n    }\n\n    /**\n     * Resets this DistanceMeasurementsTouchControl.\n     *\n     * Destroys any {@link DistanceMeasurement} under construction.\n     *\n     * Does nothing if the DistanceMeasurementsTouchControl is not active.\n     */\n    reset() {\n        if (!this._active) {\n            return;\n        }\n\n        if (this._currentDistanceMeasurement) {\n            this.distanceMeasurementsPlugin.fire(\"measurementCancel\", this._currentDistanceMeasurement);\n            this._currentDistanceMeasurement.destroy();\n            this._currentDistanceMeasurement = null;\n        }\n    }\n\n    /**\n     * Gets the {@link DistanceMeasurement} under construction by this DistanceMeasurementsTouchControl, if any.\n     *\n     * @returns {null|DistanceMeasurement}\n     */\n    get currentMeasurement() {\n        return this._currentDistanceMeasurement;\n    }\n\n    /**\n     * Destroys this DistanceMeasurementsTouchControl.\n     */\n    destroy() {\n        this.deactivate();\n        super.destroy();\n    }\n}\n\nclass DistanceMeasurementEditControl extends Component {\n\n    /**\n     * Edits {@link DistanceMeasurement} with mouse and/or touch input.\n     *\n     * @param {DistanceMeasurement} [measurement] The DistanceMeasurement to edit.\n     * @param [cfg] Configuration\n     * @param {PointerLens} [cfg.pointerLens] A PointerLens to use to provide a magnified view of the cursor.\n     * @param {boolean} [cfg.snapping] Whether to enable snap-to-vertex and snap-to-edge.\n     * @param {boolean} [handleMouseEvents] Whether to hangle mouse input.\n     * @param {boolean} [handleTouchEvents] Whether to hangle touch input.\n     */\n    constructor(measurement, cfg, handleMouseEvents, handleTouchEvents) {\n\n        const viewer = measurement.plugin.viewer;\n\n        super(viewer.scene);\n\n        const cleanup = activateDraggableDots({\n            viewer: viewer,\n            handleMouseEvents: handleMouseEvents,\n            handleTouchEvents: handleTouchEvents,\n            pointerLens: cfg.pointerLens,\n            dots: [ measurement.origin, measurement.target ],\n            ray2WorldPos: (orig, dir, canvasPos) => {\n                const tryPickWorldPos = snap => {\n                    const pickResult = viewer.scene.pick({\n                        canvasPos: canvasPos,\n                        snapToEdge: snap,\n                        snapToVertex: snap,\n                        pickSurface: true  // <<------ This causes picking to find the intersection point on the entity\n                    });\n\n                    // If - when snapping - no pick found, then try w/o snapping\n                    return (pickResult && pickResult.worldPos) ? pickResult.worldPos : (snap && tryPickWorldPos(false));\n                };\n\n                return tryPickWorldPos(!!cfg.snapping);\n            },\n            onEnd: (initPos, dot) => {\n                const changed = ! math.compareVec3(initPos, dot.worldPos);\n                if (changed) {\n                    this.fire(\"edited\");\n                }\n                return changed;\n            }\n        });\n\n        const destroyCb = measurement.on(\"destroyed\", cleanup);\n\n        this._deactivate = function() {\n            measurement.off(\"destroyed\", destroyCb);\n            cleanup();\n        };\n    }\n\n    deactivate() {\n        this._deactivate();\n        super.destroy();\n    }\n}\n\nclass DistanceMeasurementEditMouseControl extends DistanceMeasurementEditControl {\n    constructor(zone, cfg) {\n        super(zone, cfg, true, false);\n    }\n}\n\nclass DistanceMeasurementEditTouchControl extends DistanceMeasurementEditControl {\n    constructor(zone, cfg) {\n        super(zone, cfg, false, true);\n    }\n}\n\n/**\n * {@link Viewer} plugin that makes interaction smoother with large models, by temporarily switching\n * the Viewer to faster, lower-quality rendering modes whenever we interact.\n *\n * [<img src=\"https://xeokit.io/img/docs/FastNavPlugin/FastNavPlugin.gif\">](https://xeokit.github.io/xeokit-sdk/examples/index.html#performance_FastNavPlugin)\n *\n * FastNavPlugin works by hiding specified Viewer rendering features, and optionally scaling the Viewer's canvas\n * resolution, whenever we interact with the Viewer. Then, once we've finished interacting, FastNavPlugin restores those\n * rendering features and the original canvas scale, after a configured delay.\n *\n * Depending on how we configure FastNavPlugin, we essentially switch to a smooth-rendering low-quality view while\n * interacting, then return to the normal higher-quality view after we stop, following an optional delay.\n *\n * Down-scaling the canvas resolution gives particularly good results. For example, scaling by ````0.5```` means that\n * we're rendering a quarter of the pixels while interacting, which can make the Viewer noticeably smoother with big models.\n *\n * The screen capture above shows FastNavPlugin in action. In this example, whenever we move the Camera or resize the Canvas,\n * FastNavPlugin switches off enhanced edges and ambient shadows (SAO), and down-scales the canvas, making it slightly\n * blurry. When ````0.5```` seconds passes with no interaction, the plugin shows edges and SAO again, and restores the\n * original canvas scale.\n *\n * # Usage\n *\n * In the example below, we'll create a {@link Viewer}, add a {@link FastNavPlugin}, then use an {@link XKTLoaderPlugin} to load a model.\n *\n * Whenever we interact with the Viewer, our FastNavPlugin will:\n *\n * * hide edges,\n * * hide ambient shadows (SAO),\n * * hide physically-based materials (switching to non-PBR),\n * * hide transparent objects, and\n * * scale the canvas resolution by 0.5, causing the GPU to render 75% less pixels.\n * <br>\n *\n * We'll also configure a 0.5 second delay before we transition back to high-quality each time we stop ineracting, so that we're\n * not continually flipping between low and high quality as we interact. Since we're only rendering ambient shadows when not interacting, we'll also treat ourselves\n * to expensive, high-quality SAO settings, that we wouldn't normally configure for an interactive SAO effect.\n *\n * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#performance_FastNavPlugin)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, FastNavPlugin} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer with PBR and SAO enabled\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true,\n *      pbr: true,                          // Enable physically-based rendering for Viewer\n *      sao: true                           // Enable ambient shadows for Viewer\n *  });\n *\n * viewer.scene.camera.eye = [-66.26, 105.84, -281.92];\n * viewer.scene.camera.look = [42.45, 49.62, -43.59];\n * viewer.scene.camera.up = [0.05, 0.95, 0.15];\n *\n * // Higher-quality SAO settings\n *\n * viewer.scene.sao.enabled = true;\n * viewer.scene.sao.numSamples = 60;\n * viewer.scene.sao.kernelRadius = 170;\n *\n * // Install a FastNavPlugin\n *\n * new FastNavPlugin(viewer, {\n *      hideEdges: true,                // Don't show edges while we interact (default is true)\n *      hideSAO: true,                  // Don't show ambient shadows while we interact (default is true)\n *      hideColorTexture: true,        // No color textures while we interact (default is true)\n *      hidePBR: true,                  // No physically-based rendering while we interact (default is true)\n *      hideTransparentObjects: true,   // Hide transparent objects while we interact (default is false)\n *      scaleCanvasResolution: true,    // Scale canvas resolution while we interact (default is false)\n *      defaultScaleCanvasResolutionFactor: 1.0, // Factor by which we scale canvas resolution when we stop interacting (default is 1.0)\n *      scaleCanvasResolutionFactor: 0.5,  // Factor by which we scale canvas resolution when we interact (default is 0.6)\n *      delayBeforeRestore: true,       // When we stop interacting, delay before restoring normal render (default is true)\n *      delayBeforeRestoreSeconds: 0.5  // The delay duration, in seconds (default is 0.5)\n * });\n *\n * // Load a BIM model from XKT\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *      id: \"myModel\",\n *      src: \"./models/xkt/HolterTower.xkt\",\n *      sao: true,                          // Enable ambient shadows for this model\n *      pbr: true                           // Enable physically-based rendering for this model\n * });\n * ````\n *\n * @class FastNavPlugin\n */\nclass FastNavPlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg FastNavPlugin configuration.\n     * @param {String} [cfg.id=\"FastNav\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {Boolean} [cfg.hideColorTexture=true] Whether to temporarily hide color textures whenever we interact with the Viewer.\n     * @param {Boolean} [cfg.hidePBR=true] Whether to temporarily hide physically-based rendering (PBR) whenever we interact with the Viewer.\n     * @param {Boolean} [cfg.hideSAO=true] Whether to temporarily hide scalable ambient occlusion (SAO) whenever we interact with the Viewer.\n     * @param {Boolean} [cfg.hideEdges=true] Whether to temporarily hide edges whenever we interact with the Viewer.\n     * @param {Boolean} [cfg.hideTransparentObjects=false] Whether to temporarily hide transparent objects whenever we interact with the Viewer.\n     * @param {Number} [cfg.scaleCanvasResolution=false] Whether to temporarily down-scale the canvas resolution whenever we interact with the Viewer.\n     * @param {Number} [cfg.defaultScaleCanvasResolutionFactor=0.6] The factor by which we downscale the canvas resolution whenever we stop interacting with the Viewer.\n     * @param {Number} [cfg.scaleCanvasResolutionFactor=0.6] The factor by which we downscale the canvas resolution whenever we interact with the Viewer.\n     * @param {Boolean} [cfg.delayBeforeRestore=true] Whether to temporarily have a delay before restoring normal rendering after we stop interacting with the Viewer.\n     * @param {Number} [cfg.delayBeforeRestoreSeconds=0.5] Delay in seconds before restoring normal rendering after we stop interacting with the Viewer.\n     * @param {Function} [cfg.onMoved] Optional callback function fired during moving mode, should return the callback function that will be fired when the interaction stops.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"FastNav\", viewer);\n\n        this._hideColorTexture = cfg.hideColorTexture !== false;\n        this._hidePBR = cfg.hidePBR !== false;\n        this._hideSAO = cfg.hideSAO !== false;\n        this._hideEdges = cfg.hideEdges !== false;\n        this._hideTransparentObjects = !!cfg.hideTransparentObjects;\n        this._scaleCanvasResolution = !!cfg.scaleCanvasResolution;\n        this._defaultScaleCanvasResolutionFactor = cfg.defaultScaleCanvasResolutionFactor;\n        this._scaleCanvasResolutionFactor = cfg.scaleCanvasResolutionFactor || 0.6;\n        this._delayBeforeRestore = (cfg.delayBeforeRestore !== false);\n        this._delayBeforeRestoreSeconds = cfg.delayBeforeRestoreSeconds || 0.5;\n        this._onMoved = cfg.onMoved;\n        this._onStopped = null;\n\n        let timer = this._delayBeforeRestoreSeconds * 1000;\n        let fastMode = false;\n\n        const switchToLowQuality = () => {\n            timer = (this._delayBeforeRestoreSeconds * 1000);\n            if (!fastMode) {\n                viewer.scene._renderer.setColorTextureEnabled(!this._hideColorTexture);\n                viewer.scene._renderer.setPBREnabled(!this._hidePBR);\n                viewer.scene._renderer.setSAOEnabled(!this._hideSAO);\n                viewer.scene._renderer.setTransparentEnabled(!this._hideTransparentObjects);\n                viewer.scene._renderer.setEdgesEnabled(!this._hideEdges);\n                this._originalCanvasResolutionScale = viewer.scene.canvas.resolutionScale;\n                if (this._scaleCanvasResolution) {\n                    viewer.scene.canvas.resolutionScale = this._scaleCanvasResolutionFactor;\n                } else {\n                    viewer.scene.canvas.resolutionScale = this._defaultScaleCanvasResolutionFactor;\n                }\n                if (this._onMoved) {\n                    this._onStopped = this._onMoved();\n                }\n\n                fastMode = true;\n            }\n        };\n\n        const switchToHighQuality = () => {\n            viewer.scene.canvas.resolutionScale = this._defaultScaleCanvasResolutionFactor || this._originalCanvasResolutionScale || 1.0;\n            viewer.scene._renderer.setEdgesEnabled(true);\n            viewer.scene._renderer.setColorTextureEnabled(true);\n            viewer.scene._renderer.setPBREnabled(true);\n            viewer.scene._renderer.setSAOEnabled(true);\n            viewer.scene._renderer.setTransparentEnabled(true);\n            if (this._onStopped) {\n                this._onStopped();\n            }\n            fastMode = false;\n        };\n\n        this._onCameraMatrix = viewer.scene.camera.on(\"matrix\", switchToLowQuality);\n\n        this._onSceneTick = viewer.scene.on(\"tick\", (tickEvent) => {\n            if (!fastMode) {\n                return;\n            }\n            timer -= tickEvent.deltaTime;\n            if ((!this._delayBeforeRestore) || timer <= 0) {\n                switchToHighQuality();\n            }\n        });\n    }\n\n    /**\n     * Gets whether to temporarily hide color textures whenever we interact with the Viewer.\n     *\n     * Default is ````true````.\n     *\n     * @return {Boolean} ````true```` if hiding color textures.\n     */\n    get hideColorTexture() {\n        return this._hideColorTexture;\n    }\n\n    /**\n     * Sets whether to temporarily hide color textures whenever we interact with the Viewer.\n     *\n     * Default is ````true````.\n     *\n     * @param {Boolean} hideColorTexture ````true```` to hide color textures.\n     */\n    set hideColorTexture(hideColorTexture) {\n        this._hideColorTexture = hideColorTexture;\n    }\n    \n    /**\n     * Gets whether to temporarily hide physically-based rendering (PBR) whenever we interact with the Viewer.\n     *\n     * Default is ````true````.\n     *\n     * @return {Boolean} ````true```` if hiding PBR.\n     */\n    get hidePBR() {\n        return this._hidePBR;\n    }\n\n    /**\n     * Sets whether to temporarily hide physically-based rendering (PBR) whenever we interact with the Viewer.\n     *\n     * Default is ````true````.\n     *\n     * @param {Boolean} hidePBR ````true```` to hide PBR.\n     */\n    set hidePBR(hidePBR) {\n        this._hidePBR = hidePBR;\n    }\n\n    /**\n     * Gets whether to temporarily hide scalable ambient shadows (SAO) whenever we interact with the Viewer.\n     *\n     * Default is ````true````.\n     *\n     * @return {Boolean} ````true```` if hiding SAO.\n     */\n    get hideSAO() {\n        return this._hideSAO;\n    }\n\n    /**\n     * Sets whether to temporarily hide scalable ambient shadows (SAO) whenever we interact with the Viewer.\n     *\n     * Default is ````true````.\n     *\n     * @param {Boolean} hideSAO ````true```` to hide SAO.\n     */\n    set hideSAO(hideSAO) {\n        this._hideSAO = hideSAO;\n    }\n\n    /**\n     * Gets whether to temporarily hide edges whenever we interact with the Viewer.\n     *\n     * Default is ````true````.\n     *\n     * @return {Boolean}  ````true```` if hiding edges.\n     */\n    get hideEdges() {\n        return this._hideEdges;\n    }\n\n    /**\n     * Sets whether to temporarily hide edges whenever we interact with the Viewer.\n     *\n     * Default is ````true````.\n     *\n     * @param {Boolean} hideEdges ````true```` to hide edges.\n     */\n    set hideEdges(hideEdges) {\n        this._hideEdges = hideEdges;\n    }\n\n    /**\n     * Gets whether to temporarily hide transparent objects whenever we interact with the Viewer.\n     *\n     * Does not hide X-rayed, selected, highlighted objects.\n     *\n     * Default is ````false````.\n     *\n     * @return {Boolean} ````true```` if hiding transparent objects.\n     */\n    get hideTransparentObjects() {\n        return this._hideTransparentObjects\n    }\n\n    /**\n     * Sets whether to temporarily hide transparent objects whenever we interact with the Viewer.\n     *\n     * Does not hide X-rayed, selected, highlighted objects.\n     *\n     * Default is ````false````.\n     *\n     * @param {Boolean} hideTransparentObjects ````true```` to hide transparent objects.\n     */\n    set hideTransparentObjects(hideTransparentObjects) {\n        this._hideTransparentObjects = (hideTransparentObjects !== false);\n    }\n\n    /**\n     * Gets whether to temporarily scale the canvas resolution whenever we interact with the Viewer.\n     *\n     * Default is ````false````.\n     *\n     * The scaling factor is configured via {@link FastNavPlugin#scaleCanvasResolutionFactor}.\n     *\n     * @return {Boolean} ````true```` if scaling the canvas resolution.\n     */\n    get scaleCanvasResolution() {\n        return this._scaleCanvasResolution;\n    }\n\n    /**\n     * Sets the factor to which we restore the canvas resolution scale when we stop interacting with the viewer.\n     *\n     * Default is ````false````.\n     *\n     * The scaling factor is configured via {@link FastNavPlugin#scaleCanvasResolutionFactor}.\n     *\n     * @param {Boolean} scaleCanvasResolution ````true```` to scale the canvas resolution.\n     */\n    set scaleCanvasResolution(scaleCanvasResolution) {\n        this._scaleCanvasResolution = scaleCanvasResolution;\n    }\n\n    /**\n     * Gets the factor to which we restore the canvas resolution scale when we stop interacting with the viewer.\n     *\n     * Default is ````1.0````.\n     *\n     * Enable canvas resolution scaling by setting {@link FastNavPlugin#scaleCanvasResolution} ````true````.\n     *\n     * @return {Number} Factor by scale canvas resolution when we stop interacting with the viewer.\n     */\n    get defaultScaleCanvasResolutionFactor() {\n        return this._defaultScaleCanvasResolutionFactor;\n    }\n\n    /**\n     * Sets the factor to which we restore the canvas resolution scale when we stop interacting with the viewer.\n     *\n     * Accepted range is ````[0.0 .. 1.0]````.\n     *\n     * Default is ````1.0````.\n     *\n     * Enable canvas resolution scaling by setting {@link FastNavPlugin#scaleCanvasResolution} ````true````.\n     *\n     * @param {Number} defaultScaleCanvasResolutionFactor Factor by scale canvas resolution when we stop interacting with the viewer.\n     */\n    set defaultScaleCanvasResolutionFactor(defaultScaleCanvasResolutionFactor) {\n        this._defaultScaleCanvasResolutionFactor = defaultScaleCanvasResolutionFactor;\n    }\n\n    /**\n     * Gets the factor by which we temporarily scale the canvas resolution when we interact with the viewer.\n     *\n     * Default is ````0.6````.\n     *\n     * Enable canvas resolution scaling by setting {@link FastNavPlugin#scaleCanvasResolution} ````true````.\n     *\n     * @return {Number} Factor by which we scale the canvas resolution.\n     */\n    get scaleCanvasResolutionFactor() {\n        return this._scaleCanvasResolutionFactor;\n    }\n\n    /**\n     * Sets the factor by which we temporarily scale the canvas resolution when we interact with the viewer.\n     *\n     * Accepted range is ````[0.0 .. 1.0]````.\n     *\n     * Default is ````0.6````.\n     *\n     * Enable canvas resolution scaling by setting {@link FastNavPlugin#scaleCanvasResolution} ````true````.\n     *\n     * @param {Number} scaleCanvasResolutionFactor Factor by which we scale the canvas resolution.\n     */\n    set scaleCanvasResolutionFactor(scaleCanvasResolutionFactor) {\n        this._scaleCanvasResolutionFactor = scaleCanvasResolutionFactor || 0.6;\n    }\n\n    /**\n     * Gets whether to have a delay before restoring normal rendering after we stop interacting with the Viewer.\n     *\n     * The delay duration is configured via {@link FastNavPlugin#delayBeforeRestoreSeconds}.\n     *\n     * Default is ````true````.\n     *\n     * @return {Boolean} Whether to have a delay.\n     */\n    get delayBeforeRestore() {\n        return this._delayBeforeRestore;\n    }\n\n    /**\n     * Sets whether to have a delay before restoring normal rendering after we stop interacting with the Viewer.\n     *\n     * The delay duration is configured via {@link FastNavPlugin#delayBeforeRestoreSeconds}.\n     *\n     * Default is ````true````.\n     *\n     * @param {Boolean} delayBeforeRestore Whether to have a delay.\n     */\n    set delayBeforeRestore(delayBeforeRestore) {\n        this._delayBeforeRestore = delayBeforeRestore;\n    }\n\n    /**\n     * Gets the delay before restoring normal rendering after we stop interacting with the Viewer.\n     *\n     * The delay is enabled when {@link FastNavPlugin#delayBeforeRestore} is ````true````.\n     *\n     * Default is ````0.5```` seconds.\n     *\n     * @return {Number} Delay in seconds.\n     */\n    get delayBeforeRestoreSeconds() {\n        return this._delayBeforeRestoreSeconds;\n    }\n\n    /**\n     * Sets the delay before restoring normal rendering after we stop interacting with the Viewer.\n     *\n     * The delay is enabled when {@link FastNavPlugin#delayBeforeRestore} is ````true````.\n     *\n     * Default is ````0.5```` seconds.\n     *\n     * @param {Number} delayBeforeRestoreSeconds Delay in seconds.\n     */\n    set delayBeforeRestoreSeconds(delayBeforeRestoreSeconds) {\n        this._delayBeforeRestoreSeconds = delayBeforeRestoreSeconds !== null && delayBeforeRestoreSeconds !== undefined ? delayBeforeRestoreSeconds : 0.5;\n    }\n\n    /**\n     * @private\n     */\n    send(name, value) {\n    }\n\n    /**\n     * Destroys this plugin.\n     */\n    destroy() {\n        this.viewer.scene.camera.off(this._onCameraMatrix);\n        this.viewer.scene.canvas.off(this._onCanvasBoundary);\n        this.viewer.scene.input.off(this._onSceneMouseDown);\n        this.viewer.scene.input.off(this._onSceneMouseUp);\n        this.viewer.scene.input.off(this._onSceneMouseMove);\n        this.viewer.scene.off(this._onSceneTick);\n        super.destroy();\n    }\n}\n\n/**\n * Default data access strategy for {@link GLTFLoaderPlugin}.\n *\n * This just loads assets using XMLHttpRequest.\n */\nclass GLTFDefaultDataSource {\n\n    constructor(cfg = {}) {\n        this.cacheBuster = (cfg.cacheBuster !== false);\n    }\n\n    _cacheBusterURL(url) {\n        if (!this.cacheBuster) {\n            return url;\n        }\n        const timestamp = new Date().getTime();\n        if (url.indexOf('?') > -1) {\n            return url + '&_=' + timestamp;\n        } else {\n            return url + '?_=' + timestamp;\n        }\n    }\n\n    /**\n     * Gets metamodel JSON.\n     *\n     * @param {String|Number} metaModelSrc Identifies the metamodel JSON asset.\n     * @param {Function} ok Fired on successful loading of the metamodel JSON asset.\n     * @param {Function} error Fired on error while loading the metamodel JSON asset.\n     */\n    getMetaModel(metaModelSrc, ok, error) {\n        utils.loadJSON(this._cacheBusterURL(metaModelSrc),\n            (json) => {\n                ok(json);\n            },\n            function (errMsg) {\n                error(errMsg);\n            });\n    }\n\n    /**\n     * Gets glTF JSON.\n     *\n     * @param {String|Number} glTFSrc Identifies the glTF JSON asset.\n     * @param {Function} ok Fired on successful loading of the glTF JSON asset.\n     * @param {Function} error Fired on error while loading the glTF JSON asset.\n     */\n    getGLTF(glTFSrc, ok, error) {\n        utils.loadArraybuffer(this._cacheBusterURL(glTFSrc),\n            (gltf) => {\n                ok(gltf);\n            },\n            function (errMsg) {\n                error(errMsg);\n            });\n    }\n\n    /**\n     * Gets binary glTF file.\n     *\n     * @param {String|Number} glbSrc Identifies the .glb asset.\n     * @param {Function} ok Fired on successful loading of the .glb asset.\n     * @param {Function} error Fired on error while loading the .glb asset.\n     */\n    getGLB(glbSrc, ok, error) {\n        utils.loadArraybuffer(this._cacheBusterURL(glbSrc),\n            (arraybuffer) => {\n                ok(arraybuffer);\n            },\n            function (errMsg) {\n                error(errMsg);\n            });\n    }\n\n    /**\n     * Gets glTF binary attachment.\n     *\n     * Note that this method requires the source of the glTF JSON asset. This is because the binary attachment\n     * source could be relative to the glTF source, IE. it may not be a global ID.\n     *\n     * @param {String|Number} glTFSrc Identifies the glTF JSON asset.\n     * @param {String|Number} binarySrc Identifies the glTF binary asset.\n     * @param {Function} ok Fired on successful loading of the glTF binary asset.\n     * @param {Function} error Fired on error while loading the glTF binary asset.\n     */\n    getArrayBuffer(glTFSrc, binarySrc, ok, error) {\n        loadArraybuffer(this._cacheBusterURL(glTFSrc), binarySrc,\n            (arrayBuffer) => {\n                ok(arrayBuffer);\n            },\n            function (errMsg) {\n                error(errMsg);\n            });\n    }\n}\n\nfunction loadArraybuffer(glTFSrc, binarySrc, ok, err) {\n    // Check for data: URI\n    var defaultCallback = () => {\n    };\n    ok = ok || defaultCallback;\n    err = err || defaultCallback;\n    const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n    const dataUriRegexResult = binarySrc.match(dataUriRegex);\n    if (dataUriRegexResult) { // Safari can't handle data URIs through XMLHttpRequest\n        const isBase64 = !!dataUriRegexResult[2];\n        var data = dataUriRegexResult[3];\n        data = window.decodeURIComponent(data);\n        if (isBase64) {\n            data = window.atob(data);\n        }\n        try {\n            const buffer = new ArrayBuffer(data.length);\n            const view = new Uint8Array(buffer);\n            for (var i = 0; i < data.length; i++) {\n                view[i] = data.charCodeAt(i);\n            }\n            core.scheduleTask(function () {\n                ok(buffer);\n            });\n        } catch (error) {\n            core.scheduleTask(function () {\n                err(error);\n            });\n        }\n    } else {\n        const basePath = getBasePath$1(glTFSrc);\n        const url = basePath + binarySrc;\n        const request = new XMLHttpRequest();\n        request.open('GET', url, true);\n        request.responseType = 'arraybuffer';\n        request.onreadystatechange = function () {\n            if (request.readyState === 4) {\n                if (request.status === 200) {\n                    ok(request.response);\n                } else {\n                    err('loadArrayBuffer error : ' + request.response);\n                }\n            }\n        };\n        request.send(null);\n    }\n}\n\nfunction getBasePath$1(src) {\n    var i = src.lastIndexOf(\"/\");\n    return (i !== 0) ? src.substring(0, i + 1) : \"\";\n}\n\n/**\n * @private\n */\nclass GLTFSceneModelLoader {\n\n    constructor(cfg) {\n    }\n\n    load(plugin, src, metaModelJSON, options, sceneModel, ok, error) {\n        options = options || {};\n        loadGLTF(plugin, src, metaModelJSON, options, sceneModel, function () {\n                core.scheduleTask(function () {\n                    sceneModel.scene.fire(\"modelLoaded\", sceneModel.id); // FIXME: Assumes listeners know order of these two events\n                    sceneModel.fire(\"loaded\", true, false);\n                });\n                if (ok) {\n                    ok();\n                }\n            },\n            function (msg) {\n                plugin.error(msg);\n                if (error) {\n                    error(msg);\n                }\n                sceneModel.fire(\"error\", msg);\n            });\n    }\n\n    parse(plugin, gltf, metaModelJSON, options, sceneModel, ok, error) {\n        options = options || {};\n        parseGLTF(plugin, \"\", gltf, metaModelJSON, options, sceneModel, function () {\n                sceneModel.scene.fire(\"modelLoaded\", sceneModel.id); // FIXME: Assumes listeners know order of these two events\n                sceneModel.fire(\"loaded\", true, false);\n                if (ok) {\n                    ok();\n                }\n            },\n            function (msg) {\n                sceneModel.error(msg);\n                sceneModel.fire(\"error\", msg);\n                if (error) {\n                    error(msg);\n                }\n            });\n    }\n}\n\nfunction loadGLTF(plugin, src, metaModelJSON, options, sceneModel, ok, error) {\n    const spinner = plugin.viewer.scene.canvas.spinner;\n    spinner.processes++;\n    const isGLB = (src.split('.').pop() === \"glb\");\n    if (isGLB) {\n        plugin.dataSource.getGLB(src, (arrayBuffer) => { // OK\n                options.basePath = getBasePath(src);\n                parseGLTF(plugin, src, arrayBuffer, metaModelJSON, options, sceneModel, ok, error);\n                spinner.processes--;\n            },\n            (err) => {\n                spinner.processes--;\n                error(err);\n            });\n    } else {\n        plugin.dataSource.getGLTF(src, (gltf) => { // OK\n                options.basePath = getBasePath(src);\n                parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok, error);\n                spinner.processes--;\n            },\n            (err) => {\n                spinner.processes--;\n                error(err);\n            });\n    }\n}\n\nfunction getBasePath(src) {\n    const i = src.lastIndexOf(\"/\");\n    return (i !== 0) ? src.substring(0, i + 1) : \"\";\n}\n\nfunction parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok, error) {\n    const spinner = plugin.viewer.scene.canvas.spinner;\n    spinner.processes++;\n    parse$4(gltf, GLTFLoader, {\n        baseUri: options.basePath\n    }).then((gltfData) => {\n        const processedGLTF = postProcessGLTF(gltfData);\n        const ctx = {\n            src: src,\n            entityId: options.entityId,\n            metaModelJSON,\n            autoMetaModel: options.autoMetaModel,\n            globalizeObjectIds: options.globalizeObjectIds,\n            metaObjects: [],\n            loadBuffer: options.loadBuffer,\n            basePath: options.basePath,\n            handlenode: options.handlenode,\n            backfaces: !!options.backfaces,\n            gltfData: processedGLTF,\n            scene: sceneModel.scene,\n            plugin: plugin,\n            sceneModel: sceneModel,\n            //geometryCreated: {},\n            numObjects: 0,\n            nodes: [],\n            nextId: 0,\n            log: (msg) => {\n                plugin.log(msg);\n            }\n        };\n        loadTextures(ctx);\n        loadMaterials(ctx);\n        if (options.autoMetaModel) {\n          ctx.metaObjects.push({\n              id: sceneModel.id,\n              type: \"Default\",\n              name: sceneModel.id\n          });\n        }\n        loadDefaultScene(ctx);\n        sceneModel.finalize();\n        if (options.autoMetaModel) {\n            plugin.viewer.metaScene.createMetaModel(sceneModel.id, {\n                metaObjects: ctx.metaObjects\n            });\n        }\n        spinner.processes--;\n        ok();\n    }).catch((err) => {\n        if (error) error(err);\n    });\n}\n\nfunction loadTextures(ctx) {\n    const gltfData = ctx.gltfData;\n    const textures = gltfData.textures;\n    if (textures) {\n        for (let i = 0, len = textures.length; i < len; i++) {\n            loadTexture(ctx, textures[i]);\n        }\n    }\n}\n\nfunction loadTexture(ctx, texture) {\n    if (!texture.source || !texture.source.image) {\n        return;\n    }\n    const textureId = `texture-${ctx.nextId++}`;\n\n    let minFilter = NearestMipMapLinearFilter;\n    switch (texture.sampler.minFilter) {\n        case 9728:\n            minFilter = NearestFilter;\n            break;\n        case 9729:\n            minFilter = LinearFilter;\n            break;\n        case 9984:\n            minFilter = NearestMipMapNearestFilter;\n            break;\n        case 9985:\n            minFilter = LinearMipMapNearestFilter;\n            break;\n        case 9986:\n            minFilter = NearestMipMapLinearFilter;\n            break;\n        case 9987:\n            minFilter = LinearMipMapLinearFilter;\n            break;\n    }\n\n    let magFilter = LinearFilter;\n    switch (texture.sampler.magFilter) {\n        case 9728:\n            magFilter = NearestFilter;\n            break;\n        case 9729:\n            magFilter = LinearFilter;\n            break;\n    }\n\n    let wrapS = RepeatWrapping;\n    switch (texture.sampler.wrapS) {\n        case 33071:\n            wrapS = ClampToEdgeWrapping;\n            break;\n        case 33648:\n            wrapS = MirroredRepeatWrapping;\n            break;\n        case 10497:\n            wrapS = RepeatWrapping;\n            break;\n    }\n\n    let wrapT = RepeatWrapping;\n    switch (texture.sampler.wrapT) {\n        case 33071:\n            wrapT = ClampToEdgeWrapping;\n            break;\n        case 33648:\n            wrapT = MirroredRepeatWrapping;\n            break;\n        case 10497:\n            wrapT = RepeatWrapping;\n            break;\n    }\n\n    let wrapR = RepeatWrapping;\n    switch (texture.sampler.wrapR) {\n        case 33071:\n            wrapR = ClampToEdgeWrapping;\n            break;\n        case 33648:\n            wrapR = MirroredRepeatWrapping;\n            break;\n        case 10497:\n            wrapR = RepeatWrapping;\n            break;\n    }\n    ctx.sceneModel.createTexture({\n        id: textureId,\n        image: texture.source.image,\n        flipY: !!texture.flipY,\n        minFilter,\n        magFilter,\n        wrapS,\n        wrapT,\n        wrapR,\n        encoding: sRGBEncoding\n    });\n    texture._textureId = textureId;\n}\n\nfunction loadMaterials(ctx) {\n    const gltfData = ctx.gltfData;\n    const materials = gltfData.materials;\n    if (materials) {\n        for (let i = 0, len = materials.length; i < len; i++) {\n            const material = materials[i];\n            material._textureSetId = loadTextureSet(ctx, material);\n            material._attributes = loadMaterialAttributes(ctx, material);\n        }\n    }\n}\n\nfunction loadTextureSet(ctx, material) {\n    const textureSetCfg = {};\n    if (material.normalTexture) {\n        textureSetCfg.normalTextureId = material.normalTexture.texture._textureId;\n    }\n    if (material.occlusionTexture) {\n        textureSetCfg.occlusionTextureId = material.occlusionTexture.texture._textureId;\n    }\n    if (material.emissiveTexture) {\n        textureSetCfg.emissiveTextureId = material.emissiveTexture.texture._textureId;\n    }\n\n    switch (material.alphaMode) {\n        case \"OPAQUE\":\n            break;\n        case \"MASK\":\n            const alphaCutoff = material.alphaCutoff;\n            // Default from the spec https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-material\n            textureSetCfg.alphaCutoff = (alphaCutoff !== undefined) ? alphaCutoff : 0.5;\n            break;\n    }\n\n    const metallicPBR = material.pbrMetallicRoughness;\n    if (material.pbrMetallicRoughness) {\n        const pbrMetallicRoughness = material.pbrMetallicRoughness;\n        const baseColorTexture = pbrMetallicRoughness.baseColorTexture || pbrMetallicRoughness.colorTexture;\n        if (baseColorTexture) {\n            if (baseColorTexture.texture) {\n                textureSetCfg.colorTextureId = baseColorTexture.texture._textureId;\n            } else {\n                textureSetCfg.colorTextureId = ctx.gltfData.textures[baseColorTexture.index]._textureId;\n            }\n        }\n        if (metallicPBR.metallicRoughnessTexture) {\n            textureSetCfg.metallicRoughnessTextureId = metallicPBR.metallicRoughnessTexture.texture._textureId;\n        }\n    }\n    const extensions = material.extensions;\n    if (extensions) {\n        const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n        if (specularPBR) {\n            specularPBR.specularTexture;\n            const specularColorTexture = specularPBR.specularColorTexture;\n            if (specularColorTexture !== null && specularColorTexture !== undefined) {\n                textureSetCfg.colorTextureId = ctx.gltfData.textures[specularColorTexture.index]._textureId;\n            }\n        }\n    }\n    if (textureSetCfg.normalTextureId !== undefined ||\n        textureSetCfg.occlusionTextureId !== undefined ||\n        textureSetCfg.emissiveTextureId !== undefined ||\n        textureSetCfg.colorTextureId !== undefined ||\n        textureSetCfg.metallicRoughnessTextureId !== undefined) {\n        textureSetCfg.id = `textureSet-${ctx.nextId++};`;\n        ctx.sceneModel.createTextureSet(textureSetCfg);\n        return textureSetCfg.id;\n    }\n    return null;\n}\n\nfunction loadMaterialAttributes(ctx, material) { // Substitute RGBA for material, to use fast flat shading instead\n    const extensions = material.extensions;\n    const materialAttributes = {\n        color: new Float32Array([1, 1, 1, 1]),\n        opacity: 1,\n        metallic: 0,\n        roughness: 1,\n        doubleSided: true\n    };\n    if (extensions) {\n        const specularPBR = extensions[\"KHR_materials_pbrSpecularGlossiness\"];\n        if (specularPBR) {\n            const diffuseFactor = specularPBR.diffuseFactor;\n            if (diffuseFactor !== null && diffuseFactor !== undefined) {\n                materialAttributes.color.set(diffuseFactor);\n            }\n        }\n        const common = extensions[\"KHR_materials_common\"];\n        if (common) {\n            const technique = common.technique;\n            const values = common.values || {};\n            const blinn = technique === \"BLINN\";\n            const phong = technique === \"PHONG\";\n            const lambert = technique === \"LAMBERT\";\n            const diffuse = values.diffuse;\n            if (diffuse && (blinn || phong || lambert)) {\n                if (!utils.isString(diffuse)) {\n                    materialAttributes.color.set(diffuse);\n                }\n            }\n            const transparency = values.transparency;\n            if (transparency !== null && transparency !== undefined) {\n                materialAttributes.opacity = transparency;\n            }\n            const transparent = values.transparent;\n            if (transparent !== null && transparent !== undefined) {\n                materialAttributes.opacity = transparent;\n            }\n        }\n    }\n    const metallicPBR = material.pbrMetallicRoughness;\n    if (metallicPBR) {\n        const baseColorFactor = metallicPBR.baseColorFactor;\n        if (baseColorFactor) {\n            materialAttributes.color[0] = baseColorFactor[0];\n            materialAttributes.color[1] = baseColorFactor[1];\n            materialAttributes.color[2] = baseColorFactor[2];\n            materialAttributes.opacity = baseColorFactor[3];\n        }\n        const metallicFactor = metallicPBR.metallicFactor;\n        if (metallicFactor !== null && metallicFactor !== undefined) {\n            materialAttributes.metallic = metallicFactor;\n        }\n        const roughnessFactor = metallicPBR.roughnessFactor;\n        if (roughnessFactor !== null && roughnessFactor !== undefined) {\n            materialAttributes.roughness = roughnessFactor;\n        }\n    }\n    materialAttributes.doubleSided = (material.doubleSided !== false);\n    return materialAttributes;\n}\n\nfunction loadDefaultScene(ctx) {\n    const gltfData = ctx.gltfData;\n    const scene = gltfData.scene || gltfData.scenes[0];\n    if (!scene) {\n        error(ctx, \"glTF has no default scene\");\n        return;\n    }\n\n    const nodes = scene.nodes;\n    if (!nodes) {\n        return;\n    }\n\n    (function accumulateMeshInstantes(nodes) {\n        nodes.forEach(node => {\n            const mesh = node.mesh;\n            if (mesh) {\n                mesh.instances ||= 0;\n                mesh.instances += 1;\n            }\n            if (node.children) {\n                accumulateMeshInstantes(node.children);\n            }\n        });\n    })(nodes);\n\n    // Create a SceneMesh for each mesh primitive, and a SceneModelEntity for the root node and each named node.\n    const meshIdsStack = [];\n    let meshIds = null;\n    (function createSceneMeshesAndEntities(nodes, depth, parentMatrix) {\n        nodes.forEach(node => {\n            const nodeName = node.name;\n            let entityId = (((nodeName !== undefined) && (nodeName !== null) && nodeName)\n                            ||\n                            ((depth === 0) && (\"entity-\" + ctx.nextId++)));\n\n            if (entityId) {\n                while (ctx.sceneModel.objects[entityId]) {\n                    entityId = \"entity-\" + ctx.nextId++;\n                }\n                meshIdsStack.push(meshIds);\n                meshIds = [];\n            }\n\n            const matrix = parseNodeMatrix(node, parentMatrix);\n\n            if (node.mesh) {\n                parseNodeMesh(node, ctx, matrix, meshIds);\n            }\n\n            if (node.children) {\n                createSceneMeshesAndEntities(node.children, depth + 1, matrix);\n            }\n\n            if (entityId) {\n                if (meshIds.length > 0) {\n                    const globalId = ctx.globalizeObjectIds ? math.globalizeObjectId(ctx.sceneModel.id, entityId) : entityId;\n                    ctx.sceneModel.createEntity({\n                        id: globalId,\n                        meshIds: meshIds,\n                        isObject: true\n                    });\n                    if (ctx.autoMetaModel) {\n                        ctx.metaObjects.push({\n                            id: globalId,\n                            type: \"Default\",\n                            name: globalId,\n                            parent: ctx.sceneModel.id\n                        });\n                    }\n                }\n                meshIds = meshIdsStack.pop();\n            }\n        });\n    })(nodes, 0, null);\n}\n/**\n * Parses transform at the given glTF node.\n *\n * @param node the glTF node\n * @param matrix Transfor matrix from parent nodes\n * @returns {*} Transform matrix for the node\n */\nfunction parseNodeMatrix(node, matrix) {\n    let localMatrix;\n    if (node.matrix) {\n        localMatrix = node.matrix;\n        if (matrix) {\n            matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n        } else {\n            matrix = localMatrix;\n        }\n    }\n    if (node.translation) {\n        localMatrix = math.translationMat4v(node.translation);\n        if (matrix) {\n            matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n        } else {\n            matrix = localMatrix;\n        }\n    }\n    if (node.rotation) {\n        localMatrix = math.quaternionToMat4(node.rotation);\n        if (matrix) {\n            matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n        } else {\n            matrix = localMatrix;\n        }\n    }\n    if (node.scale) {\n        localMatrix = math.scalingMat4v(node.scale);\n        if (matrix) {\n            matrix = math.mulMat4(matrix, localMatrix, math.mat4());\n        } else {\n            matrix = localMatrix;\n        }\n    }\n    return matrix;\n}\n\n/**\n * Parses primitives referenced by the mesh belonging to the given node, creating XKTMeshes in the XKTModel.\n *\n * @param node glTF node\n * @param ctx Parsing context\n * @param matrix Matrix for the XKTMeshes\n * @param meshIds returns IDs of the new XKTMeshes\n */\nfunction parseNodeMesh(node, ctx, matrix, meshIds) {\n    const mesh = node.mesh;\n    if (!mesh) {\n        return;\n    }\n    const numPrimitives = mesh.primitives.length;\n    if (numPrimitives > 0) {\n        for (let i = 0; i < numPrimitives; i++) {\n            const primitive = mesh.primitives[i];\n            if (primitive.mode < 4) {\n                continue;\n            }\n            const meshCfg = {\n                id: ctx.sceneModel.id + \".\" + ctx.numObjects++\n            };\n            const material = primitive.material;\n            if (material) {\n                meshCfg.textureSetId = material._textureSetId;\n                meshCfg.color = material._attributes.color;\n                meshCfg.opacity = material._attributes.opacity;\n                meshCfg.metallic = material._attributes.metallic;\n                meshCfg.roughness = material._attributes.roughness;\n            } else {\n                meshCfg.color = new Float32Array([1.0, 1.0, 1.0]);\n                meshCfg.opacity = 1.0;\n            }\n            const backfaces = ((ctx.backfaces !== false) || (material && material.doubleSided !== false));\n            switch (primitive.mode) {\n                case 0: // POINTS\n                    meshCfg.primitive = \"points\";\n                    break;\n                case 1: // LINES\n                    meshCfg.primitive = \"lines\";\n                    break;\n                case 2: // LINE_LOOP\n                    meshCfg.primitive = \"lines\";\n                    break;\n                case 3: // LINE_STRIP\n                    meshCfg.primitive = \"lines\";\n                    break;\n                case 4: // TRIANGLES\n                    meshCfg.primitive = backfaces ? \"triangles\" : \"solid\";\n                    break;\n                case 5: // TRIANGLE_STRIP\n                    meshCfg.primitive = backfaces ? \"triangles\" : \"solid\";\n                    break;\n                case 6: // TRIANGLE_FAN\n                    meshCfg.primitive = backfaces ? \"triangles\" : \"solid\";\n                    break;\n                default:\n                    meshCfg.primitive = backfaces ? \"triangles\" : \"solid\";\n            }\n            const POSITION = primitive.attributes.POSITION;\n            if (!POSITION) {\n                continue;\n            }\n            meshCfg.localPositions = POSITION.value;\n            meshCfg.positions = new Float64Array(meshCfg.localPositions.length);\n            if (primitive.attributes.NORMAL) {\n                meshCfg.normals = primitive.attributes.NORMAL.value;\n            }\n            if (primitive.attributes.TEXCOORD_0) {\n                meshCfg.uv = primitive.attributes.TEXCOORD_0.value;\n            }\n            if (primitive.indices) {\n                meshCfg.indices = primitive.indices.value;\n            }\n            if (matrix) {\n                math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);\n            } else { // eqiv to math.transformPositions3(math.identityMat4(), meshCfg.localPositions, meshCfg.positions);\n                meshCfg.positions.set(meshCfg.localPositions);\n            }\n            const origin = math.vec3();\n            const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy\n            if (rtcNeeded) {\n                meshCfg.origin = origin;\n            }\n            ctx.sceneModel.createMesh(meshCfg);\n            meshIds.push(meshCfg.id);\n        }\n    }\n}\n\nfunction error(ctx, msg) {\n    ctx.plugin.error(msg);\n}\n\n/**\n * @desc Default initial properties for {@link Entity}s loaded from models accompanied by metadata.\n *\n * When loading a model, plugins such as {@link XKTLoaderPlugin} create\n * a tree of {@link Entity}s that represent the model. These loaders can optionally load metadata, to create\n * a {@link MetaModel} corresponding to the root {@link Entity}, with a {@link MetaObject} corresponding to each\n * object {@link Entity} within the tree.\n *\n * @type {{String:Object}}\n */\nconst IFCObjectDefaults = {\n\n    DEFAULT: {\n    }\n};\n\n/**\n * {@link Viewer} plugin that loads models from [glTF](https://www.khronos.org/gltf/).\n *\n * * Loads all glTF formats, including embedded and binary formats.\n * * Loads physically-based materials and textures.\n * * Creates an {@link Entity} representing each model it loads, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.\n * * Creates an {@link Entity} for each object within the model, which is indicated by each glTF ````node```` that has a ````name```` attribute. Those Entities will have {@link Entity#isObject} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.\n * * When loading, can set the World-space position, scale and rotation of each model within World space, along with initial properties for all the model's {@link Entity}s.\n * * Not recommended for large models. For best performance with large glTF datasets, we recommend first converting them\n * to ````.xkt```` format (eg. using [convert2xkt](https://github.com/xeokit/xeokit-convert)), then loading\n * the ````.xkt```` using {@link XKTLoaderPlugin}.\n *\n * ## Metadata\n *\n * GLTFLoaderPlugin can also load an accompanying JSON metadata file with each model, which creates a {@link MetaModel} corresponding\n * to the model {@link Entity} and a {@link MetaObject} corresponding to each object {@link Entity}.\n *\n * Each {@link MetaObject} has a {@link MetaObject#type}, which indicates the classification of its corresponding {@link Entity}. When loading\n * metadata, we can also provide GLTFLoaderPlugin with a custom lookup table of initial values to set on the properties of each type of {@link Entity}. By default, GLTFLoaderPlugin\n * uses its own map of default colors and visibilities for IFC element types.\n *\n * ## Usage\n *\n * In the example below we'll load a house plan model from a [binary glTF file](/examples/models/gltf/schependomlaan/), along\n * with an accompanying JSON [IFC metadata file](/examples/metaModels/schependomlaan/).\n *\n * This will create a bunch of {@link Entity}s that represents the model and its objects, along with a {@link MetaModel} and {@link MetaObject}s\n * that hold their metadata.\n *\n * Since this model contains IFC types, the GLTFLoaderPlugin will set the initial colors of object {@link Entity}s according\n * to the standard IFC element colors in the GLTFModel's current map. Override that with your own map via property {@link GLTFLoaderPlugin#objectDefaults}.\n *\n * Read more about this example in the user guide on [Viewing BIM Models Offline](https://www.notion.so/xeokit/Viewing-an-IFC-Model-with-xeokit-c373e48bc4094ff5b6e5c5700ff580ee).\n *\n * ````javascript\n * import {Viewer, GLTFLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // 1. Create a Viewer,\n * // 2. Arrange the camera,\n * // 3. Tweak the selection material (tone it down a bit)\n * //------------------------------------------------------------------------------------------------------------------\n *\n * // 1\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * // 2\n * viewer.camera.orbitPitch(20);\n * viewer.camera.orbitYaw(-45);\n *\n * // 3\n * viewer.scene.selectedMaterial.fillAlpha = 0.1;\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // 1. Create a glTF loader plugin,\n * // 2. Load a glTF building model and JSON IFC metadata\n * // 3. Emphasis the edges to make it look nice\n * //------------------------------------------------------------------------------------------------------------------\n *\n * // 1\n * const gltfLoader = new GLTFLoaderPlugin(viewer);\n *\n * // 2\n * var model = gltfLoader.load({                                    // Returns an Entity that represents the model\n *      id: \"myModel\",\n *      src: \"./models/gltf/OTCConferenceCenter/scene.gltf\",\n *      metaModelSrc: \"./models/gltf/OTCConferenceCenter/metaModel.json\",     // Creates a MetaModel (see below)\n *      edges: true\n * });\n *\n * model.on(\"loaded\", () => {\n *\n *      //--------------------------------------------------------------------------------------------------------------\n *      // 1. Find metadata on the third storey\n *      // 2. Select all the objects in the building's third storey\n *      // 3. Fit the camera to all the objects on the third storey\n *      //--------------------------------------------------------------------------------------------------------------\n *\n *      // 1\n *      const metaModel = viewer.metaScene.metaModels[\"myModel\"];       // MetaModel with ID \"myModel\"\n *      const metaObject\n *          = viewer.metaScene.metaObjects[\"0u4wgLe6n0ABVaiXyikbkA\"];   // MetaObject with ID \"0u4wgLe6n0ABVaiXyikbkA\"\n *\n *      const name = metaObject.name;                                   // \"01 eerste verdieping\"\n *      const type = metaObject.type;                                   // \"IfcBuildingStorey\"\n *      const parent = metaObject.parent;                               // MetaObject with type \"IfcBuilding\"\n *      const children = metaObject.children;                           // Array of child MetaObjects\n *      const objectId = metaObject.id;                                 // \"0u4wgLe6n0ABVaiXyikbkA\"\n *      const objectIds = viewer.metaScene.getObjectIDsInSubtree(objectId);   // IDs of leaf sub-objects\n *      const aabb = viewer.scene.getAABB(objectIds);                   // Axis-aligned boundary of the leaf sub-objects\n *\n *      // 2\n *      viewer.scene.setObjectsSelected(objectIds, true);\n *\n *      // 3\n *      viewer.cameraFlight.flyTo(aabb);\n * });\n *\n * // Find the model Entity by ID\n * model = viewer.scene.models[\"myModel\"];\n *\n * // Destroy the model\n * model.destroy();\n * ````\n *\n * ## Transforming\n *\n * We have the option to rotate, scale and translate each  *````.glTF````* model as we load it.\n *\n * This lets us load multiple models, or even multiple copies of the same model, and position them apart from each other.\n *\n * In the example below, we'll scale our model to half its size, rotate it 90 degrees about its local X-axis, then\n * translate it 100 units along its X axis.\n *\n * ````javascript\n * const model = gltfLoader.load({\n *      src: \"./models/gltf/Duplex/scene.gltf\",\n *      metaModelSrc: \"./models/gltf/Duplex/Duplex.json\",\n *      rotation: [90,0,0],\n *      scale: [0.5, 0.5, 0.5],\n *      position: [100, 0, 0]\n * });\n * ````\n *\n * ## Including and excluding IFC types\n *\n * We can also load only those objects that have the specified IFC types. In the example below, we'll load only the\n * objects that represent walls.\n *\n * ````javascript\n * const model = gltfLoader.load({\n *     id: \"myModel\",\n *      src: \"./models/gltf/OTCConferenceCenter/scene.gltf\",\n *      metaModelSrc: \"./models/gltf/OTCConferenceCenter/metaModel.json\",\n *      includeTypes: [\"IfcWallStandardCase\"]\n * });\n * ````\n *\n * We can also load only those objects that **don't** have the specified IFC types. In the example below, we'll load only the\n * objects that do not represent empty space.\n *\n * ````javascript\n * const model = gltfLoader.load({\n *     id: \"myModel\",\n *      src: \"./models/gltf/OTCConferenceCenter/scene.gltf\",\n *      metaModelSrc: \"./models/gltf/OTCConferenceCenter/metaModel.json\",\n *      excludeTypes: [\"IfcSpace\"]\n * });\n * ````\n *\n * ## Showing a glTF model in TreeViewPlugin when metadata is not available\n *\n * When GLTFLoaderPlugin loads a glTF model, it creates an object Entity for each `node` in the glTF `scene` hierarchy that has a\n * `name` attribute, giving the Entity an ID that has the value of the `name` attribute.\n *\n * Those name attributes are created by converter tools, such as by [IFC2GLTFCxConverter](https://github.com/Creoox/creoox-ifc2gltfcxconverter) when it generates glTF from IFC files. However, those name attributes are not\n * ordinarily present in glTF that comes from other sources, such as LiDAR scanners. For such glTF models, GLTFLoaderPlugin\n * will create Entities, but they will have randomly-generated IDs, and therefore cannot be associated with MetaObjects in any\n * MetaModels that we create alongside the model.\n *\n * For glTF models containing `nodes` that don't have `name` attributes, we can use the `load()` method's `elementId` parameter\n * to make GLTFLoaderPlugin load the entire model into a single Entity that gets this ID.\n *\n * In conjunction with that parameter, we can then use the `load()` method's `metaModelJSON` parameter to create a MetaModel that\n * contains a MetaObject that corresponds to that Entity.\n *\n * When we've done that, then xeokit's {@link TreeViewPlugin} is able to have a node that represents the glTF model and controls\n * the visibility of that Entity (ie. to control the visibility of the entire model).\n *\n * The snippet below shows how this is done.\n *\n * ````javascript\n * import {Viewer, GLTFLoaderPlugin, NavCubePlugin, TreeViewPlugin} from \"../../dist/xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * new TreeViewPlugin(viewer, {\n *     containerElement: document.getElementById(\"treeViewContainer\"),\n *     hierarchy: \"containment\"\n * });\n *\n * const gltfLoader = new GLTFLoaderPlugin(viewer);\n *\n * const sceneModel = gltfLoader.load({ // Creates a SceneModel with ID \"myScanModel\"\n *     id: \"myScanModel\",\n *     src: \"public-use-sample-apartment.glb\",\n *\n *     //-------------------------------------------------------------------------\n *     // Specify an `elementId` parameter, which causes the\n *     // entire model to be loaded into a single Entity that gets this ID.\n *     //-------------------------------------------------------------------------\n *\n *     entityId: \"3toKckUfH2jBmd$7uhJHa4\", // Creates an Entity with this ID\n *\n *     //-------------------------------------------------------------------------\n *     // Specify a `metaModelJSON` parameter, which creates a\n *     // MetaModel with two MetaObjects, one of which corresponds\n *     // to our Entity. Then the TreeViewPlugin is able to have a node\n *     // that can represent the model and control the visibility of the Entity.\n *     //--------------------------------------------------------------------------\n *\n *    metaModelJSON: { // Creates a MetaModel with ID \"myScanModel\"\n *         \"metaObjects\": [\n *             {\n *                 \"id\": \"3toKckUfH2jBmd$7uhJHa6\", // Creates a MetaObject with this ID\n *                 \"name\": \"My Project\",\n *                 \"type\": \"Default\",\n *                 \"parent\": null\n *             },\n *             {\n *                 \"id\": \"3toKckUfH2jBmd$7uhJHa4\", // Creates a MetaObject with this ID (same ID as our Entity)\n *                 \"name\": \"My Scan\",\n *                 \"type\": \"Default\",\n *                 \"parent\": \"3toKckUfH2jBmd$7uhJHa6\"\n *             }\n *         ]\n *     }\n * });\n * ````\n * @class GLTFLoaderPlugin\n */\nclass GLTFLoaderPlugin extends Plugin {\n\n    /**\n     * @constructor\n     *\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"GLTFLoader\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {Object} [cfg.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object.  Default value is {@link IFCObjectDefaults}.\n     * @param {Object} [cfg.dataSource] A custom data source through which the GLTFLoaderPlugin can load metadata, glTF and binary attachments. Defaults to an instance of {@link GLTFDefaultDataSource}, which loads over HTTP.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"GLTFLoader\", viewer, cfg);\n\n        this._sceneModelLoader = new GLTFSceneModelLoader(this, cfg);\n\n        this.dataSource = cfg.dataSource;\n        this.objectDefaults = cfg.objectDefaults;\n    }\n\n    /**\n     * Sets a custom data source through which the GLTFLoaderPlugin can load metadata, glTF and binary attachments.\n     *\n     * Default value is {@link GLTFDefaultDataSource}, which loads via an XMLHttpRequest.\n     *\n     * @type {Object}\n     */\n    set dataSource(value) {\n        this._dataSource = value || new GLTFDefaultDataSource();\n    }\n\n    /**\n     * Gets the custom data source through which the GLTFLoaderPlugin can load metadata, glTF and binary attachments.\n     *\n     * Default value is {@link GLTFDefaultDataSource}, which loads via an XMLHttpRequest.\n     *\n     * @type {Object}\n     */\n    get dataSource() {\n        return this._dataSource;\n    }\n\n    /**\n     * Sets map of initial default states for each loaded {@link Entity} that represents an object.\n     *\n     * Default value is {@link IFCObjectDefaults}.\n     *\n     * @type {{String: Object}}\n     */\n    set objectDefaults(value) {\n        this._objectDefaults = value || IFCObjectDefaults;\n    }\n\n    /**\n     * Gets map of initial default states for each loaded {@link Entity} that represents an object.\n     *\n     * Default value is {@link IFCObjectDefaults}.\n     *\n     * @type {{String: Object}}\n     */\n    get objectDefaults() {\n        return this._objectDefaults;\n    }\n\n    /**\n     * Loads a glTF model from a file into this GLTFLoaderPlugin's {@link Viewer}.\n     *\n     * @param {*} params Loading parameters.\n     * @param {String} [params.id] ID to assign to the root {@link Entity#id}, unique among all components in the Viewer's {@link Scene}, generated automatically by default.\n     * @param {String} [params.src] Path to a glTF file, as an alternative to the ````gltf```` parameter.\n     * @param {*} [params.gltf] glTF JSON, as an alternative to the ````src```` parameter.\n     * @param {String} [params.metaModelSrc] Path to an optional metadata file, as an alternative to the ````metaModelJSON```` parameter.\n     * @param {*} [params.metaModelJSON] JSON model metadata, as an alternative to the ````metaModelSrc```` parameter.\n     * @param {{String:Object}} [params.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.\n     * @param {Boolean} [params.edges=false] Whether or not xeokit renders the model with edges emphasized.\n     * @param {Number[]} [params.origin=[0,0,0]] The double-precision World-space origin of the model's coordinates.\n     * @param {Number[]} [params.position=[0,0,0]] The single-precision position, relative to ````origin````.\n     * @param {Number[]} [params.scale=[1,1,1]] The model's scale.\n     * @param {Number[]} [params.rotation=[0,0,0]] The model's orientation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [params.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] The model's world transform matrix. Overrides the position, scale and rotation parameters. Relative to ````origin````.\n     * @param {Boolean} [params.saoEnabled=true] Indicates if Scalable Ambient Obscurance (SAO) is enabled for the model. SAO is configured by the Scene's {@link SAO} component. Only works when {@link SAO#enabled} is also ````true````\n     * @param {Boolean} [params.pbrEnabled=true] Indicates if physically-based rendering (PBR) is enabled for the model. Overrides ````colorTextureEnabled````. Only works when {@link Scene#pbrEnabled} is also ````true````.\n     * @param {Boolean} [params.colorTextureEnabled=true] Indicates if base color texture rendering is enabled for the model. Overridden by ````pbrEnabled````.  Only works when {@link Scene#colorTextureEnabled} is also ````true````.\n     * @param {Boolean} [params.backfaces=true] When true, always show backfaces, even on objects for which the glTF material is single-sided. When false, only show backfaces on geometries whenever the glTF material is double-sided.\n     * @param {Number} [params.edgeThreshold=10] When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n     * @param {Boolean} [params.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to\n     * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable\n     * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point\n     * primitives. Only works while {@link DTX#enabled} is also ````true````.\n     * @param {Boolean} [params.autoMetaModel] When supplied, creates a default MetaModel with a single MetaObject.\n     * @param {Boolean} [params.globalizeObjectIds=false] Indicates whether to globalize each {@link Entity#id} and {@link MetaObject#id}, in case you need to prevent ID clashes with other models.\n     * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}\n     */\n    load(params = {}) {\n        if (params.id && this.viewer.scene.components[params.id]) {\n            this.error(\"Component with this ID already exists in viewer: \" + params.id + \" - will autogenerate this ID\");\n            delete params.id;\n        }\n        const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {\n            isModel: true,\n            dtxEnabled: params.dtxEnabled\n        }));\n        const modelId = sceneModel.id;  // In case ID was auto-generated\n        if (!params.src && !params.gltf) {\n            this.error(\"load() param expected: src or gltf\");\n            return sceneModel; // Return new empty model\n        }\n        if (params.metaModelSrc || params.metaModelJSON) {\n            const processMetaModelJSON = (metaModelJSON) => {\n                this.viewer.metaScene.createMetaModel(modelId, metaModelJSON, {});\n                this.viewer.scene.canvas.spinner.processes--;\n                if (params.src) {\n                    this._sceneModelLoader.load(this, params.src, metaModelJSON, params, sceneModel);\n                } else {\n                    this._sceneModelLoader.parse(this, params.gltf, metaModelJSON, params, sceneModel);\n                }\n            };\n            if (params.metaModelSrc) {\n                const metaModelSrc = params.metaModelSrc;\n                this.viewer.scene.canvas.spinner.processes++;\n                this._dataSource.getMetaModel(metaModelSrc, (metaModelJSON) => {\n                    this.viewer.scene.canvas.spinner.processes--;\n                    processMetaModelJSON(metaModelJSON);\n                }, (errMsg) => {\n                    this.error(`load(): Failed to load model metadata for model '${modelId} from  '${metaModelSrc}' - ${errMsg}`);\n                    this.viewer.scene.canvas.spinner.processes--;\n                });\n            } else if (params.metaModelJSON) {\n                processMetaModelJSON(params.metaModelJSON);\n            }\n        } else {\n            if (params.src) {\n                this._sceneModelLoader.load(this, params.src, null, params, sceneModel);\n            } else {\n                this._sceneModelLoader.parse(this, params.gltf, null, params, sceneModel);\n            }\n        }\n\n        sceneModel.once(\"destroyed\", () => {\n            this.viewer.metaScene.destroyMetaModel(modelId);\n        });\n\n        return sceneModel;\n    }\n\n    /**\n     * Destroys this GLTFLoaderPlugin.\n     */\n    destroy() {\n        super.destroy();\n    }\n}\n\n/**\n * @private\n */\nfunction CubeTextureCanvas(viewer, navCubeScene, cfg = {}) {\n\n    const cubeColor = \"lightgrey\";\n    const cubeHighlightColor = cfg.hoverColor || \"rgba(0,0,0,0.4)\";\n    const textColor = cfg.textColor || \"black\";\n    const parentNode = cfg.canvasElement || document.body;\n\n    const height = 500;\n    const width = height + (height / 3);\n    const scale = width / 24;\n\n    const facesZUp = [\n        {boundary: [6, 6, 6, 6], color: cfg.frontColor || cfg.color || \"#55FF55\"},\n        {boundary: [18, 6, 6, 6], color: cfg.backColor || cfg.color || \"#55FF55\"},\n        {boundary: [12, 6, 6, 6], color: cfg.rightColor || cfg.color || \"#FF5555\"},\n        {boundary: [0, 6, 6, 6], color: cfg.leftColor || cfg.color || \"#FF5555\"},\n        {boundary: [6, 0, 6, 6], color: cfg.topColor || cfg.color || \"#7777FF\"},\n        {boundary: [6, 12, 6, 6], color: cfg.bottomColor || cfg.color || \"#7777FF\"}\n    ];\n\n    const areasZUp = [\n        {label: \"NavCube.front\", boundaries: [[7, 7, 4, 4]], dir: [0, 1, 0], up: [0, 0, 1]},\n        {label: \"NavCube.back\", boundaries: [[19, 7, 4, 4]], dir: [0, -1, 0], up: [0, 0, 1]},\n        {label: \"NavCube.right\", boundaries: [[13, 7, 4, 4]], dir: [-1, 0, 0], up: [0, 0, 1]},\n        {label: \"NavCube.left\", boundaries: [[1, 7, 4, 4]], dir: [1, 0, 0], up: [0, 0, 1]},\n        {label: \"NavCube.top\", boundaries: [[7, 1, 4, 4]], dir: [0, 0, -1], up: [0, 1, 0]},\n        {label: \"NavCube.bottom\", boundaries: [[7, 13, 4, 4]], dir: [0, 0, 1], up: [0, -1, 0]},\n        {boundaries: [[7, 5, 4, 2]], dir: [0, 1, -1], up: [0, 1, 1]},\n        {boundaries: [[1, 6, 4, 1], [6, 1, 1, 4]], dir: [1, 0, -1], up: [1, 0, 1]},\n        {boundaries: [[7, 0, 4, 1], [19, 6, 4, 1]], dir: [0, -1, -1], up: [0, -1, 1]},\n        {boundaries: [[13, 6, 4, 1], [11, 1, 1, 4]], dir: [-1, 0, -1], up: [-1, 0, 1]},\n        {boundaries: [[7, 11, 4, 2]], dir: [0, 1, 1], up: [0, -1, 1]},\n        {boundaries: [[1, 11, 4, 1], [6, 13, 1, 4]], dir: [1, 0, 1], up: [-1, 0, 1]},\n        {boundaries: [[7, 17, 4, 1], [19, 11, 4, 1]], dir: [0, -1, 1], up: [0, 1, 1]},\n        {boundaries: [[13, 11, 4, 1], [11, 13, 1, 4]], dir: [-1, 0, 1], up: [1, 0, 1]},\n        {boundaries: [[5, 7, 2, 4]], dir: [1, 1, 0], up: [0, 0, 1]},\n        {boundaries: [[11, 7, 2, 4]], dir: [-1, 1, 0], up: [0, 0, 1]},\n        {boundaries: [[17, 7, 2, 4]], dir: [-1, -1, 0], up: [0, 0, 1]},\n        {boundaries: [[0, 7, 1, 4], [23, 7, 1, 4]], dir: [1, -1, 0], up: [0, 0, 1]},\n        {boundaries: [[5, 11, 2, 2]], dir: [1, 1, 1], up: [-1, -1, 1]},\n        {boundaries: [[23, 11, 1, 1], [6, 17, 1, 1], [0, 11, 1, 1]], dir: [1, -1, 1], up: [-1, 1, 1]},\n        {boundaries: [[5, 5, 2, 2]], dir: [1, 1, -1], up: [1, 1, 1]},\n        {boundaries: [[11, 17, 1, 1], [17, 11, 2, 1]], dir: [-1, -1, 1], up: [1, 1, 1]},\n        {boundaries: [[17, 6, 2, 1], [11, 0, 1, 1]], dir: [-1, -1, -1], up: [-1, -1, 1]},\n        {boundaries: [[11, 11, 2, 2]], dir: [-1, 1, 1], up: [1, -1, 1]},\n        {boundaries: [[0, 6, 1, 1], [6, 0, 1, 1], [23, 6, 1, 1]], dir: [1, -1, -1], up: [1, -1, 1]},\n        {boundaries: [[11, 5, 2, 2]], dir: [-1, 1, -1], up: [-1, 1, 1]}\n    ];\n\n    [\n        {boundary: [6, 6, 6, 6], color: cfg.frontColor || cfg.color || \"#55FF55\"},\n        {boundary: [18, 6, 6, 6], color: cfg.backColor || cfg.color || \"#55FF55\"},\n        {boundary: [12, 6, 6, 6], color: cfg.rightColor || cfg.color || \"#FF5555\"},\n        {boundary: [0, 6, 6, 6], color: cfg.leftColor || cfg.color || \"#FF5555\"},\n        {boundary: [6, 0, 6, 6], color: cfg.topColor || cfg.color || \"#7777FF\"},\n        {boundary: [6, 12, 6, 6], color: cfg.bottomColor || cfg.color || \"#7777FF\"}\n    ];\n\n    const areasYUp = [\n\n        // Faces\n\n        {yUp: \"\", label: \"NavCube.front\", boundaries: [[7, 7, 4, 4]], dir: [0, 0, -1], up: [0, 1, 0]},\n        {label: \"NavCube.back\", boundaries: [[19, 7, 4, 4]], dir: [0, 0, 1], up: [0, 1, 0]},\n        {label: \"NavCube.right\", boundaries: [[13, 7, 4, 4]], dir: [-1, 0, 0], up: [0, 1, 0]},\n        {label: \"NavCube.left\", boundaries: [[1, 7, 4, 4]], dir: [1, 0, 0], up: [0, 1, 0]},\n        {label: \"NavCube.top\", boundaries: [[7, 1, 4, 4]], dir: [0, -1, 0], up: [0, 0, -1]},\n        {label: \"NavCube.bottom\", boundaries: [[7, 13, 4, 4]], dir: [0, 1, 0], up: [0, 0, 1]},\n        {boundaries: [[7, 5, 4, 2]], dir: [0, -0.7071, -0.7071], up: [0, 0.7071, -0.7071]}, // Top-front edge\n        {boundaries: [[1, 6, 4, 1], [6, 1, 1, 4]], dir: [1, -1, 0], up: [1, 1, 0]},  // Top-left edge\n        {boundaries: [[7, 0, 4, 1], [19, 6, 4, 1]], dir: [0, -0.7071, 0.7071], up: [0, 0.7071, 0.7071]}, // Top-back edge\n        {boundaries: [[13, 6, 4, 1], [11, 1, 1, 4]], dir: [-1, -1, 0], up: [-1, 1, 0]}, // Top-right edge\n        {boundaries: [[7, 11, 4, 2]], dir: [0, 1, -1], up: [0, 1, 1]},  // Bottom-front edge\n        {boundaries: [[1, 11, 4, 1], [6, 13, 1, 4]], dir: [1, 1, 0], up: [-1, 1, 0]}, // Bottom-left edge\n        {boundaries: [[7, 17, 4, 1], [19, 11, 4, 1]], dir: [0, 1, 1], up: [0, 1, -1]}, // Bottom-back edge\n        {boundaries: [[13, 11, 4, 1], [11, 13, 1, 4]], dir: [-1, 1, 0], up: [1, 1, 0]}, // Bottom-right edge\n        {boundaries: [[5, 7, 2, 4]], dir: [1, 0, -1], up: [0, 1, 0]},// Front-left edge\n        {boundaries: [[11, 7, 2, 4]], dir: [-1, 0, -1], up: [0, 1, 0]}, // Front-right edge\n        {boundaries: [[17, 7, 2, 4]], dir: [-1, 0, 1], up: [0, 1, 0]},// Back-right edge\n        {boundaries: [[0, 7, 1, 4], [23, 7, 1, 4]], dir: [1, 0, 1], up: [0, 1, 0]},// Back-left edge\n        {boundaries: [[5, 11, 2, 2]], \"dir\": [0.5, 0.7071, -0.5], \"up\": [-0.5, 0.7071, 0.5]}, // Bottom-left-front corner\n        {boundaries: [[23, 11, 1, 1], [6, 17, 1, 1], [0, 11, 1, 1]],\"dir\": [0.5, 0.7071, 0.5],\"up\": [-0.5, 0.7071, -0.5]},// Bottom-back-left corner\n        {boundaries: [[5, 5, 2, 2]], \"dir\": [0.5, -0.7071, -0.5], \"up\": [0.5, 0.7071, -0.5]}, // Left-front-top corner\n        {boundaries: [[11, 17, 1, 1], [17, 11, 2, 1]], \"dir\": [-0.5, 0.7071, 0.5], \"up\": [0.5, 0.7071, -0.5]}, // Bottom-back-right corner\n        {boundaries: [[17, 6, 2, 1], [11, 0, 1, 1]], \"dir\": [-0.5, -0.7071, 0.5], \"up\": [-0.5, 0.7071, 0.5]}, // Top-back-right corner\n        {boundaries: [[11, 11, 2, 2]], \"dir\": [-0.5, 0.7071, -0.5], \"up\": [0.5, 0.7071, 0.5]}, // Bottom-front-right corner\n        {boundaries: [[0, 6, 1, 1], [6, 0, 1, 1], [23, 6, 1, 1]], \"dir\": [0.5, -0.7071, 0.5], \"up\": [0.5, 0.7071, 0.5]},// Top-back-left corner\n        {boundaries: [[11, 5, 2, 2]], \"dir\": [-0.5, -0.7071, -0.5], \"up\": [-0.5, 0.7071, -0.5]}// Top-front-right corner\n    ];\n\n    for (let i = 0, len = areasZUp.length; i < len; i++) {\n        math.normalizeVec3(areasZUp[i].dir, areasZUp[i].dir);\n        math.normalizeVec3(areasZUp[i].up, areasZUp[i].up);\n    }\n\n    for (let i = 0, len = areasYUp.length; i < len; i++) {\n        math.normalizeVec3(areasYUp[i].dir, areasYUp[i].dir);\n        math.normalizeVec3(areasYUp[i].up, areasYUp[i].up);\n    }\n    var areas = areasYUp;\n\n    this._textureCanvas = document.createElement('canvas');\n    this._textureCanvas.width = width;\n    this._textureCanvas.height = height;\n    this._textureCanvas.style.width = width + \"px\";\n    this._textureCanvas.style.height = height + \"px\";\n    this._textureCanvas.style.padding = \"0\";\n    this._textureCanvas.style.margin = \"0\";\n    this._textureCanvas.style.top = \"0\";\n    this._textureCanvas.style.background = cubeColor;\n    this._textureCanvas.style.position = \"absolute\";\n    this._textureCanvas.style.opacity = \"1.0\";\n    this._textureCanvas.style.visibility = \"hidden\";\n    this._textureCanvas.style[\"z-index\"] = 2000000;\n\n    parentNode.appendChild(this._textureCanvas);\n\n    const context = this._textureCanvas.getContext(\"2d\");\n\n    let zUp = false;\n\n    function paint() {\n\n        for (let i = 0, len = facesZUp.length; i < len; i++) {\n            const face = facesZUp[i];\n            const boundary = face.boundary;\n            const xmin = Math.round(boundary[0] * scale);\n            const ymin = Math.round(boundary[1] * scale);\n            const width = Math.round(boundary[2] * scale);\n            const height = Math.round(boundary[3] * scale);\n            context.fillStyle = face.color;\n            context.fillRect(xmin, ymin, width, height);\n        }\n\n        for (let i = 0, len = areas.length; i < len; i++) {\n            let xmin;\n            let ymin;\n            let width;\n            let height;\n            const area = areas[i];\n\n            const boundaries = area.boundaries;\n            for (var j = 0, lenj = boundaries.length; j < lenj; j++) {\n                const boundary = boundaries[j];\n                xmin = Math.round(boundary[0] * scale);\n                ymin = Math.round(boundary[1] * scale);\n                width = Math.round(boundary[2] * scale);\n                height = Math.round(boundary[3] * scale);\n                if (area.highlighted) {\n                    context.fillStyle = area.highlighted ? cubeHighlightColor : (area.color || cubeColor);\n                    context.fillRect(xmin, ymin, width, height);\n                }\n            }\n            if (area.label) {\n                context.fillStyle = textColor;\n                context.font = '60px sans-serif';\n                context.textAlign = \"center\";\n                var xcenter = xmin + (width * 0.5);\n                var ycenter = ymin + (height * 0.7);\n                context.fillText(translateLabel(area.label), xcenter, ycenter, 80);\n            }\n        }\n\n        navCubeScene.glRedraw();\n    }\n\n    const translateLabel = (function () {\n\n        const swizzleYUp = {\n            \"NavCube.front\": \"NavCube.front\",\n            \"NavCube.back\": \"NavCube.back\",\n            \"NavCube.right\": \"NavCube.right\",\n            \"NavCube.left\": \"NavCube.left\",\n            \"NavCube.top\": \"NavCube.top\",\n            \"NavCube.bottom\": \"NavCube.bottom\"\n        };\n\n        const swizzleZUp = {\n            \"NavCube.front\": \"NavCube.front\",\n            \"NavCube.back\": \"NavCube.back\",\n            \"NavCube.right\": \"NavCube.right\",\n            \"NavCube.left\": \"NavCube.left\",\n            \"NavCube.top\": \"NavCube.top\",\n            \"NavCube.bottom\": \"NavCube.bottom\"\n        };\n\n        const defaultLabels = {\n            \"NavCube.front\": \"FRONT\",\n            \"NavCube.back\": \"BACK\",\n            \"NavCube.right\": \"RIGHT\",\n            \"NavCube.left\": \"LEFT\",\n            \"NavCube.top\": \"TOP\",\n            \"NavCube.bottom\": \"BOTTOM\"\n        };\n\n        return function (key) {\n            const swizzle = zUp ? swizzleZUp : swizzleYUp;\n            const swizzledKey = swizzle ? swizzle[key] : null;\n            if (swizzledKey) {\n                return viewer.localeService.translate(swizzledKey) || defaultLabels[swizzledKey] || swizzledKey;\n            }\n            return key;\n        };\n    })();\n\n    this.setZUp = function () {\n        zUp = true;\n        areas = areasZUp;\n        this.clear();\n    };\n\n    this.setYUp = function () {\n        zUp = false;\n        areas = areasYUp;\n        this.clear();\n    };\n\n    this.clear = function () {\n        context.fillStyle = cubeColor;\n        context.fillRect(0, 0, width, height);\n        for (var i = 0, len = areas.length; i < len; i++) {\n            const area = areas[i];\n            area.highlighted = false;\n        }\n        paint();\n    };\n\n    this.getArea = function (uv) {\n        const s = uv[0] * width;\n        const t = height - (uv[1] * height); // Correct for our texture Y-flipping\n        for (var i = 0, len = areas.length; i < len; i++) {\n            const area = areas[i];\n            const boundaries = area.boundaries;\n            for (var j = 0, lenj = boundaries.length; j < lenj; j++) {\n                const boundary = boundaries[j];\n                if (s >= (boundary[0] * scale) && s <= ((boundary[0] + boundary[2]) * scale) && t >= (boundary[1] * scale) && t <= ((boundary[1] + boundary[3]) * scale)) {\n                    return i;\n                }\n            }\n        }\n        return -1;\n    };\n\n    this.setAreaHighlighted = function (areaId, highlighted) {\n        var area = areas[areaId];\n        if (!area) {\n            throw \"Area not found: \" + areaId;\n        }\n        area.highlighted = !!highlighted;\n        paint();\n    };\n\n    this.getAreaDir = function (areaId) {\n        var area = areas[areaId];\n        if (!area) {\n            throw \"Unknown area: \" + areaId;\n        }\n        return area.dir;\n    };\n\n    this.getAreaUp = function (areaId) {\n        var area = areas[areaId];\n        if (!area) {\n            throw \"Unknown area: \" + areaId;\n        }\n        return area.up;\n    };\n\n    this.getImage = function () {\n        return this._textureCanvas;\n    };\n\n    this.destroy = function () {\n        if (this._textureCanvas) {\n            this._textureCanvas.parentNode.removeChild(this._textureCanvas);\n            this._textureCanvas = null;\n        }\n    };\n}\n\nconst tempVec3a$4 = math.vec3();\nconst tempVec3b$1 = math.vec3();\nmath.mat4();\n\n/**\n * {@link Viewer} plugin that lets us look at the entire {@link Scene} from along a chosen axis or diagonal.\n *\n *  [<img src=\"https://user-images.githubusercontent.com/83100/55674490-c93c2e00-58b5-11e9-8a28-eb08876947c0.gif\">](https://xeokit.github.io/xeokit-sdk/examples/index.html#gizmos_NavCubePlugin)\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#gizmos_NavCubePlugin)]\n *\n * ## Overview\n *\n * * Rotating the NavCube causes the Viewer's {@link Camera} to orbit its current\n * point-of-interest. Conversely, orbiting the Camera causes the NavCube to rotate accordingly.\n * * The faces of the NavCube are aligned with the Viewer's {@link Scene}'s World-space coordinate axis. Clicking on a face moves\n * the Camera to look at the entire Scene along the corresponding axis. Clicking on an edge or a corner looks at\n * the entire Scene along a diagonal.\n * * The NavCube can be configured to either jump or fly the Camera to each new position. We can configure how tightly the\n * NavCube fits the Scene to view, and when flying, we can configure how fast it flies. We can also configure whether the\n * NavCube fits all objects to view, or just the currently visible objects. See below for a usage example.\n * * Clicking the NavCube also sets {@link CameraControl#pivotPos} to the center of the fitted objects.\n *\n * ## Usage\n *\n * In the example below, we'll create a Viewer and add a NavCubePlugin, which will create a NavCube gizmo in the canvas\n * with the given ID. Then we'll use the {@link XKTLoaderPlugin} to load a model into the Viewer's Scene. We can then\n * use the NavCube to look at the model along each axis or diagonal.\n *\n * ````JavaScript\n * import {Viewer, XKTLoaderPlugin, NavCubePlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [-3.93, 2.85, 27.01];\n * viewer.camera.look = [4.40, 3.72, 8.89];\n * viewer.camera.up = [-0.01, 0.99, 0.03];\n *\n * const navCube = new NavCubePlugin(viewer, {\n *\n *     canvasID: \"myNavCubeCanvas\",\n *\n *     visible: true,         // Initially visible (default)\n *\n *     cameraFly: true,       // Fly camera to each selected axis/diagonal\n *     cameraFitFOV: 45,      // How much field-of-view the scene takes once camera has fitted it to view\n *     cameraFlyDuration: 0.5,// How long (in seconds) camera takes to fly to each new axis/diagonal\n *\n *     fitVisible: false,     // Fit whole scene, including invisible objects (default)\n *\n *     synchProjection: false // Keep NavCube in perspective projection, even when camera switches to ortho (default)\n * });\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/xkt/Duplex.ifc.xkt\",\n *     edges: true\n * });\n * ````\n */\nclass NavCubePlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg NavCubePlugin configuration.\n     * @param {String} [cfg.id=\"NavCube\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {String} [cfg.canvasId] ID of an existing HTML canvas to display the NavCube - either this or canvasElement is mandatory. When both values are given, the element reference is always preferred to the ID.\n     * @param {HTMLCanvasElement} [cfg.canvasElement] Reference of an existing HTML canvas to display the NavCube - either this or canvasId is mandatory. When both values are given, the element reference is always preferred to the ID.\n     * @param {Boolean} [cfg.visible=true] Initial visibility.\n     * @param {Boolean} [cfg.shadowVisible=true] Whether the shadow of the cube is visible.\n     * @param {String} [cfg.cameraFly=true] Whether the {@link Camera} flies or jumps to each selected axis or diagonal.\n     * @param {String} [cfg.cameraFitFOV=45] How much of the field-of-view, in degrees, that the 3D scene should fill the {@link Canvas} when the {@link Camera} moves to an axis or diagonal.\n     * @param {String} [cfg.cameraFlyDuration=0.5] When flying the {@link Camera} to each new axis or diagonal, how long, in seconds, that the Camera takes to get there.\n     * @param {String} [cfg.color=\"lightgrey\"] Custom uniform color for the faces of the NavCube.\n     * @param {String} [cfg.frontColor=\"#55FF55\"] Custom color for the front face of the NavCube. Overrides ````color````.\n     * @param {String} [cfg.backColor=\"#55FF55\"] Custom color for the back face of the NavCube. Overrides ````color````.\n     * @param {String} [cfg.leftColor=\"#FF5555\"] Custom color for the left face of the NavCube. Overrides ````color````.\n     * @param {String} [cfg.rightColor=\"#FF5555\"] Custom color for the right face of the NavCube. Overrides ````color````.\n     * @param {String} [cfg.topColor=\"#5555FF\"] Custom color for the top face of the NavCube. Overrides ````color````.\n     * @param {String} [cfg.bottomColor=\"#5555FF\"] Custom color for the bottom face of the NavCube. Overrides ````color````.\n     * @param {String} [cfg.hoverColor=\"rgba(0,0,0,0.4)\"] Custom color for highlighting regions on the NavCube as we hover the pointer over them.\n     * @param {String} [cfg.textColor=\"black\"] Custom text color for labels of the NavCube.\n     * @param {Boolean} [cfg.fitVisible=false] Sets whether the axis, corner and edge-aligned views will fit the\n     * view to the entire {@link Scene} or just to visible object-{@link Entity}s. Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.\n     * @param {Boolean} [cfg.synchProjection=false] Sets whether the NavCube switches between perspective and orthographic projections in synchrony with the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.\n     * @param {Boolean} [cfg.isProjectNorth] sets whether the NavCube switches between true north and project north - using the project north offset angle.\n     * @param {number} [cfg.projectNorthOffsetAngle] sets the NavCube project north offset angle - when the {@link isProjectNorth} is true.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"NavCube\", viewer, cfg);\n\n        viewer.navCube = this;\n\n        var visible = true;\n\n        try {\n            this._navCubeScene = new Scene(viewer, {\n                canvasId: cfg.canvasId,\n                canvasElement: cfg.canvasElement,\n                transparent: true,\n            });\n\n            this._navCubeCanvas = this._navCubeScene.canvas.canvas;\n\n            this._navCubeScene.input.keyboardEnabled = false; // Don't want keyboard input in the NavCube\n\n        } catch (error) {\n            this.error(error);\n            return;\n        }\n\n        const navCubeScene = this._navCubeScene;\n\n        navCubeScene.clearLights();\n\n        new DirLight(navCubeScene, {dir: [0.4, -0.4, 0.8], color: [0.8, 1.0, 1.0], intensity: 1.0, space: \"view\"});\n        new DirLight(navCubeScene, {dir: [-0.8, -0.3, -0.4], color: [0.8, 0.8, 0.8], intensity: 1.0, space: \"view\"});\n        new DirLight(navCubeScene, {dir: [0.8, -0.6, -0.8], color: [1.0, 1.0, 1.0], intensity: 1.0, space: \"view\"});\n\n        this._navCubeCamera = navCubeScene.camera;\n        this._navCubeCamera.ortho.scale = 7.0;\n        this._navCubeCamera.ortho.near = 0.1;\n        this._navCubeCamera.ortho.far = 2000;\n\n        navCubeScene.edgeMaterial.edgeColor = [0.2, 0.2, 0.2];\n        navCubeScene.edgeMaterial.edgeAlpha = 0.6;\n\n        this._zUp = Boolean(viewer.camera.zUp);\n\n        var self = this;\n\n        this.setIsProjectNorth(cfg.isProjectNorth);\n        this.setProjectNorthOffsetAngle(cfg.projectNorthOffsetAngle);\n\n        const rotateTrueNorth = (function () {\n            const trueNorthMatrix = math.mat4();\n            return function (dir, vec, dest) {\n                math.identityMat4(trueNorthMatrix);\n                math.rotationMat4v(dir * self._projectNorthOffsetAngle * math.DEGTORAD, [0, 1, 0], trueNorthMatrix);\n                return math.transformVec3(trueNorthMatrix, vec, dest)\n            }\n        }());\n\n        this._synchCamera = (function () {\n            var matrix = math.rotationMat4c(-90 * math.DEGTORAD, 1, 0, 0);\n            var eyeLookVec = math.vec3();\n            var eyeLookVecCube = math.vec3();\n            var upCube = math.vec3();\n            return function () {\n                var eye = viewer.camera.eye;\n                var look = viewer.camera.look;\n                var up = viewer.camera.up;\n                eyeLookVec = math.mulVec3Scalar(math.normalizeVec3(math.subVec3(eye, look, eyeLookVec)), 5);\n\n                if (self._isProjectNorth && self._projectNorthOffsetAngle) {\n                    eyeLookVec = rotateTrueNorth(-1, eyeLookVec, tempVec3a$4);\n                    up = rotateTrueNorth(-1, up, tempVec3b$1);\n                }\n\n                if (self._zUp) { // +Z up\n                    math.transformVec3(matrix, eyeLookVec, eyeLookVecCube);\n                    math.transformVec3(matrix, up, upCube);\n                    self._navCubeCamera.look = [0, 0, 0];\n                    self._navCubeCamera.eye = math.transformVec3(matrix, eyeLookVec, eyeLookVecCube);\n                    self._navCubeCamera.up = math.transformPoint3(matrix, up, upCube);\n                } else { // +Y up\n                    self._navCubeCamera.look = [0, 0, 0];\n                    self._navCubeCamera.eye = eyeLookVec;\n                    self._navCubeCamera.up = up;\n                }\n            };\n        }());\n\n        this._cubeTextureCanvas = new CubeTextureCanvas(viewer, navCubeScene, cfg);\n\n        this._cubeSampler = new Texture(navCubeScene, {\n            image: this._cubeTextureCanvas.getImage(),\n            flipY: true,\n            wrapS: ClampToEdgeWrapping,\n            wrapT: ClampToEdgeWrapping\n        });\n\n        this._cubeMesh = new Mesh(navCubeScene, {\n            geometry: new ReadableGeometry(navCubeScene, {\n                primitive: \"triangles\",\n                normals: [\n                    0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,\n                    0, 1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1,\n                    0, 0, -1, 0, 0, -1, 0, 0, -1\n                ],\n                positions: [\n                    1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1,\n                    1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1,\n                    1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1\n                ],\n                uv: [\n                    0.5, 0.6666, 0.25, 0.6666, 0.25, 0.3333, 0.5, 0.3333, 0.5, 0.6666, 0.5, 0.3333, 0.75, 0.3333, 0.75, 0.6666,\n                    0.5, 0.6666, 0.5, 1, 0.25, 1, 0.25, 0.6666, 0.25, 0.6666, 0.0, 0.6666, 0.0, 0.3333, 0.25, 0.3333,\n                    0.25, 0, 0.50, 0, 0.50, 0.3333, 0.25, 0.3333, 0.75, 0.3333, 1.0, 0.3333, 1.0, 0.6666, 0.75, 0.6666\n                ],\n                indices: [\n                    0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16,\n                    18, 19, 20, 21, 22, 20, 22, 23\n                ]\n            }),\n            material: new PhongMaterial(navCubeScene, {\n                diffuse: [0.4, 0.4, 0.4],\n                specular: [0.4, 0.4, 0.4],\n                emissive: [.6, .6, .6],\n                diffuseMap: this._cubeSampler,\n                emissiveMap: this._cubeSampler\n            }),\n            visible: !!visible,\n            edges: true\n        });\n\n        this._shadow = cfg.shadowVisible === false ? null : new Mesh(navCubeScene, {\n            geometry: new ReadableGeometry(navCubeScene, buildCylinderGeometry({\n                center: [0, 0, 0],\n                radiusTop: 0.001,\n                radiusBottom: 1.4,\n                height: 0.01,\n                radialSegments: 20,\n                heightSegments: 1,\n                openEnded: true\n            })),\n            material: new PhongMaterial(navCubeScene, {\n                diffuse: [0.0, 0.0, 0.0], specular: [0, 0, 0], emissive: [0.0, 0.0, 0.0], alpha: 0.5\n            }),\n            position: [0, -1.5, 0],\n            visible: !!visible,\n            pickable: false,\n            backfaces: false\n        });\n\n        this._onCameraMatrix = viewer.camera.on(\"matrix\", this._synchCamera);\n        this._onCameraWorldAxis = viewer.camera.on(\"worldAxis\", () => {\n            if (viewer.camera.zUp) {\n                this._zUp = true;\n                this._cubeTextureCanvas.setZUp();\n                this._repaint();\n                this._synchCamera();\n            } else if (viewer.camera.yUp) {\n                this._zUp = false;\n                this._cubeTextureCanvas.setYUp();\n                this._repaint();\n                this._synchCamera();\n            }\n        });\n        this._onCameraFOV = viewer.camera.perspective.on(\"fov\", (fov) => {\n            if (this._synchProjection) {\n                this._navCubeCamera.perspective.fov = fov;\n            }\n        });\n        this._onCameraProjection = viewer.camera.on(\"projection\", (projection) => {\n            if (this._synchProjection) {\n                this._navCubeCamera.projection = (projection === \"ortho\" || projection === \"perspective\") ? projection : \"perspective\";\n            }\n        });\n\n        var lastAreaId = -1;\n\n        function actionMove(posX, posY) {\n            var yawInc = (posX - lastX) * -sensitivity;\n            var pitchInc = (posY - lastY) * -sensitivity;\n            viewer.camera.orbitYaw(yawInc);\n            viewer.camera.orbitPitch(-pitchInc);\n            lastX = posX;\n            lastY = posY;\n        }\n\n        function getCoordsWithinElement(clientCoords) {\n            const { left, top } = self._navCubeCanvas.getBoundingClientRect();\n            return [clientCoords.clientX - left, clientCoords.clientY - top];\n        }\n\n        {\n            var downX = null;\n            var downY = null;\n            var down = false;\n            var over = false;\n            var sensitivity = 0.5;\n\n            var lastX;\n            var lastY;\n\n\n            self._navCubeCanvas.addEventListener(\"mouseenter\", self._onMouseEnter = function (e) {\n                over = true;\n            });\n\n\n            self._navCubeCanvas.addEventListener(\"mouseleave\", self._onMouseLeave = function (e) {\n                over = false;\n            });\n\n            self._navCubeCanvas.addEventListener(\"mousedown\", self._onMouseDown = function (e) {\n                if (e.which !== 1) {\n                    return;\n                }\n                downX = e.x;\n                downY = e.y;\n                lastX = e.clientX;\n                lastY = e.clientY;\n                var canvasPos = getCoordsWithinElement({clientX: e.clientX, clientY: e.clientY});\n                var hit = navCubeScene.pick({\n                    canvasPos: canvasPos\n                });\n                if (hit) {\n                    down = true;\n\n                } else {\n                    down = false;\n                }\n            });\n\n            self._navCubeCanvas.addEventListener(\"mouseup\", self._onMouseUp = function (e) {\n                if (e.which !== 1) {// Left button\n                    return;\n                }\n                down = false;\n                if (downX === null) {\n                    return;\n                }\n                var canvasPos = getCoordsWithinElement({clientX: e.clientX, clientY: e.clientY});\n                var hit = navCubeScene.pick({\n                    canvasPos: canvasPos,\n                    pickSurface: true\n                });\n                if (hit) {\n                    if (hit.uv) {\n                        var areaId = self._cubeTextureCanvas.getArea(hit.uv);\n                        if (areaId >= 0) {\n                            self._navCubeCanvas.style.cursor = \"pointer\";\n                            if (lastAreaId >= 0) {\n                                self._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\n                                self._repaint();\n                                lastAreaId = -1;\n                            }\n                            if (areaId >= 0) {\n                                self._cubeTextureCanvas.setAreaHighlighted(areaId, true);\n                                lastAreaId = areaId;\n                                self._repaint();\n                                if (e.x < (downX - 3) || e.x > (downX + 3) || e.y < (downY - 3) || e.y > (downY + 3)) {\n                                    return;\n                                }\n                                var dir = self._cubeTextureCanvas.getAreaDir(areaId);\n                                if (dir) {\n                                    var up = self._cubeTextureCanvas.getAreaUp(areaId);\n                                    if (self._isProjectNorth && self._projectNorthOffsetAngle) {\n                                        dir = rotateTrueNorth(+1, dir, tempVec3a$4);\n                                        up = rotateTrueNorth(+1, up, tempVec3b$1);\n                                    }\n                                    flyTo(dir, up, function () {\n                                        if (lastAreaId >= 0) {\n                                            self._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\n                                            self._repaint();\n                                            lastAreaId = -1;\n                                        }\n                                        self._navCubeCanvas.style.cursor = \"pointer\";\n                                        if (lastAreaId >= 0) {\n                                            self._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\n                                            self._repaint();\n                                            lastAreaId = -1;\n                                        }\n                                        if (areaId >= 0) {\n                                            self._cubeTextureCanvas.setAreaHighlighted(areaId, false);\n                                            lastAreaId = -1;\n                                            self._repaint();\n                                        }\n                                    });\n                                }\n                            }\n                        }\n                    }\n                }\n            });\n\n            self._navCubeCanvas.addEventListener(\"mousemove\", self._onMouseMove = function (e) {\n                if (lastAreaId >= 0) {\n                    self._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\n                    self._repaint();\n                    lastAreaId = -1;\n                }\n                if (e.buttons === 1 && !down) {\n                    return;\n                }\n                if (down) {\n                    var posX = e.clientX;\n                    var posY = e.clientY;\n                    self._navCubeCanvas.style.cursor = \"move\";\n                    actionMove(posX, posY);\n                    return;\n                }\n                if (!over) {\n                    return;\n                }\n                var canvasPos = getCoordsWithinElement({clientX: e.clientX, clientY: e.clientY});\n                var hit = navCubeScene.pick({\n                    canvasPos: canvasPos,\n                    pickSurface: true\n                });\n                if (hit) {\n                    if (hit.uv) {\n                        self._navCubeCanvas.style.cursor = \"pointer\";\n                        var areaId = self._cubeTextureCanvas.getArea(hit.uv);\n                        if (areaId === lastAreaId) {\n                            return;\n                        }\n                        if (lastAreaId >= 0) {\n                            self._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\n                        }\n                        if (areaId >= 0) {\n                            self._cubeTextureCanvas.setAreaHighlighted(areaId, true);\n                            self._repaint();\n                            lastAreaId = areaId;\n                        }\n                    }\n                } else {\n                    self._navCubeCanvas.style.cursor = \"default\";\n                    if (lastAreaId >= 0) {\n                        self._cubeTextureCanvas.setAreaHighlighted(lastAreaId, false);\n                        self._repaint();\n                        lastAreaId = -1;\n                    }\n                }\n            });\n            \n            self._navCubeCanvas.addEventListener(\"touchstart\", self._onTouchStart = function (e) {\n                if (e.touches.length > 0) {\n                    downX = e.touches[0].clientX;\n                    downY = e.touches[0].clientY;\n                    lastX = e.touches[0].clientX;\n                    lastY = e.touches[0].clientY;\n                    var canvasPos = getCoordsWithinElement({clientX: e.touches[0].clientX, clientY: e.touches[0].clientY});\n                    var hit = navCubeScene.pick({\n                        canvasPos: canvasPos\n                    });\n                    if (hit) {\n                        down = true;\n                    } else {\n                        down = false;\n                    }\n                }\n            }, \n            {\n                passive: false\n            });\n\n            self._navCubeCanvas.addEventListener(\"touchmove\", self._onTouchMove = function (e) {\n                e.preventDefault();\n                var touch = e.touches[0];\n                var posX = touch.clientX;\n                var posY = touch.clientY;\n\n                var currentElement = document.elementFromPoint(posX, posY);\n                over = (self._navCubeCanvas === currentElement);\n\n                if (!over) {\n                    return;\n                }\n                if (down) {\n                    actionMove(posX, posY);\n                    return;\n                }\n            }, \n            {\n                passive: false\n            });\n\n            self._navCubeCanvas.addEventListener(\"touchend\", self._onTouchEnd = function (e) {\n                down = false;\n                if (downX === null) {\n                    return;\n                } \n            });\n\n            var flyTo = (function () {\n                var center = math.vec3();\n                return function (dir, up, ok) {\n                    var aabb = self._fitVisible ? viewer.scene.getAABB(viewer.scene.visibleObjectIds) : viewer.scene.aabb;\n                    var diag = math.getAABB3Diag(aabb);\n                    math.getAABB3Center(aabb, center);\n                    var dist = Math.abs(diag / Math.tan(self._cameraFitFOV * math.DEGTORAD));\n                    viewer.cameraControl.pivotPos = center;\n                    if (self._cameraFly) {\n                        viewer.cameraFlight.flyTo({\n                            look: center,\n                            eye: [center[0] - (dist * dir[0]), center[1] - (dist * dir[1]), center[2] - (dist * dir[2])],\n                            up: up || [0, 1, 0],\n                            orthoScale: diag * 1.1,\n                            fitFOV: self._cameraFitFOV,\n                            duration: self._cameraFlyDuration\n                        }, ok);\n                    } else {\n                        viewer.cameraFlight.jumpTo({\n                            look: center,\n                            eye: [center[0] - (dist * dir[0]), center[1] - (dist * dir[1]), center[2] - (dist * dir[2])],\n                            up: up || [0, 1, 0],\n                            orthoScale: diag * 1.1,\n                            fitFOV: self._cameraFitFOV\n                        }, ok);\n                    }\n                };\n            })();\n        }\n\n        this._onUpdated = viewer.localeService.on(\"updated\", () => {\n            this._cubeTextureCanvas.clear();\n            this._repaint();\n        });\n\n        this.setVisible(cfg.visible);\n        this.setCameraFitFOV(cfg.cameraFitFOV);\n        this.setCameraFly(cfg.cameraFly);\n        this.setCameraFlyDuration(cfg.cameraFlyDuration);\n        this.setFitVisible(cfg.fitVisible);\n        this.setSynchProjection(cfg.synchProjection);\n    }\n\n    send(name, value) {\n        switch (name) {\n            case \"language\":\n                this._cubeTextureCanvas.clear();\n                this._repaint(); // CubeTextureCanvas gets language from Viewer\n                break;\n        }\n    }\n\n    _repaint() {\n        const image = this._cubeTextureCanvas.getImage();\n        this._cubeMesh.material.diffuseMap.image = image;\n        this._cubeMesh.material.emissiveMap.image = image;\n    }\n\n    /**\n     * Sets if the NavCube is visible.\n     *\n     * @param {Boolean} visible Whether or not the NavCube is visible.\n     */\n    setVisible(visible = true) {\n        if (!this._navCubeCanvas) {\n            return;\n        }\n        this._cubeMesh.visible = visible;\n        if (this._shadow) {\n            this._shadow.visible = visible;\n        }\n        this._navCubeCanvas.style.visibility = visible ? \"visible\" : \"hidden\";\n    }\n\n    /**\n     * Gets if the NavCube is visible.\n     *\n     * @return {Boolean} True when the NavCube is visible.\n     */\n    getVisible() {\n        if (!this._navCubeCanvas) {\n            return false;\n        }\n        return this._cubeMesh.visible;\n    }\n\n\n    /**\n     * Sets whether the axis, corner and edge-aligned views will fit the\n     * view to the entire {@link Scene} or just to visible object-{@link Entity}s.\n     *\n     * Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.\n     *\n     * @param {Boolean} fitVisible Set ````true```` to fit only visible object-Entitys.\n     */\n    setFitVisible(fitVisible = false) {\n        this._fitVisible = fitVisible;\n    }\n\n    /**\n     * Gets whether the axis, corner and edge-aligned views will fit the\n     * view to the entire {@link Scene} or just to visible object-{@link Entity}s.\n     *\n     * Entitys are visible objects when {@link Entity#isObject} and {@link Entity#visible} are both ````true````.\n     *\n     * @return {Boolean} True when fitting only visible object-Entitys.\n     */\n    getFitVisible() {\n        return this._fitVisible;\n    }\n\n    /**\n     * Sets whether the {@link Camera} flies or jumps to each selected axis or diagonal.\n     *\n     * Default is ````true````, to fly.\n     *\n     * @param {Boolean} cameraFly Set ````true```` to fly, else ````false```` to jump.\n     */\n    setCameraFly(cameraFly = true) {\n        this._cameraFly = cameraFly;\n    }\n\n    /**\n     * Gets whether the {@link Camera} flies or jumps to each selected axis or diagonal.\n     *\n     * Default is ````true````, to fly.\n     *\n     * @returns {Boolean} Returns ````true```` to fly, else ````false```` to jump.\n     */\n    getCameraFly() {\n        return this._cameraFly;\n    }\n\n    /**\n     * Sets how much of the field-of-view, in degrees, that the {@link Scene} should\n     * fill the canvas when flying or jumping the {@link Camera} to each selected axis or diagonal.\n     *\n     * Default value is ````45````.\n     *\n     * @param {Number} cameraFitFOV New FOV value.\n     */\n    setCameraFitFOV(cameraFitFOV = 45) {\n        this._cameraFitFOV = cameraFitFOV;\n    }\n\n    /**\n     * Gets how much of the field-of-view, in degrees, that the {@link Scene} should\n     * fill the canvas when flying or jumping the {@link Camera} to each selected axis or diagonal.\n     *\n     * Default value is ````45````.\n     *\n     * @returns {Number} Current FOV value.\n     */\n    getCameraFitFOV() {\n        return this._cameraFitFOV;\n    }\n\n    /**\n     * When flying the {@link Camera} to each new axis or diagonal, sets how long, in seconds, that the Camera takes to get there.\n     *\n     * Default is ````0.5````.\n     *\n     * @param {Boolean} cameraFlyDuration Camera flight duration in seconds.\n     */\n    setCameraFlyDuration(cameraFlyDuration = 0.5) {\n        this._cameraFlyDuration = cameraFlyDuration;\n    }\n\n    /**\n     * When flying the {@link Camera} to each new axis or diagonal, gets how long, in seconds, that the Camera takes to get there.\n     *\n     * Default is ````0.5````.\n     *\n     * @returns {Boolean} Camera flight duration in seconds.\n     */\n    getCameraFlyDuration() {\n        return this._cameraFlyDuration;\n    }\n\n    /**\n     * Sets whether the NavCube switches between perspective and orthographic projections in synchrony with\n     * the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.\n     *\n     * @param {Boolean} synchProjection Set ````true```` to keep NavCube projection synchronized with {@link Camera#projection}.\n     */\n    setSynchProjection(synchProjection = false) {\n        this._synchProjection = synchProjection;\n    }\n\n    /**\n     * Gets whether the NavCube switches between perspective and orthographic projections in synchrony with\n     * the {@link Camera}. When ````false````, the NavCube will always be rendered with perspective projection.\n     *\n     * @return {Boolean} True when NavCube projection is synchronized with {@link Camera#projection}.\n     */\n    getSynchProjection() {\n        return this._synchProjection;\n    }\n\n    /**\n     * Sets whether the NavCube switches between project north and true north\n     *\n     * @param {Boolean} isProjectNorth Set ````true```` to use project north offset\n     */\n    setIsProjectNorth(isProjectNorth = false) {\n        this._isProjectNorth = isProjectNorth;\n    }\n\n    /**\n     * Gets whether the NavCube switches between project north and true north\n     *\n     * @return {Boolean} isProjectNorth when ````true```` - use project north offset\n     */\n    getIsProjectNorth() {\n        return this._isProjectNorth;\n    }\n\n    /**\n     * Sets the NavCube project north offset angle (used when {@link isProjectNorth} is ````true````\n     *\n     * @param {number} projectNorthOffsetAngle Set the vector offset for project north\n     */\n    setProjectNorthOffsetAngle(projectNorthOffsetAngle) {\n        this._projectNorthOffsetAngle = projectNorthOffsetAngle;\n    }\n\n    /**\n     * Gets the offset angle between project north and true north\n     *\n     * @return {number} projectNorthOffsetAngle\n     */\n    getProjectNorthOffsetAngle() {\n        return this._projectNorthOffsetAngle;\n    }\n\n    /**\n     * Destroys this NavCubePlugin.\n     *\n     * Does not destroy the canvas the NavCubePlugin was configured with.\n     */\n    destroy() {\n\n        if (this._navCubeCanvas) {\n\n            this.viewer.localeService.off(this._onUpdated);\n            this.viewer.camera.off(this._onCameraMatrix);\n            this.viewer.camera.off(this._onCameraWorldAxis);\n            this.viewer.camera.perspective.off(this._onCameraFOV);\n            this.viewer.camera.off(this._onCameraProjection);\n\n            this._navCubeCanvas.removeEventListener(\"mouseenter\", this._onMouseEnter);\n            this._navCubeCanvas.removeEventListener(\"mouseleave\", this._onMouseLeave);\n            this._navCubeCanvas.removeEventListener(\"mousedown\", this._onMouseDown);\n\n            this._navCubeCanvas.removeEventListener(\"mousemove\", this._onMouseMove);\n            this._navCubeCanvas.removeEventListener(\"mouseup\", this._onMouseUp);\n\n            this._navCubeCanvas.removeEventListener(\"touchstart\", this._onTouchStart);\n            this._navCubeCanvas.removeEventListener(\"touchmove\", this._onTouchMove);\n            this._navCubeCanvas.removeEventListener(\"touchend\", this._onTouchEnd);\n\n            this._navCubeCanvas = null;\n            this._cubeTextureCanvas.destroy();\n            this._cubeTextureCanvas = null;\n\n            this._onMouseEnter = null;\n            this._onMouseLeave = null;\n            this._onMouseDown = null;\n            this._onMouseMove = null;\n            this._onMouseUp = null;\n\n            this._onTouchStart = null;\n            this._onTouchMove = null;\n            this._onTouchEnd = null;\n        }\n\n        this._navCubeScene.destroy();\n        this._navCubeScene = null;\n        this._cubeMesh = null;\n        this._shadow = null;\n\n        super.destroy();\n    }\n}\n\nconst tempVec3a$3 = math.vec3();\n\n/**\n * @private\n */\nclass OBJSceneGraphLoader {\n\n    /**\n     * Loads OBJ and MTL from file(s) into a {@link Node}.\n     *\n     * @static\n     * @param {Node} modelNode Node to load into.\n     * @param {String} src Path to OBJ file.\n     * @param {Object} params Loading options.\n     */\n    load(modelNode, src, params = {}) {\n\n        var spinner = modelNode.scene.canvas.spinner;\n        spinner.processes++;\n\n        loadOBJ(modelNode, src, function (state) {\n            loadMTLs(modelNode, state, function () {\n\n                createMeshes(modelNode, state);\n\n                spinner.processes--;\n\n                core.scheduleTask(function () {\n                    modelNode.fire(\"loaded\", true, false);\n                });\n            });\n        });\n    }\n\n    /**\n     * Parses OBJ and MTL text strings into a {@link Node}.\n     *\n     * @static\n     * @param {Node} modelNode Node to load into.\n     * @param {String} objText OBJ text string.\n     * @param {String} [mtlText] MTL text string.\n     * @param {String} [basePath] Base path for external resources.\n     */\n    parse(modelNode, objText, mtlText, basePath) {\n        if (!objText) {\n            this.warn(\"load() param expected: objText\");\n            return;\n        }\n        var state = parseOBJ(modelNode, objText, null);\n        if (mtlText) {\n            parseMTL(modelNode, mtlText, basePath);\n        }\n        createMeshes(modelNode, state);\n        modelNode.src = null;\n        modelNode.fire(\"loaded\", true, false);\n    }\n}\n\n//--------------------------------------------------------------------------------------------\n// Loads OBJ\n//\n// Parses OBJ into an intermediate state object. The object will contain geometry data\n// and material IDs from which meshes can be created later. The object will also\n// contain a list of filenames of the MTL files referenced by the OBJ, is any.\n//\n// Originally based on the THREE.js OBJ and MTL loaders:\n//\n// https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/OBJLoader.js\n// https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/MTLLoader.js\n//--------------------------------------------------------------------------------------------\n\nvar loadOBJ = function (modelNode, url, ok) {\n    loadFile(url, function (text) {\n            var state = parseOBJ(modelNode, text, url);\n            ok(state);\n        },\n        function (error) {\n            modelNode.error(error);\n        });\n};\n\nvar parseOBJ = (function () {\n\n    const regexp = {\n        // v float float float\n        vertex_pattern: /^v\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)/,\n        // vn float float float\n        normal_pattern: /^vn\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)/,\n        // vt float float\n        uv_pattern: /^vt\\s+([\\d|\\.|\\+|\\-|e|E]+)\\s+([\\d|\\.|\\+|\\-|e|E]+)/,\n        // f vertex vertex vertex\n        face_vertex: /^f\\s+(-?\\d+)\\s+(-?\\d+)\\s+(-?\\d+)(?:\\s+(-?\\d+))?/,\n        // f vertex/uv vertex/uv vertex/uv\n        face_vertex_uv: /^f\\s+(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)(?:\\s+(-?\\d+)\\/(-?\\d+))?/,\n        // f vertex/uv/normal vertex/uv/normal vertex/uv/normal\n        face_vertex_uv_normal: /^f\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+)\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+)(?:\\s+(-?\\d+)\\/(-?\\d+)\\/(-?\\d+))?/,\n        // f vertex//normal vertex//normal vertex//normal\n        face_vertex_normal: /^f\\s+(-?\\d+)\\/\\/(-?\\d+)\\s+(-?\\d+)\\/\\/(-?\\d+)\\s+(-?\\d+)\\/\\/(-?\\d+)(?:\\s+(-?\\d+)\\/\\/(-?\\d+))?/,\n        // o object_name | g group_name\n        object_pattern: /^[og]\\s*(.+)?/,\n        // s boolean\n        smoothing_pattern: /^s\\s+(\\d+|on|off)/,\n        // mtllib file_reference\n        material_library_pattern: /^mtllib /,\n        // usemtl material_name\n        material_use_pattern: /^usemtl /\n    };\n\n    return function (modelNode, text, url) {\n\n        url = url || \"\";\n\n        var state = {\n            src: url,\n            basePath: getBasePath(url),\n            objects: [],\n            object: {},\n            positions: [],\n            normals: [],\n            uv: [],\n            materialLibraries: {}\n        };\n\n        startObject(state, \"\", false);\n\n        // Parts of this parser logic are derived from the THREE.js OBJ loader:\n        // https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/OBJLoader.js\n\n        if (text.indexOf('\\r\\n') !== -1) {\n            // This is faster than String.split with regex that splits on both\n            text = text.replace('\\r\\n', '\\n');\n        }\n\n        var lines = text.split('\\n');\n        var line = '', lineFirstChar = '', lineSecondChar = '';\n        var lineLength = 0;\n        var result = [];\n\n        // Faster to just trim left side of the line. Use if available.\n        var trimLeft = (typeof ''.trimLeft === 'function');\n\n        for (var i = 0, l = lines.length; i < l; i++) {\n\n            line = lines[i];\n\n            line = trimLeft ? line.trimLeft() : line.trim();\n\n            lineLength = line.length;\n\n            if (lineLength === 0) {\n                continue;\n            }\n\n            lineFirstChar = line.charAt(0);\n\n            if (lineFirstChar === '#') {\n                continue;\n            }\n\n            if (lineFirstChar === 'v') {\n\n                lineSecondChar = line.charAt(1);\n\n                if (lineSecondChar === ' ' && (result = regexp.vertex_pattern.exec(line)) !== null) {\n\n                    // 0                  1      2      3\n                    // ['v 1.0 2.0 3.0', '1.0', '2.0', '3.0']\n\n                    state.positions.push(\n                        parseFloat(result[1]),\n                        parseFloat(result[2]),\n                        parseFloat(result[3])\n                    );\n\n                } else if (lineSecondChar === 'n' && (result = regexp.normal_pattern.exec(line)) !== null) {\n\n                    // 0                   1      2      3\n                    // ['vn 1.0 2.0 3.0', '1.0', '2.0', '3.0']\n\n                    state.normals.push(\n                        parseFloat(result[1]),\n                        parseFloat(result[2]),\n                        parseFloat(result[3])\n                    );\n\n                } else if (lineSecondChar === 't' && (result = regexp.uv_pattern.exec(line)) !== null) {\n\n                    // 0               1      2\n                    // ['vt 0.1 0.2', '0.1', '0.2']\n\n                    state.uv.push(\n                        parseFloat(result[1]),\n                        parseFloat(result[2])\n                    );\n\n                } else {\n\n                    modelNode.error('Unexpected vertex/normal/uv line: \\'' + line + '\\'');\n                    return;\n                }\n\n            } else if (lineFirstChar === 'f') {\n\n                if ((result = regexp.face_vertex_uv_normal.exec(line)) !== null) {\n\n                    // f vertex/uv/normal vertex/uv/normal vertex/uv/normal\n                    // 0                        1    2    3    4    5    6    7    8    9   10         11         12\n                    // ['f 1/1/1 2/2/2 3/3/3', '1', '1', '1', '2', '2', '2', '3', '3', '3', undefined, undefined, undefined]\n\n                    addFace(state,\n                        result[1], result[4], result[7], result[10],\n                        result[2], result[5], result[8], result[11],\n                        result[3], result[6], result[9], result[12]\n                    );\n\n                } else if ((result = regexp.face_vertex_uv.exec(line)) !== null) {\n\n                    // f vertex/uv vertex/uv vertex/uv\n                    // 0                  1    2    3    4    5    6   7          8\n                    // ['f 1/1 2/2 3/3', '1', '1', '2', '2', '3', '3', undefined, undefined]\n\n                    addFace(state,\n                        result[1], result[3], result[5], result[7],\n                        result[2], result[4], result[6], result[8]\n                    );\n\n                } else if ((result = regexp.face_vertex_normal.exec(line)) !== null) {\n\n                    // f vertex//normal vertex//normal vertex//normal\n                    // 0                     1    2    3    4    5    6   7          8\n                    // ['f 1//1 2//2 3//3', '1', '1', '2', '2', '3', '3', undefined, undefined]\n\n                    addFace(state,\n                        result[1], result[3], result[5], result[7],\n                        undefined, undefined, undefined, undefined,\n                        result[2], result[4], result[6], result[8]\n                    );\n\n                } else if ((result = regexp.face_vertex.exec(line)) !== null) {\n\n                    // f vertex vertex vertex\n                    // 0            1    2    3   4\n                    // ['f 1 2 3', '1', '2', '3', undefined]\n\n                    addFace(state, result[1], result[2], result[3], result[4]);\n                } else {\n                    modelNode.error('Unexpected face line: \\'' + line + '\\'');\n                    return;\n                }\n\n            } else if (lineFirstChar === 'l') {\n\n                var lineParts = line.substring(1).trim().split(' ');\n                var lineVertices = [], lineUVs = [];\n\n                if (line.indexOf('/') === -1) {\n\n                    lineVertices = lineParts;\n\n                } else {\n                    for (var li = 0, llen = lineParts.length; li < llen; li++) {\n                        var parts = lineParts[li].split('/');\n                        if (parts[0] !== '') {\n                            lineVertices.push(parts[0]);\n                        }\n                        if (parts[1] !== '') {\n                            lineUVs.push(parts[1]);\n                        }\n                    }\n                }\n                addLineGeometry(state, lineVertices, lineUVs);\n\n            } else if ((result = regexp.object_pattern.exec(line)) !== null) {\n\n                // o object_name\n                // or\n                // g group_name\n\n                var id = result[0].substr(1).trim();\n                startObject(state, id, true);\n\n            } else if (regexp.material_use_pattern.test(line)) {\n\n                // material\n\n                var id = line.substring(7).trim();\n                state.object.material.id = id;\n\n            } else if (regexp.material_library_pattern.test(line)) {\n\n                // mtl file\n\n                state.materialLibraries[line.substring(7).trim()] = true;\n\n            } else if ((result = regexp.smoothing_pattern.exec(line)) !== null) {\n\n                // smooth shading\n\n                var value = result[1].trim().toLowerCase();\n                state.object.material.smooth = (value === '1' || value === 'on');\n\n            } else {\n\n                // Handle null terminated files without exception\n                if (line === '\\0') {\n                    continue;\n                }\n\n                modelNode.error('Unexpected line: \\'' + line + '\\'');\n                return;\n            }\n        }\n\n        return state;\n    };\n\n    function getBasePath(src) {\n        var n = src.lastIndexOf('/');\n        return (n === -1) ? src : src.substring(0, n + 1);\n    }\n\n    function startObject(state, id, fromDeclaration) {\n        if (state.object && state.object.fromDeclaration === false) {\n            state.object.id = id;\n            state.object.fromDeclaration = (fromDeclaration !== false);\n            return;\n        }\n        state.object = {\n            id: id || '',\n            geometry: {\n                positions: [],\n                normals: [],\n                uv: []\n            },\n            material: {\n                id: '',\n                smooth: true\n            },\n            fromDeclaration: (fromDeclaration !== false)\n        };\n        state.objects.push(state.object);\n    }\n\n    function parseVertexIndex(value, len) {\n        var index = parseInt(value, 10);\n        return (index >= 0 ? index - 1 : index + len / 3) * 3;\n    }\n\n    function parseNormalIndex(value, len) {\n        var index = parseInt(value, 10);\n        return (index >= 0 ? index - 1 : index + len / 3) * 3;\n    }\n\n    function parseUVIndex(value, len) {\n        var index = parseInt(value, 10);\n        return (index >= 0 ? index - 1 : index + len / 2) * 2;\n    }\n\n    function addVertex(state, a, b, c) {\n        var src = state.positions;\n        var dst = state.object.geometry.positions;\n        dst.push(src[a + 0]);\n        dst.push(src[a + 1]);\n        dst.push(src[a + 2]);\n        dst.push(src[b + 0]);\n        dst.push(src[b + 1]);\n        dst.push(src[b + 2]);\n        dst.push(src[c + 0]);\n        dst.push(src[c + 1]);\n        dst.push(src[c + 2]);\n    }\n\n    function addVertexLine(state, a) {\n        var src = state.positions;\n        var dst = state.object.geometry.positions;\n        dst.push(src[a + 0]);\n        dst.push(src[a + 1]);\n        dst.push(src[a + 2]);\n    }\n\n    function addNormal(state, a, b, c) {\n        var src = state.normals;\n        var dst = state.object.geometry.normals;\n        dst.push(src[a + 0]);\n        dst.push(src[a + 1]);\n        dst.push(src[a + 2]);\n        dst.push(src[b + 0]);\n        dst.push(src[b + 1]);\n        dst.push(src[b + 2]);\n        dst.push(src[c + 0]);\n        dst.push(src[c + 1]);\n        dst.push(src[c + 2]);\n    }\n\n    function addUV(state, a, b, c) {\n        var src = state.uv;\n        var dst = state.object.geometry.uv;\n        dst.push(src[a + 0]);\n        dst.push(src[a + 1]);\n        dst.push(src[b + 0]);\n        dst.push(src[b + 1]);\n        dst.push(src[c + 0]);\n        dst.push(src[c + 1]);\n    }\n\n    function addUVLine(state, a) {\n        var src = state.uv;\n        var dst = state.object.geometry.uv;\n        dst.push(src[a + 0]);\n        dst.push(src[a + 1]);\n    }\n\n    function addFace(state, a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd) {\n        var vLen = state.positions.length;\n        var ia = parseVertexIndex(a, vLen);\n        var ib = parseVertexIndex(b, vLen);\n        var ic = parseVertexIndex(c, vLen);\n        var id;\n        if (d === undefined) {\n            addVertex(state, ia, ib, ic);\n\n        } else {\n            id = parseVertexIndex(d, vLen);\n            addVertex(state, ia, ib, id);\n            addVertex(state, ib, ic, id);\n        }\n\n        if (ua !== undefined) {\n\n            var uvLen = state.uv.length;\n\n            ia = parseUVIndex(ua, uvLen);\n            ib = parseUVIndex(ub, uvLen);\n            ic = parseUVIndex(uc, uvLen);\n\n            if (d === undefined) {\n                addUV(state, ia, ib, ic);\n\n            } else {\n                id = parseUVIndex(ud, uvLen);\n                addUV(state, ia, ib, id);\n                addUV(state, ib, ic, id);\n            }\n        }\n\n        if (na !== undefined) {\n\n            // Normals are many times the same. If so, skip function call and parseInt.\n\n            var nLen = state.normals.length;\n\n            ia = parseNormalIndex(na, nLen);\n            ib = na === nb ? ia : parseNormalIndex(nb, nLen);\n            ic = na === nc ? ia : parseNormalIndex(nc, nLen);\n\n            if (d === undefined) {\n                addNormal(state, ia, ib, ic);\n\n            } else {\n\n                id = parseNormalIndex(nd, nLen);\n                addNormal(state, ia, ib, id);\n                addNormal(state, ib, ic, id);\n            }\n        }\n    }\n\n    function addLineGeometry(state, positions, uv) {\n\n        state.object.geometry.type = 'Line';\n\n        var vLen = state.positions.length;\n        var uvLen = state.uv.length;\n\n        for (var vi = 0, l = positions.length; vi < l; vi++) {\n            addVertexLine(state, parseVertexIndex(positions[vi], vLen));\n        }\n\n        for (var uvi = 0, uvl = uv.length; uvi < uvl; uvi++) {\n            addUVLine(state, parseUVIndex(uv[uvi], uvLen));\n        }\n    }\n})();\n\n//--------------------------------------------------------------------------------------------\n// Loads MTL files listed in parsed state\n//--------------------------------------------------------------------------------------------\n\nfunction loadMTLs(modelNode, state, ok) {\n    var basePath = state.basePath;\n    var srcList = Object.keys(state.materialLibraries);\n    var numToLoad = srcList.length;\n    for (var i = 0, len = numToLoad; i < len; i++) {\n        loadMTL(modelNode, basePath, basePath + srcList[i], function () {\n            if (--numToLoad === 0) {\n                ok();\n            }\n        });\n    }\n}\n\n//--------------------------------------------------------------------------------------------\n// Loads an MTL file\n//--------------------------------------------------------------------------------------------\n\nvar loadMTL = function (modelNode, basePath, src, ok) {\n    loadFile(src, function (text) {\n            parseMTL(modelNode, text, basePath);\n            ok();\n        },\n        function (error) {\n            modelNode.error(error);\n            ok();\n        });\n};\n\nvar parseMTL = (function () {\n\n    var delimiter_pattern = /\\s+/;\n\n    return function (modelNode, mtlText, basePath) {\n\n        var lines = mtlText.split('\\n');\n        var materialCfg = {\n            id: \"Default\"\n        };\n        var needCreate = false;\n        var line;\n        var pos;\n        var key;\n        var value;\n        var alpha;\n\n        basePath = basePath || \"\";\n\n        for (var i = 0; i < lines.length; i++) {\n\n            line = lines[i].trim();\n\n            if (line.length === 0 || line.charAt(0) === '#') { // Blank line or comment ignore\n                continue;\n            }\n\n            pos = line.indexOf(' ');\n\n            key = (pos >= 0) ? line.substring(0, pos) : line;\n            key = key.toLowerCase();\n\n            value = (pos >= 0) ? line.substring(pos + 1) : '';\n            value = value.trim();\n\n            switch (key.toLowerCase()) {\n\n                case \"newmtl\": // New material\n                    //if (needCreate) {\n                    createMaterial(modelNode, materialCfg);\n                    //}\n                    materialCfg = {\n                        id: value\n                    };\n                    needCreate = true;\n                    break;\n\n                case 'ka':\n                    materialCfg.ambient = parseRGB(value);\n                    break;\n\n                case 'kd':\n                    materialCfg.diffuse = parseRGB(value);\n                    break;\n\n                case 'ks':\n                    materialCfg.specular = parseRGB(value);\n                    break;\n\n                case 'map_kd':\n                    if (!materialCfg.diffuseMap) {\n                        materialCfg.diffuseMap = createTexture(modelNode, basePath, value, \"sRGB\");\n                    }\n                    break;\n\n                case 'map_ks':\n                    if (!materialCfg.specularMap) {\n                        materialCfg.specularMap = createTexture(modelNode, basePath, value, \"linear\");\n                    }\n                    break;\n\n                case 'map_bump':\n                case 'bump':\n                    if (!materialCfg.normalMap) {\n                        materialCfg.normalMap = createTexture(modelNode, basePath, value);\n                    }\n                    break;\n\n                case 'ns':\n                    materialCfg.shininess = parseFloat(value);\n                    break;\n\n                case 'd':\n                    alpha = parseFloat(value);\n                    if (alpha < 1) {\n                        materialCfg.alpha = alpha;\n                        materialCfg.alphaMode = \"blend\";\n                    }\n                    break;\n\n                case 'tr':\n                    alpha = parseFloat(value);\n                    if (alpha > 0) {\n                        materialCfg.alpha = 1 - alpha;\n                        materialCfg.alphaMode = \"blend\";\n                    }\n                    break;\n                // modelNode.error(\"Unrecognized token: \" + key);\n            }\n        }\n\n        if (needCreate) {\n            createMaterial(modelNode, materialCfg);\n        }\n    };\n\n    function createTexture(modelNode, basePath, value, encoding) {\n        var textureCfg = {};\n        var items = value.split(/\\s+/);\n        var pos = items.indexOf('-bm');\n        if (pos >= 0) {\n            //matParams.bumpScale = parseFloat(items[pos + 1]);\n            items.splice(pos, 2);\n        }\n        pos = items.indexOf('-s');\n        if (pos >= 0) {\n            textureCfg.scale = [parseFloat(items[pos + 1]), parseFloat(items[pos + 2])];\n            items.splice(pos, 4); // we expect 3 parameters here!\n        }\n        pos = items.indexOf('-o');\n        if (pos >= 0) {\n            textureCfg.translate = [parseFloat(items[pos + 1]), parseFloat(items[pos + 2])];\n            items.splice(pos, 4); // we expect 3 parameters here!\n        }\n        textureCfg.src = basePath + items.join(' ').trim();\n        textureCfg.flipY = true;\n        textureCfg.encoding = encoding || \"linear\";\n        //textureCfg.wrapS = self.wrap;\n        //textureCfg.wrapT = self.wrap;\n        var texture = new Texture(modelNode, textureCfg);\n        return texture.id;\n    }\n\n    function createMaterial(modelNode, materialCfg) {\n        new PhongMaterial(modelNode, materialCfg);\n    }\n\n    function parseRGB(value) {\n        var ss = value.split(delimiter_pattern, 3);\n        return [parseFloat(ss[0]), parseFloat(ss[1]), parseFloat(ss[2])];\n    }\n\n})();\n//--------------------------------------------------------------------------------------------\n// Creates meshes from parsed state\n//--------------------------------------------------------------------------------------------\n\n\nfunction createMeshes(modelNode, state) {\n\n    for (var j = 0, k = state.objects.length; j < k; j++) {\n\n        var object = state.objects[j];\n        var geometry = object.geometry;\n        (geometry.type === 'Line');\n\n        if (geometry.positions.length === 0) {\n            // Skip o/g line declarations that did not follow with any faces\n            continue;\n        }\n\n        var geometryCfg = {\n            primitive: \"triangles\",\n            compressGeometry: false\n        };\n\n        geometryCfg.positions = geometry.positions;\n\n        if (geometry.normals.length > 0) {\n            geometryCfg.normals = geometry.normals;\n        }\n\n        if (geometry.uv.length > 0) {\n            geometryCfg.uv = geometry.uv;\n        }\n\n        var indices = new Array(geometryCfg.positions.length / 3); // Triangle soup\n        for (var idx = 0; idx < indices.length; idx++) {\n            indices[idx] = idx;\n        }\n        geometryCfg.indices = indices;\n\n        const origin = tempVec3a$3;\n\n        worldToRTCPositions(geometry.positions, geometry.positions, origin);\n\n        var readableGeometry = new ReadableGeometry(modelNode, geometryCfg);\n\n        var materialId = object.material.id;\n        var material;\n        if (materialId && materialId !== \"\") {\n            material = modelNode.scene.components[materialId];\n            if (!material) {\n                modelNode.error(\"Material not found: \" + materialId);\n            }\n        } else {\n            material = new PhongMaterial(modelNode, {\n                //emissive: [0.6, 0.6, 0.0],\n                diffuse: [0.6, 0.6, 0.6],\n                backfaces: true\n            });\n\n        }\n\n        // material.emissive = [Math.random(), Math.random(), Math.random()];\n\n        var mesh = new Mesh(modelNode, {\n            id: modelNode.id + \"#\" + object.id,\n            origin: (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0) ? origin : null,\n            isObject: true,\n            geometry: readableGeometry,\n            material: material,\n            pickable: true\n        });\n\n        modelNode.addChild(mesh);\n    }\n}\n\nfunction loadFile(url, ok, err) {\n    var request = new XMLHttpRequest();\n    request.open('GET', url, true);\n    request.addEventListener('load', function (event) {\n        var response = event.target.response;\n        if (this.status === 200) {\n            if (ok) {\n                ok(response);\n            }\n        } else if (this.status === 0) {\n            // Some browsers return HTTP Status 0 when using non-http protocol\n            // e.g. 'file://' or 'data://'. Handle as success.\n            console.warn('loadFile: HTTP Status 0 received.');\n            if (ok) {\n                ok(response);\n            }\n        } else {\n            if (err) {\n                err(event);\n            }\n        }\n    }, false);\n\n    request.addEventListener('error', function (event) {\n        if (err) {\n            err(event);\n        }\n    }, false);\n    request.send(null);\n}\n\n/**\n * {@link Viewer} plugin that loads models from [OBJ](https://en.wikipedia.org/wiki/Wavefront_.obj_file) files.\n *\n * * Creates an {@link Entity} representing each model it loads, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.\n * * Creates an {@link Entity} for each object within the model, which will have {@link Entity#isObject} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.\n * * When loading, can set the World-space position, scale and rotation of each model within World space, along with initial properties for all the model's {@link Entity}s.\n *\n * ## Metadata\n *\n * OBJLoaderPlugin can also load an accompanying JSON metadata file with each model, which creates a {@link MetaModel} corresponding\n * to the model {@link Entity} and a {@link MetaObject} corresponding to each object {@link Entity}.\n *\n * Each {@link MetaObject} has a {@link MetaObject#type}, which indicates the classification of its corresponding {@link Entity}. When loading\n * metadata, we can also provide GLTFModelLoaderPlugin with a custom lookup table of initial values to set on the properties of each type of {@link Entity}. By default, OBJLoaderPlugin\n * uses its own map of standard default colors, visibilities and opacities for IFC element types.\n\n *\n * ## Usage\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/cad/#OBJ_SportsCar_ExplodeModel)]\n *\n * ````javascript\n * import {Viewer, OBJLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * // Create a xeokit Viewer and arrange the camera\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * viewer.camera.orbitPitch(20);\n *\n * // Add an OBJLoaderPlugin to the Viewer\n * const objLoader = new OBJLoaderPlugin(viewer);\n *\n * // Load an OBJ model\n * var model = objLoader.load({ // Model is an Entity\n *      id: \"myModel\",\n *      src: \"./models/obj/sportsCar/sportsCar.obj\",\n *      edges: true\n * });\n *\n * // When the model has loaded, fit it to view\n * model.on(\"loaded\", () => {\n *      viewer.cameraFlight.flyTo(model);\n * })\n *\n * // Find the model Entity by ID\n * model = viewer.scene.models[\"myModel\"];\n *\n * // Update properties of the model Entity\n * model.highlight = [1,0,0];\n *\n * // Destroy the model\n * model.destroy();\n * ````\n * @class OBJLoaderPlugin\n */\nclass OBJLoaderPlugin extends Plugin {\n\n    /**\n     * @constructor\n     *\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg Plugin configuration.\n     * @param {String} [cfg.id=\"OBJLoader\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     */\n    constructor(viewer, cfg) {\n\n        super(\"OBJLoader\", viewer, cfg);\n\n        /**\n         * @private\n         */\n        this._sceneGraphLoader = new OBJSceneGraphLoader();\n    }\n\n    /**\n     * Loads an OBJ model from a file into this OBJLoader's {@link Viewer}.\n     *\n     * @param {*} params  Loading parameters.\n     * @param {String} params.id ID to assign to the model's root {@link Entity}, unique among all components in the Viewer's {@link Scene}.\n     * @param {String} params.src Path to an OBJ file.\n     * @param {String} [params.metaModelSrc] Path to an optional metadata file.\n     * @param {Number[]} [params.position=[0,0,0]] The model World-space 3D position.\n     * @param {Number[]} [params.scale=[1,1,1]] The model's World-space scale.\n     * @param {Number[]} [params.rotation=[0,0,0]] The model's World-space rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [params.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] The model's world transform matrix. Overrides the position, scale and rotation parameters.\n     * @param {Number} [params.edgeThreshold=20] When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n     * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}\n     */\n    load(params = {}) {\n\n        if (params.id && this.viewer.scene.components[params.id]) {\n            this.error(\"Component with this ID already exists in viewer: \" + params.id + \" - will autogenerate this ID\");\n            delete params.id;\n        }\n\n        var modelNode = new Node$1(this.viewer.scene, utils.apply(params, {\n            isModel: true\n        }));\n\n        const modelId = modelNode.id;  // In case ID was auto-generated\n        const src = params.src;\n\n        if (!src) {\n            this.error(\"load() param expected: src\");\n            return modelNode;\n        }\n\n        if (params.metaModelSrc) {\n            const metaModelSrc = params.metaModelSrc;\n            utils.loadJSON(metaModelSrc,\n                (modelMetadata) => {\n                    this.viewer.metaScene.createMetaModel(modelId, modelMetadata);\n                    this._sceneGraphLoader.load(modelNode, src, params);\n                },\n                (errMsg) => {\n                    this.error(`load(): Failed to load model modelMetadata for model '${modelId} from  '${metaModelSrc}' - ${errMsg}`);\n                });\n        } else {\n            this._sceneGraphLoader.load(modelNode, src, params);\n        }\n\n        modelNode.once(\"destroyed\", () => {\n            this.viewer.metaScene.destroyMetaModel(modelId);\n        });\n\n        return modelNode;\n    }\n\n    /**\n     * Destroys this OBJLoaderPlugin.\n     */\n    destroy() {\n        super.destroy();\n    }\n}\n\n/**\n * Controls a transformation with mouse and touch input.\n *\n * @private\n */\nclass TransformControl {\n\n    /** @private */\n    constructor(viewer) {\n        const cameraControl = viewer.cameraControl;\n        const scene = viewer.scene;\n        const canvas = scene.canvas.canvas;\n\n        // Builds the Entities that represent this Control.\n        const NO_STATE_INHERIT = false;\n        const arrowLength = 1.0;\n        const handleRadius = 0.09;\n        const tubeRadius = 0.01;\n\n        const rootNode = new Node$1(scene, { // Root of Node graph that represents this control in the 3D scene\n            position: [0, 0, 0],\n            scale: [5, 5, 5],\n            isObject: false\n        });\n\n        const pos = math.vec3();\n        this._setPosition = (function() {\n            const origin = math.vec3();\n            const rtcPos = math.vec3();\n            return function(p) {\n                pos.set(p);\n                worldToRTCPos(p, origin, rtcPos);\n                rootNode.origin = origin;\n                rootNode.position = rtcPos;\n            };\n        })();\n\n        this._setQuaternion = q => { rootNode.quaternion = q; };\n\n        const arrowGeometry = (radiusBottom, height) => new ReadableGeometry(rootNode, buildCylinderGeometry({\n            radiusTop: 0.001,\n            radiusBottom: radiusBottom,\n            radialSegments: 32,\n            heightSegments: 1,\n            height: height,\n            openEnded: false\n        }));\n\n        const tubeGeometry = (radius, height, radialSegments) => new ReadableGeometry(rootNode, buildCylinderGeometry({\n            radiusTop: radius,\n            radiusBottom: radius,\n            radialSegments: radialSegments,\n            heightSegments: 1,\n            height: height,\n            openEnded: false\n        }));\n\n        const torusGeometry = (tube, arcFraction, tubeSegments) => new ReadableGeometry(rootNode, buildTorusGeometry({\n            radius: arrowLength - 0.2,\n            tube: tube,\n            radialSegments: 64,\n            tubeSegments: tubeSegments,\n            arc: (Math.PI * 2.0) * arcFraction\n        }));\n\n        const shapes = {// Reusable geometries\n\n            curve:       torusGeometry(tubeRadius,   0.25, 14),\n            curveHandle: torusGeometry(handleRadius, 0.25, 14),\n            hoop:        torusGeometry(tubeRadius,   1,     8),\n\n            arrowHead:       arrowGeometry(0.07, 0.2),\n            arrowHeadBig:    arrowGeometry(0.09, 0.25),\n            arrowHeadHandle: tubeGeometry(handleRadius, 0.37, 8),\n\n            axis:       tubeGeometry(tubeRadius,   arrowLength, 20),\n            axisHandle: tubeGeometry(handleRadius, arrowLength, 20)\n        };\n\n        const colorMaterial = (rgb) => new PhongMaterial(rootNode, {\n            diffuse: rgb,\n            emissive: rgb,\n            ambient: [0.0, 0.0, 0.0],\n            specular: [.6, .6, .3],\n            shininess: 80,\n            lineWidth: 2\n        });\n\n        const highlightMaterial = (rgb, fillAlpha) => new EmphasisMaterial(rootNode, {\n            edges: false,\n            fill: true,\n            fillColor: rgb,\n            fillAlpha: fillAlpha\n        });\n\n        const pickableMaterial = new PhongMaterial(rootNode, { // Invisible material for pickable handles, which define a pickable 3D area\n            diffuse: [1, 1, 0],\n            alpha: 0, // Invisible\n            alphaMode: \"blend\"\n        });\n\n        const handlers = { };\n        const addAxis = (rgb, hoopRot) => {\n            math.mulVec3Scalar(rgb, -1, math.vec3());\n            const material = colorMaterial(rgb);\n\n            const hoopMatrix = math.quaternionToRotationMat4(hoopRot, math.identityMat4());\n            math.mulMat4(math.rotationMat4v(Math.PI, [0,1,0], math.mat4()), hoopMatrix, hoopMatrix);\n            const scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());\n            const scaledArrowMatrix = (t, matR) => {\n                const matT = math.translateMat4v(t, math.identityMat4());\n                const ret = math.identityMat4();\n                math.mulMat4(matT, matR, ret);\n                math.mulMat4(hoopMatrix, ret, ret);\n                return math.mulMat4(ret, scale, math.identityMat4());\n            };\n\n            const curve = rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.curve,\n                material: material,\n                matrix: hoopMatrix,\n                pickable: false,\n                collidable: true,\n                clippable: false,\n                backfaces: true,\n                visible: false,\n                isUI: true,\n                isObject: false\n            }), NO_STATE_INHERIT);\n\n            const rotateHandle = rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.curveHandle,\n                material: pickableMaterial,\n                matrix: hoopMatrix,\n                pickable: true,\n                collidable: true,\n                clippable: false,\n                backfaces: true,\n                visible: false,\n                isUI: true,\n                isObject: false\n            }), NO_STATE_INHERIT);\n\n            const arrow1 = rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.arrowHead,\n                material: material,\n                matrix: scaledArrowMatrix([ .8, .07, 0 ], math.rotationMat4v(180 * math.DEGTORAD, [0, 0, 1], math.identityMat4())),\n                pickable: true,\n                collidable: true,\n                clippable: false,\n                visible: false,\n                isUI: true,\n                isObject: false\n            }), NO_STATE_INHERIT);\n\n            const arrow2 = rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.arrowHead,\n                material: material,\n                matrix: scaledArrowMatrix([ .07, .8, 0 ], math.rotationMat4v(90 * math.DEGTORAD, [0, 0, 1], math.identityMat4())),\n                pickable: true,\n                collidable: true,\n                clippable: false,\n                visible: false,\n                isUI: true,\n                isObject: false\n            }), NO_STATE_INHERIT);\n\n            const hoop = rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.hoop,\n                material: material,\n                highlighted: true,\n                highlightMaterial: highlightMaterial(rgb, 0.6),\n                matrix: hoopMatrix,\n                pickable: false,\n                collidable: true,\n                clippable: false,\n                visible: false,\n                isUI: true,\n                isObject: false\n            }), NO_STATE_INHERIT);\n\n\n            const axisRotation = math.quaternionToRotationMat4(math.vec3PairToQuaternion([ 0, 1, 0 ], rgb), math.identityMat4());\n            math.mulMat4(math.rotationMat4v(Math.PI, [0,1,0], math.mat4()), axisRotation, axisRotation);\n\n            const translatedAxisMatrix = (yOffset) => math.mulMat4(axisRotation, math.translateMat4c(0, yOffset, 0, math.identityMat4()), math.identityMat4());\n            const arrowMatrix = translatedAxisMatrix(arrowLength + .1);\n            const shaftMatrix = translatedAxisMatrix(arrowLength / 2);\n\n            const arrow = rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.arrowHead,\n                material: material,\n                matrix: arrowMatrix,\n                pickable: false,\n                collidable: true,\n                clippable: false,\n                visible: false,\n                isUI: true,\n                isObject: false\n            }), NO_STATE_INHERIT);\n\n            const arrowHandle = rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.arrowHeadHandle,\n                material: pickableMaterial,\n                matrix: arrowMatrix,\n                pickable: true,\n                collidable: true,\n                clippable: false,\n                visible: false,\n                isUI: true,\n                isObject: false\n            }), NO_STATE_INHERIT);\n\n            const shaft = rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.axis,\n                material: material,\n                matrix: shaftMatrix,\n                pickable: false,\n                collidable: true,\n                clippable: false,\n                visible: false,\n                isUI: true,\n                isObject: false\n            }), NO_STATE_INHERIT);\n\n            const shaftHandle = rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.axisHandle,\n                material: pickableMaterial,\n                matrix: shaftMatrix,\n                pickable: true,\n                collidable: true,\n                clippable: false,\n                visible: false,\n                isUI: true,\n                isObject: false\n            }), NO_STATE_INHERIT);\n\n            const bigArrowHead = rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.arrowHeadBig,\n                material: material,\n                matrix: arrowMatrix,\n                pickable: false,\n                collidable: true,\n                clippable: false,\n                visible: false,\n                isUI: true,\n                isObject: false\n            }), NO_STATE_INHERIT);\n\n            const localToWorldVec = (localVec, worldVec) => math.vec3ApplyQuaternion(rootNode.quaternion, localVec, worldVec);\n\n            const closestPointOnAxis = (function() {\n                const worldAxis = math.vec3();\n                const org = math.vec3();\n                const dir = math.vec3();\n                return (canvasPos, dst) => {\n                    localToWorldVec(rgb, worldAxis);\n\n                    const P = pos;\n                    const D = worldAxis;\n\n                    math.canvasPosToWorldRay(canvas, scene.camera.viewMatrix, scene.camera.projMatrix, scene.camera.projection, canvasPos, org, dir);\n\n                    const d01 = math.dotVec3(D, dir);\n                    const v = math.subVec3(org, P, dst);\n                    const v0 = math.dotVec3(v, D);\n                    const v1 = math.dotVec3(v, dir);\n                    const det = 1 - d01 * d01;\n\n                    if (Math.abs(det) > 1e-10) { // if lines are not parallel\n                        const s = (v0 - d01 * v1) / det;\n                        math.addVec3(P, math.mulVec3Scalar(D, s, dst), dst);\n                        return true;\n                    } else {\n                        return false;\n                    }\n                };\n            })();\n            const initOffset = math.vec3();\n            const tempVec3 = math.vec3();\n            handlers[arrowHandle.id] = handlers[shaftHandle.id] = {\n                setActivated: a => bigArrowHead.visible = a,\n                initDragAction: (initCanvasPos) => {\n                    return closestPointOnAxis(initCanvasPos, initOffset) && math.subVec3(initOffset, pos, initOffset) && ((canvasPos) => {\n                        if (closestPointOnAxis(canvasPos, tempVec3)) {\n                            math.subVec3(tempVec3, initOffset, tempVec3);\n                            this._setPosition(tempVec3);\n                            if (this._handlers) {\n                                this._handlers.onPosition(tempVec3);\n                            }\n                        }\n                    });\n                }\n            };\n\n            handlers[rotateHandle.id] = {\n                setActivated: a => hoop.visible = a,\n                initDragAction: (initCanvasPos) => {\n                    const rotationFromCanvasPos = (function() {\n                        const planeCanvasPos = scene.camera.projectWorldPos(pos);\n                        localToWorldVec(rgb, tempVec3);\n                        math.transformVec3(scene.camera.normalMatrix, tempVec3, tempVec3);\n                        const axisCoeff = Math.sign(tempVec3[2]);\n                        return (canvasPos) => {\n                            const dx = canvasPos[0] - planeCanvasPos[0];\n                            const dy = canvasPos[1] - planeCanvasPos[1];\n                            return axisCoeff * Math.atan2(-dy, dx);\n                        };\n                    })();\n\n                    let lastRotation = rotationFromCanvasPos(initCanvasPos);\n\n                    return canvasPos => {\n                        const rotation = rotationFromCanvasPos(canvasPos);\n                        rootNode.rotate(rgb, (rotation - lastRotation) * 180 / Math.PI);\n                        if (this._handlers) {\n                            this._handlers.onQuaternion(rootNode.quaternion);\n                        }\n                        lastRotation = rotation;\n                    };\n                }\n            };\n\n            let positionActive = false;\n            let rotationActive = false;\n            let visible = false;\n\n            const updatePositionHandle = () => {\n                const v = visible && positionActive;\n                arrowHandle.visible = shaftHandle.visible = arrow.visible = shaft.visible = !!v;\n                if (! v) {\n                    bigArrowHead.visible = false;\n                }\n            };\n            const updateRotationHandle = () => {\n                const v = visible && rotationActive;\n                rotateHandle.visible = curve.visible = arrow1.visible = arrow2.visible = !!v;\n                if (! v) {\n                    hoop.visible = false;\n                }\n            };\n\n            return {\n                setPositionActive: (a) => { positionActive = a; updatePositionHandle(); },\n                setRotationActive: (a) => { rotationActive = a; updateRotationHandle(); },\n                set visible(v) {\n                    visible = v;\n                    updatePositionHandle();\n                    updateRotationHandle();\n                }\n            };\n        };\n\n        this._displayMeshes = {\n            center: rootNode.addChild(new Mesh(rootNode, { // center\n                geometry: new ReadableGeometry(rootNode, buildSphereGeometry({\n                    radius: 0.05\n                })),\n                material: new PhongMaterial(rootNode, {\n                    diffuse: [0.0, 0.0, 0.0],\n                    emissive: [0, 0, 0],\n                    ambient: [0.0, 0.0, 0.0],\n                    specular: [.6, .6, .3],\n                    shininess: 80\n                }),\n                pickable: false,\n                collidable: true,\n                clippable: false,\n                visible: false,\n                isObject: false\n            }), NO_STATE_INHERIT),\n\n            x: addAxis([1,0,0], math.vec3PairToQuaternion([1,0,0], [0,0,1])),\n            y: addAxis([0,1,0], math.eulerToQuaternion([90,0,0], \"XYZ\")),\n            z: addAxis([0,0,1], math.identityQuaternion())\n        };\n\n        const cleanups = [ ];\n\n        { // Keep gizmo screen size constant\n            let lastDist = -1;\n            const setRootNodeScale = size => {\n                if (rootNode.scale[0] !== size) {\n                    rootNode.scale = [size, size, size];\n                    if (this._handlers && this._handlers.onScreenScale) {\n                        this._handlers.onScreenScale(rootNode.scale);\n                    }\n                }\n            };\n            const onSceneTick = scene.on(\"tick\", () => {\n                const camera = scene.camera;\n                const dist = Math.abs(math.distVec3(camera.eye, pos));\n                if (camera.projection === \"perspective\") {\n                    if (dist !== lastDist) {\n                        setRootNodeScale(0.07 * dist * Math.tan(camera.perspective.fov * math.DEGTORAD));\n                    }\n                } else if (camera.projection === \"ortho\") {\n                    setRootNodeScale(camera.ortho.scale / 10);\n                }\n                lastDist = dist;\n            });\n            cleanups.push(() => scene.off(onSceneTick));\n        }\n\n        {\n            let deactivateActive = null;\n            let currentDrag = null;\n            cleanups.push(() => { if (currentDrag) { currentDrag.cleanup(); } });\n            const canvasPos = math.vec2();\n\n            const copyCanvasPos = (event, vec2) => {\n                vec2[0] = event.pageX;\n                vec2[1] = event.pageY;\n                transformToNode(canvas.ownerDocument.documentElement, canvas, vec2);\n            };\n            const pickHandler = (e) => {\n                copyCanvasPos(e, canvasPos);\n                // This doesn't guarantee the gizmo is prioritized (as it should be) by other Scene::pick calls\n                const pickResult = scene.pick({ canvasPos: canvasPos });//, includeEntities: pickIds });\n                const pickEntity = pickResult && pickResult.entity;\n                const pickId = pickEntity && pickEntity.id;\n                return (pickId in handlers) && handlers[pickId];\n            };\n\n            const startDrag = (event, matchesEvent) => {\n                const handler = pickHandler(matchesEvent(event));\n                if (handler) {\n                    if (currentDrag) {\n                        currentDrag.cleanup();\n                    }\n\n                    const dragAction = handler.initDragAction(canvasPos);\n                    if (dragAction) {\n                        cameraControl.pointerEnabled = false; // or .active = false ?\n                        handler.setActivated(true);\n\n                        currentDrag = {\n                            onChange: event => {\n                                const e = matchesEvent(event);\n                                if (e) {\n                                    copyCanvasPos(e, canvasPos);\n                                    dragAction(canvasPos);\n                                }\n                            },\n                            cleanup: function() {\n                                currentDrag = null;\n                                cameraControl.pointerEnabled = true; // or .active = true ?\n                                handler.setActivated(false);\n                            }\n                        };\n                    }\n                    return !!dragAction;\n                } else {\n                    return false;\n                }\n            };\n\n            const addCanvasEventListener = (type, listener) => {\n                canvas.addEventListener(type, listener);\n                cleanups.push(() => canvas.removeEventListener(type, listener));\n            };\n\n            const preventDefaultStopPropagation = e => {\n                e.preventDefault();\n                e.stopPropagation();\n                e.stopImmediatePropagation();\n            };\n\n            addCanvasEventListener(\"mousedown\", (e) => {\n                if ((e.which === 1) && startDrag(e, event => (event.which === 1) && event)) {\n                    preventDefaultStopPropagation(e);\n                }\n            });\n\n            addCanvasEventListener(\"mousemove\", (e) => {\n                if (currentDrag) {\n                    currentDrag.onChange(e);\n                    preventDefaultStopPropagation(e);\n                } else {\n                    if (deactivateActive) {\n                        deactivateActive();\n                    }\n                    const handler = pickHandler(e);\n                    if (handler) {\n                        handler.setActivated(true);\n                        deactivateActive = () => handler.setActivated(false);\n                    } else {\n                        deactivateActive = null;\n                    }\n                }\n            });\n\n            addCanvasEventListener(\"mouseup\", (e) => {\n                if (currentDrag) {\n                    currentDrag.onChange(e);\n                    currentDrag.cleanup();\n                    // Calling preventDefaultStopPropagation would interfere with cameraControl\n                    // by making it follow the pointer until next click\n                    // preventDefaultStopPropagation(e);\n                }\n            });\n\n\n            addCanvasEventListener(\"touchstart\", event => {\n                event.preventDefault();\n                if (event.touches.length === 1)\n                {\n                    const touchStartId = event.touches[0].identifier;\n                    if (startDrag(event, event => [...event.changedTouches].find(e => e.identifier === touchStartId))) {\n                        preventDefaultStopPropagation(event);\n                    }\n                }\n            });\n\n            addCanvasEventListener(\"touchmove\", event => {\n                if (currentDrag) {\n                    currentDrag.onChange(event);\n                    preventDefaultStopPropagation(event);\n                }\n            });\n\n            addCanvasEventListener(\"touchend\",  event => {\n                if (currentDrag) {\n                    currentDrag.onChange(event);\n                    currentDrag.cleanup();\n                    // See the comment in mouseup listener\n                    // preventDefaultStopPropagation(e);\n                }\n            });\n        }\n\n        this.__destroy = () => {\n            cleanups.forEach(c => c());\n            rootNode.destroy();\n            for (let id in handlers) {\n                delete handlers[id];\n            }\n        };\n    }\n\n    destroy() {\n        this.__destroy();\n    }\n\n    /**\n     * Called to assign this Control to Handlers.\n     * Call with a null or undefined value to disconnect the Control from whatever Handlers it was assigned to.\n     * @private\n     */\n    setHandlers(handlers) {\n        Object.values(this._displayMeshes).forEach(m => m.visible = !!handlers);\n        this._handlers = handlers;\n        this._displayMeshes.x.setPositionActive(handlers && handlers.onPosition);\n        this._displayMeshes.y.setPositionActive(handlers && handlers.onPosition);\n        this._displayMeshes.z.setPositionActive(handlers && handlers.onPosition);\n        this._displayMeshes.x.setRotationActive(handlers && handlers.onQuaternion);\n        this._displayMeshes.y.setRotationActive(handlers && handlers.onQuaternion);\n        this._displayMeshes.z.setRotationActive(handlers && handlers.onQuaternion);\n    }\n\n    /**\n     * Sets the World-space position of this Control.\n     *\n     * @param {Number[]} value New position.\n     */\n    setPosition(p) {\n        this._setPosition(p);\n    }\n\n    /**\n     * Sets the quaternion of this Control.\n     *\n     * @param {Number[]} value New quaternion.\n     */\n    setQuaternion(q) {\n        this._setQuaternion(q);\n    }\n}\n\n/**\n * Renders a 3D plane within an {@link Overview} to indicate its {@link SectionPlane}'s current position and orientation.\n *\n * @private\n */\nclass Plane$1 {\n\n    /** @private */\n    constructor(overview, overviewScene, sectionPlane) {\n\n        /**\n         * The ID of this SectionPlanesOverviewPlane.\n         *\n         * @type {String}\n         */\n        this.id = sectionPlane.id;\n\n        /**\n         * The {@link SectionPlane} represented by this SectionPlanesOverviewPlane.\n         *\n         * @type {SectionPlane}\n         */\n        this._sectionPlane = sectionPlane;\n\n        this._mesh = new Mesh(overviewScene, {\n            id: sectionPlane.id,\n            geometry: new ReadableGeometry(overviewScene, buildBoxGeometry({\n                xSize: .5,\n                ySize: .5,\n                zSize: .001\n            })),\n            material: new PhongMaterial(overviewScene, {\n                emissive: [1, 1, 1],\n                diffuse: [0, 0, 0],\n                backfaces: false\n            }),\n            edgeMaterial: new EdgeMaterial(overviewScene, {\n                edgeColor: [0.0, 0.0, 0.0],\n                edgeAlpha: 1.0,\n                edgeWidth: 1\n            }),\n            highlightMaterial: new EmphasisMaterial(overviewScene, {\n                fill: true,\n                fillColor: [0.5, 1, 0.5],\n                fillAlpha: 0.7,\n                edges: true,\n                edgeColor: [0.0, 0.0, 0.0],\n                edgeAlpha: 1.0,\n                edgeWidth: 1\n            }),\n            selectedMaterial: new EmphasisMaterial(overviewScene, {\n                fill: true,\n                fillColor: [0, 0, 1],\n                fillAlpha: 0.7,\n                edges: true,\n                edgeColor: [1.0, 0.0, 0.0],\n                edgeAlpha: 1.0,\n                edgeWidth: 1\n            }),\n            highlighted: true,\n            scale: [3, 3, 3],\n            position: [0, 0, 0],\n            rotation: [0, 0, 0],\n            opacity: 0.3,\n            edges: true\n        });\n\n\n        {\n            const vec = math.vec3([0, 0, 0]);\n            const pos2 = math.vec3();\n            const zeroVec = math.vec3([0, 0, 1]);\n            const quat = math.vec4(4);\n            const pos3 = math.vec3();\n\n            const update = () => {\n\n                const origin = this._sectionPlane.scene.center;\n\n                const negDir = [-this._sectionPlane.dir[0], -this._sectionPlane.dir[1], -this._sectionPlane.dir[2]];\n                math.subVec3(origin, this._sectionPlane.pos, vec);\n                const dist = -math.dotVec3(negDir, vec);\n\n                math.normalizeVec3(negDir);\n                math.mulVec3Scalar(negDir, dist, pos2);\n                const quaternion = math.vec3PairToQuaternion(zeroVec, this._sectionPlane.dir, quat);\n\n                pos3[0] = pos2[0] * 0.1;\n                pos3[1] = pos2[1] * 0.1;\n                pos3[2] = pos2[2] * 0.1;\n\n                this._mesh.quaternion = quaternion;\n                this._mesh.position = pos3;\n            };\n\n            this._onSectionPlanePos = this._sectionPlane.on(\"pos\", update);\n            this._onSectionPlaneDir = this._sectionPlane.on(\"dir\", update);\n\n            // update();\n        }\n\n        this._highlighted = false;\n        this._selected = false;\n    }\n\n    /**\n     * Sets if this SectionPlanesOverviewPlane is highlighted.\n     *\n     * @type {Boolean}\n     * @private\n     */\n    setHighlighted(highlighted) {\n        this._highlighted = !!highlighted;\n        this._mesh.highlighted = this._highlighted;\n        this._mesh.highlightMaterial.fillColor = highlighted ? [0, 0.7, 0] : [0, 0, 0];\n        // this._selectedMesh.highlighted = true;\n    }\n\n    /**\n     * Gets if this SectionPlanesOverviewPlane is highlighted.\n     *\n     * @type {Boolean}\n     * @private\n     */\n    getHighlighted() {\n        return this._highlighted;\n    }\n\n    /**\n     * Sets if this SectionPlanesOverviewPlane is selected.\n     *\n     * @type {Boolean}\n     * @private\n     */\n    setSelected(selected) {\n        this._selected = !!selected;\n        this._mesh.edgeMaterial.edgeWidth = selected ? 3 : 1;\n        this._mesh.highlightMaterial.edgeWidth = selected ? 3 : 1;\n\n    }\n\n    /**\n     * Gets if this SectionPlanesOverviewPlane is selected.\n     *\n     * @type {Boolean}\n     * @private\n     */\n    getSelected() {\n        return this._selected;\n    }\n\n    /** @private */\n    destroy() {\n        this._sectionPlane.off(this._onSectionPlanePos);\n        this._sectionPlane.off(this._onSectionPlaneDir);\n        this._mesh.destroy();\n    }\n}\n\n/**\n * @desc An interactive 3D overview for navigating the {@link SectionPlane}s created by its {@link SectionPlanesPlugin}.\n *\n * * Located at {@link SectionPlanesPlugin#overview}.\n * * Renders the overview on a separate canvas at a corner of the {@link Viewer}'s {@link Scene} {@link Canvas}.\n * * The overview shows a 3D plane object for each {@link SectionPlane} in the {@link Scene}.\n * * Click a plane object in the overview to toggle the visibility of a 3D gizmo to edit the position and orientation of its {@link SectionPlane}.\n *\n * @private\n */\nclass Overview$1 {\n\n    /**\n     * @private\n     */\n    constructor(plugin, cfg) {\n\n        if (!cfg.onHoverEnterPlane || !cfg.onHoverLeavePlane || !cfg.onClickedNothing || !cfg.onClickedPlane) {\n            throw \"Missing config(s): onHoverEnterPlane, onHoverLeavePlane, onClickedNothing || onClickedPlane\";\n        }\n\n        /**\n         * The {@link SectionPlanesPlugin} that owns this SectionPlanesOverview.\n         *\n         * @type {SectionPlanesPlugin}\n         */\n        this.plugin = plugin;\n\n        this._viewer = plugin.viewer;\n\n        this._onHoverEnterPlane = cfg.onHoverEnterPlane;\n        this._onHoverLeavePlane = cfg.onHoverLeavePlane;\n        this._onClickedNothing = cfg.onClickedNothing;\n        this._onClickedPlane = cfg.onClickedPlane;\n        this._visible = true;\n\n        this._planes = {};\n\n        //--------------------------------------------------------------------------------------------------------------\n        // Init canvas\n        //--------------------------------------------------------------------------------------------------------------\n\n        this._canvas = cfg.overviewCanvas;\n\n        //--------------------------------------------------------------------------------------------------------------\n        // Init scene\n        //--------------------------------------------------------------------------------------------------------------\n\n        this._scene = new Scene(this._viewer, {\n            canvasId: this._canvas.id,\n            transparent: true\n        });\n        this._scene.clearLights();\n        new DirLight(this._scene, {\n            dir: [0.4, -0.4, 0.8],\n            color: [0.8, 1.0, 1.0],\n            intensity: 1.0,\n            space: \"view\"\n        });\n        new DirLight(this._scene, {\n            dir: [-0.8, -0.3, -0.4],\n            color: [0.8, 0.8, 0.8],\n            intensity: 1.0,\n            space: \"view\"\n        });\n        new DirLight(this._scene, {\n            dir: [0.8, -0.6, -0.8],\n            color: [1.0, 1.0, 1.0],\n            intensity: 1.0,\n            space: \"view\"\n        });\n\n        this._scene.camera;\n        this._scene.camera.perspective.fov = 70;\n\n        this._zUp = false;\n\n        //--------------------------------------------------------------------------------------------------------------\n        // Synchronize overview scene camera with viewer camera\n        //--------------------------------------------------------------------------------------------------------------\n\n        {\n            const camera = this._scene.camera;\n            const matrix = math.rotationMat4c(-90 * math.DEGTORAD, 1, 0, 0);\n            const eyeLookVec = math.vec3();\n            const eyeLookVecOverview = math.vec3();\n            const upOverview = math.vec3();\n\n            this._synchCamera = () => {\n                const eye = this._viewer.camera.eye;\n                const look = this._viewer.camera.look;\n                const up = this._viewer.camera.up;\n                math.mulVec3Scalar(math.normalizeVec3(math.subVec3(eye, look, eyeLookVec)), 7);\n                if (this._zUp) { // +Z up\n                    math.transformVec3(matrix, eyeLookVec, eyeLookVecOverview);\n                    math.transformVec3(matrix, up, upOverview);\n                    camera.look = [0, 0, 0];\n                    camera.eye = math.transformVec3(matrix, eyeLookVec, eyeLookVecOverview);\n                    camera.up = math.transformPoint3(matrix, up, upOverview);\n                } else { // +Y up\n                    camera.look = [0, 0, 0];\n                    camera.eye = eyeLookVec;\n                    camera.up = up;\n                }\n            };\n        }\n\n        this._onViewerCameraMatrix = this._viewer.camera.on(\"matrix\", this._synchCamera);\n\n        this._onViewerCameraWorldAxis = this._viewer.camera.on(\"worldAxis\", this._synchCamera);\n\n        this._onViewerCameraFOV = this._viewer.camera.perspective.on(\"fov\", (fov) => {\n            this._scene.camera.perspective.fov = fov;\n        });\n\n        //--------------------------------------------------------------------------------------------------------------\n        // Bind overview canvas events\n        //--------------------------------------------------------------------------------------------------------------\n\n        {\n            var hoveredEntity = null;\n\n            this._onInputMouseMove = this._scene.input.on(\"mousemove\", (coords) => {\n                const hit = this._scene.pick({\n                    canvasPos: coords\n                });\n                if (hit) {\n                    if (!hoveredEntity || hit.entity.id !== hoveredEntity.id) {\n                        if (hoveredEntity) {\n                            const plane = this._planes[hoveredEntity.id];\n                            if (plane) {\n                                this._onHoverLeavePlane(hoveredEntity.id);\n                            }\n                        }\n                        hoveredEntity = hit.entity;\n                        const plane = this._planes[hoveredEntity.id];\n                        if (plane) {\n                            this._onHoverEnterPlane(hoveredEntity.id);\n                        }\n                    }\n                } else {\n                    if (hoveredEntity) {\n                        this._onHoverLeavePlane(hoveredEntity.id);\n                        hoveredEntity = null;\n                    }\n                }\n            });\n\n            this._scene.canvas.canvas.addEventListener(\"mouseup\", this._onCanvasMouseUp = () => {\n                if (hoveredEntity) {\n                    const plane = this._planes[hoveredEntity.id];\n                    if (plane) {\n                        this._onClickedPlane(hoveredEntity.id);\n                    }\n                } else {\n                    this._onClickedNothing();\n                }\n            });\n\n            this._scene.canvas.canvas.addEventListener(\"mouseout\", this._onCanvasMouseOut = () => {\n                if (hoveredEntity) {\n                    this._onHoverLeavePlane(hoveredEntity.id);\n                    hoveredEntity = null;\n                }\n            });\n        }\n\n        //--------------------------------------------------------------------------------------------------------------\n        // Configure overview\n        //--------------------------------------------------------------------------------------------------------------\n\n        this.setVisible(cfg.overviewVisible);\n    }\n\n    /** Called by SectionPlanesPlugin#createSectionPlane()\n     * @private\n     */\n    addSectionPlane(sectionPlane) {\n        this._planes[sectionPlane.id] = new Plane$1(this, this._scene, sectionPlane);\n    }\n\n    /**  @private\n     */\n    setPlaneHighlighted(id, highlighted) {\n        const plane = this._planes[id];\n        if (plane) {\n            plane.setHighlighted(highlighted);\n        }\n    }\n\n    /**  @private\n     */\n    setPlaneSelected(id, selected) {\n        const plane = this._planes[id];\n        if (plane) {\n            plane.setSelected(selected);\n        }\n    }\n\n    /** @private\n     */\n    removeSectionPlane(sectionPlane) {\n        const plane = this._planes[sectionPlane.id];\n        if (plane) {\n            plane.destroy();\n            delete this._planes[sectionPlane.id];\n        }\n    }\n\n    /**\n     * Sets if this SectionPlanesOverview is visible.\n     *\n     * @param {Boolean} visible Whether or not this SectionPlanesOverview is visible.\n     */\n    setVisible(visible = true) {\n        this._visible = visible;\n        this._canvas.style.visibility = visible ? \"visible\" : \"hidden\";\n    }\n\n    /**\n     * Gets if this SectionPlanesOverview is visible.\n     *\n     * @return {Boolean} True when this SectionPlanesOverview is visible.\n     */\n    getVisible() {\n        return this._visible;\n    }\n\n    /**  @private\n     */\n    destroy() {\n        this._viewer.camera.off(this._onViewerCameraMatrix);\n        this._viewer.camera.off(this._onViewerCameraWorldAxis);\n        this._viewer.camera.perspective.off(this._onViewerCameraFOV);\n\n        this._scene.input.off(this._onInputMouseMove);\n        this._scene.canvas.canvas.removeEventListener(\"mouseup\", this._onCanvasMouseUp);\n        this._scene.canvas.canvas.removeEventListener(\"mouseout\", this._onCanvasMouseOut);\n        this._scene.destroy();\n    }\n}\n\nconst tempAABB$1 = math.AABB3();\nconst tempVec3$1 = math.vec3();\n\n/**\n * SectionPlanesPlugin is a {@link Viewer} plugin that manages {@link SectionPlane}s.\n *\n * [<img src=\"https://user-images.githubusercontent.com/83100/57724962-406e9a00-768c-11e9-9f1f-3d178a3ec11f.gif\">](https://xeokit.github.io/xeokit-sdk/examples/index.html#gizmos_SectionPlanesPlugin)\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#gizmos_SectionPlanesPlugin)]\n *\n * ## Overview\n *\n * * Use the SectionPlanesPlugin to\n * create and edit {@link SectionPlane}s to slice portions off your models and reveal internal structures.\n * * As shown in the screen capture above, SectionPlanesPlugin shows an overview of all your SectionPlanes (on the right, in\n * this example).\n * * Click a plane in the overview to activate a 3D control with which you can interactively\n * reposition its SectionPlane in the main canvas.\n * * Use {@lin BCFViewpointsPlugin} to save and load SectionPlanes in BCF viewpoints.\n *\n * ## Usage\n *\n * In the example below, we'll use a {@link GLTFLoaderPlugin} to load a model, and a SectionPlanesPlugin\n * to slice it open with two {@link SectionPlane}s. We'll show the overview in the bottom right of the Viewer\n * canvas. Finally, we'll programmatically activate the 3D editing control, so that we can use it to interactively\n * reposition our second SectionPlane.\n *\n * ````JavaScript\n * import {Viewer, GLTFLoaderPlugin, SectionPlanesPlugin} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer and arrange its Camera\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [-5.02, 2.22, 15.09];\n * viewer.camera.look = [4.97, 2.79, 9.89];\n * viewer.camera.up = [-0.05, 0.99, 0.02];\n *\n *\n * // Add a GLTFLoaderPlugin\n *\n * const gltfLoader = new GLTFLoaderPlugin(viewer);\n *\n * // Add a SectionPlanesPlugin, with overview visible\n *\n * const sectionPlanes = new SectionPlanesPlugin(viewer, {\n *     overviewCanvasID: \"myOverviewCanvas\",\n *     overviewVisible: true\n * });\n *\n * // Load a model\n *\n * const model = gltfLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/gltf/schependomlaan/scene.gltf\"\n * });\n *\n * // Create a couple of section planes\n * // These will be shown in the overview\n *\n * sectionPlanes.createSectionPlane({\n *     id: \"mySectionPlane\",\n *     pos: [1.04, 1.95, 9.74],\n *     dir: [1.0, 0.0, 0.0]\n * });\n *\n * sectionPlanes.createSectionPlane({\n *     id: \"mySectionPlane2\",\n *     pos: [2.30, 4.46, 14.93],\n *     dir: [0.0, -0.09, -0.79]\n * });\n *\n * // Show the SectionPlanePlugin's 3D editing gizmo,\n * // to interactively reposition one of our SectionPlanes\n *\n * sectionPlanes.showControl(\"mySectionPlane2\");\n *\n * const mySectionPlane2 = sectionPlanes.sectionPlanes[\"mySectionPlane2\"];\n *\n * // Programmatically reposition one of our SectionPlanes\n * // This also updates its position as shown in the overview gizmo\n *\n * mySectionPlane2.pos = [11.0, 6.0, -12];\n * mySectionPlane2.dir = [0.4, 0.0, 0.5];\n * ````\n */\nclass SectionPlanesPlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg Plugin configuration.\n     * @param {String} [cfg.id=\"SectionPlanes\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {String} [cfg.overviewCanvasId] ID of a canvas element to display the overview.\n     * @param {String} [cfg.overviewVisible=true] Initial visibility of the overview canvas.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"SectionPlanes\", viewer);\n\n        this._freeControls = [];\n        this._sectionPlanes = viewer.scene.sectionPlanes;\n        this._controls = {};\n        this._shownControlId = null;\n\n        if (cfg.overviewCanvasId !== null && cfg.overviewCanvasId !== undefined) {\n\n            const overviewCanvas = document.getElementById(cfg.overviewCanvasId);\n\n            if (!overviewCanvas) {\n                this.warn(\"Can't find overview canvas: '\" + cfg.overviewCanvasId + \"' - will create plugin without overview\");\n\n            } else {\n\n                this._overview = new Overview$1(this, {\n                    overviewCanvas: overviewCanvas,\n                    visible: cfg.overviewVisible,\n\n                    onHoverEnterPlane: ((id) => {\n                        this._overview.setPlaneHighlighted(id, true);\n                    }),\n\n                    onHoverLeavePlane: ((id) => {\n                        this._overview.setPlaneHighlighted(id, false);\n                    }),\n\n                    onClickedPlane: ((id) => {\n                        if (this.getShownControl() === id) {\n                            this.hideControl();\n                            return;\n                        }\n                        this.showControl(id);\n                        const sectionPlane = this.sectionPlanes[id];\n                        const sectionPlanePos = sectionPlane.pos;\n                        tempAABB$1.set(this.viewer.scene.aabb);\n                        math.getAABB3Center(tempAABB$1, tempVec3$1);\n                        tempAABB$1[0] += sectionPlanePos[0] - tempVec3$1[0];\n                        tempAABB$1[1] += sectionPlanePos[1] - tempVec3$1[1];\n                        tempAABB$1[2] += sectionPlanePos[2] - tempVec3$1[2];\n                        tempAABB$1[3] += sectionPlanePos[0] - tempVec3$1[0];\n                        tempAABB$1[4] += sectionPlanePos[1] - tempVec3$1[1];\n                        tempAABB$1[5] += sectionPlanePos[2] - tempVec3$1[2];\n                        this.viewer.cameraFlight.flyTo({\n                            aabb: tempAABB$1,\n                            fitFOV: 65\n                        });\n                    }),\n\n                    onClickedNothing: (() => {\n                        this.hideControl();\n                    })\n                });\n            }\n        }\n\n        this._onSceneSectionPlaneCreated = viewer.scene.on(\"sectionPlaneCreated\", (sectionPlane) => {\n\n            // SectionPlane created, either via SectionPlanesPlugin#createSectionPlane(), or by directly\n            // instantiating a SectionPlane independently of SectionPlanesPlugin, which can be done\n            // by BCFViewpointsPlugin#loadViewpoint().\n\n            this._sectionPlaneCreated(sectionPlane);\n        });\n    }\n\n    /**\n     * Sets if the overview canvas is visible.\n     *\n     * @param {Boolean} visible Whether or not the overview canvas is visible.\n     */\n    setOverviewVisible(visible) {\n        if (this._overview) {\n            this._overview.setVisible(visible);\n        }\n    }\n\n    /**\n     * Gets if the overview canvas is visible.\n     *\n     * @return {Boolean} True when the overview canvas is visible.\n     */\n    getOverviewVisible() {\n        if (this._overview) {\n            return this._overview.getVisible();\n        }\n    }\n\n    /**\n     * Returns a map of the {@link SectionPlane}s created by this SectionPlanesPlugin.\n     *\n     * @returns {{String:SectionPlane}} A map containing the {@link SectionPlane}s, each mapped to its {@link SectionPlane#id}.\n     */\n    get sectionPlanes() {\n        return this._sectionPlanes;\n    }\n\n    /**\n     * Creates a {@link SectionPlane}.\n     *\n     * The {@link SectionPlane} will be registered by {@link SectionPlane#id} in {@link SectionPlanesPlugin#sectionPlanes}.\n     *\n     * @param {Object} params {@link SectionPlane} configuration.\n     * @param {String} [params.id] Unique ID to assign to the {@link SectionPlane}. Must be unique among all components in the {@link Viewer}'s {@link Scene}. Auto-generated when omitted.\n     * @param {Number[]} [params.pos=[0,0,0]] World-space position of the {@link SectionPlane}.\n     * @param {Number[]} [params.dir=[0,0,-1]] World-space vector indicating the orientation of the {@link SectionPlane}.\n     * @param {Boolean} [params.active=true] Whether the {@link SectionPlane} is initially active. Only clips while this is true.\n     * @returns {SectionPlane} The new {@link SectionPlane}.\n     */\n    createSectionPlane(params = {}) {\n\n        if (params.id !== undefined && params.id !== null && this.viewer.scene.components[params.id]) {\n            this.error(\"Viewer component with this ID already exists: \" + params.id);\n            delete params.id;\n        }\n\n        // Note that SectionPlane constructor fires \"sectionPlaneCreated\" on the Scene,\n        // which SectionPlanesPlugin handles and calls #_sectionPlaneCreated to create gizmo and add to overview canvas.\n\n        const sectionPlane = new SectionPlane(this.viewer.scene, {\n            id: params.id,\n            pos: params.pos,\n            dir: params.dir,\n            active: true \n        });\n        return sectionPlane;\n    }\n\n    _sectionPlaneCreated(sectionPlane) {\n        const control = ((this._freeControls.length > 0)\n                         ? this._freeControls.pop()\n                         : (() => {\n                             const scene = this.viewer.scene;\n                             const planeRoot = (function() {\n                                 const rootNode = new Node$1(scene, { isObject: false });\n\n                                 rootNode.addChild(new Mesh(rootNode, { // plane\n                                     geometry: new ReadableGeometry(rootNode, {\n                                         primitive: \"triangles\",\n                                         positions: [\n                                             0.5, 0.5, 0.0, 0.5, -0.5, 0.0, // 0\n                                             -0.5, -0.5, 0.0, -0.5, 0.5, 0.0, // 1\n                                             0.5, 0.5, -0.0, 0.5, -0.5, -0.0, // 2\n                                             -0.5, -0.5, -0.0, -0.5, 0.5, -0.0 // 3\n                                         ],\n                                         indices: [0, 1, 2, 2, 3, 0]\n                                     }),\n                                     material: new PhongMaterial(rootNode, {\n                                         emissive: [0, 0.0, 0],\n                                         diffuse: [0, 0, 0],\n                                         backfaces: true\n                                     }),\n                                     opacity: 0.6,\n                                     ghosted: true,\n                                     ghostMaterial: new EmphasisMaterial(rootNode, {\n                                         edges: false,\n                                         filled: true,\n                                         fillColor: [1, 1, 0],\n                                         edgeColor: [0, 0, 0],\n                                         fillAlpha: 0.1,\n                                         backfaces: true\n                                     }),\n                                     pickable: false,\n                                     collidable: true,\n                                     clippable: false,\n                                     visible: false,\n                                     scale: [2.4, 2.4, 1],\n                                     isObject: false\n                                 }));\n\n                                 rootNode.addChild(new Mesh(rootNode, { // Visible frame\n                                     geometry: new ReadableGeometry(rootNode, buildTorusGeometry({\n                                         center: [0, 0, 0],\n                                         radius: 1.7,\n                                         tube: 0.02,\n                                         radialSegments: 4,\n                                         tubeSegments: 4,\n                                         arc: Math.PI * 2.0\n                                     })),\n                                     material: new PhongMaterial(rootNode, {\n                                         emissive: [0, 0, 0],\n                                         diffuse: [0, 0, 0],\n                                         specular: [0, 0, 0],\n                                         shininess: 0\n                                     }),\n                                     //highlighted: true,\n                                     highlightMaterial: new EmphasisMaterial(rootNode, {\n                                         edges: false,\n                                         edgeColor: [0.0, 0.0, 0.0],\n                                         filled: true,\n                                         fillColor: [0.8, 0.8, 0.8],\n                                         fillAlpha: 1.0\n                                     }),\n                                     pickable: false,\n                                     collidable: false,\n                                     clippable: false,\n                                     visible: false,\n                                     scale: [1, 1, .1],\n                                     rotation: [0, 0, 45],\n                                     isObject: false\n                                 }));\n\n                                 return {\n                                     setPosition: (function() {\n                                         const origin = math.vec3();\n                                         const rtcPos = math.vec3();\n                                         return function(p) {\n                                             worldToRTCPos(p, origin, rtcPos);\n                                             rootNode.origin = origin;\n                                             rootNode.position = rtcPos;\n                                         };\n                                     })(),\n                                     setQuaternion: q => { rootNode.quaternion = q; },\n                                     setScale: s => { rootNode.scale = s; },\n                                     setVisible: v => { rootNode.visible = v; },\n                                     destroy: () => { rootNode.destroy(); }\n                                 };\n                             })();\n                             let unbindSectionPlane = () => { };\n                             const ctrl = new TransformControl(this.viewer);\n\n                             let culled  = false;\n                             let visible = false;\n                             let handlers = null;\n                             const updateVisible = () => {\n                                 const vis = visible && (! culled);\n                                 planeRoot.setVisible(vis);\n                                 ctrl.setHandlers(vis && handlers);\n                             };\n\n                             return {\n                                 _destroy: () => {\n                                     unbindSectionPlane();\n                                     ctrl.destroy();\n                                     planeRoot.destroy();\n                                 },\n                                 setCulled:  c => { culled = c;  updateVisible(); },\n                                 setVisible: v => { visible = v; updateVisible(); },\n                                 _setSectionPlane: sectionPlane => {\n                                     unbindSectionPlane();\n                                     if (sectionPlane) {\n                                         let ignoreNextSectionPlaneDirUpdate = false;\n                                         handlers = {\n                                             onPosition:   p => {\n                                                 planeRoot.setPosition(p);\n                                                 sectionPlane.pos = p;\n                                             },\n                                             onQuaternion: q => {\n                                                 planeRoot.setQuaternion(q);\n                                                 ignoreNextSectionPlaneDirUpdate = true;\n                                                 sectionPlane.quaternion = q;\n                                             },\n                                             onScreenScale: s => {\n                                                 planeRoot.setScale(s);\n                                             }\n                                         };\n\n                                         const setPosFromSectionPlane = () => {\n                                             planeRoot.setPosition(sectionPlane.pos);\n                                             ctrl.setPosition(sectionPlane.pos);\n                                         };\n                                         const setDirFromSectionPlane = () => {\n                                             planeRoot.setQuaternion(sectionPlane.quaternion);\n                                             ctrl.setQuaternion(sectionPlane.quaternion);\n                                         };\n                                         setPosFromSectionPlane();\n                                         setDirFromSectionPlane();\n                                         const onSectionPlanePos = sectionPlane.on(\"pos\", setPosFromSectionPlane);\n                                         const onSectionPlaneDir = sectionPlane.on(\"dir\", () => {\n                                             if (!ignoreNextSectionPlaneDirUpdate) {\n                                                 setDirFromSectionPlane();\n                                             } else {\n                                                 ignoreNextSectionPlaneDirUpdate = false;\n                                             }\n                                         });\n\n                                         unbindSectionPlane = () => {\n                                             sectionPlane.off(onSectionPlanePos);\n                                             sectionPlane.off(onSectionPlaneDir);\n                                             unbindSectionPlane = () => { };\n                                         };\n                                     }\n                                 }\n                             };\n                         })());\n        control._setSectionPlane(sectionPlane);\n        control.setVisible(false);\n        this._controls[sectionPlane.id] = control;\n        if (this._overview) {\n            this._overview.addSectionPlane(sectionPlane);\n        }\n        sectionPlane.once(\"destroyed\", () => {\n            this._sectionPlaneDestroyed(sectionPlane);\n        });\n    }\n\n    /**\n     * Inverts the direction of {@link SectionPlane#dir} on every existing SectionPlane.\n     *\n     * Inverts all SectionPlanes, including those that were not created with SectionPlanesPlugin.\n     */\n    flipSectionPlanes() {\n        const sectionPlanes = this.viewer.scene.sectionPlanes;\n        for (let id in sectionPlanes) {\n            const sectionPlane = sectionPlanes[id];\n            sectionPlane.flipDir();\n        }\n    }\n\n    /**\n     * Shows the 3D editing gizmo for a {@link SectionPlane}.\n     *\n     * @param {String} id ID of the {@link SectionPlane}.\n     */\n    showControl(id) {\n        const control = this._controls[id];\n        if (!control) {\n            this.error(\"Control not found: \" + id);\n            return;\n        }\n        this.hideControl();\n        control.setVisible(true);\n        if (this._overview) {\n            this._overview.setPlaneSelected(id, true);\n        }\n        this._shownControlId = id;\n    }\n\n    /**\n     * Gets the ID of the {@link SectionPlane} that the 3D editing gizmo is shown for.\n     *\n     * Returns ````null```` when the editing gizmo is not shown.\n     *\n     * @returns {String} ID of the the {@link SectionPlane} that the 3D editing gizmo is shown for, if shown, else ````null````.\n     */\n    getShownControl() {\n        return this._shownControlId;\n    }\n\n    /**\n     * Hides the 3D {@link SectionPlane} editing gizmo if shown.\n     */\n    hideControl() {\n        for (var id in this._controls) {\n            if (this._controls.hasOwnProperty(id)) {\n                this._controls[id].setVisible(false);\n                if (this._overview) {\n                    this._overview.setPlaneSelected(id, false);\n                }\n            }\n        }\n        this._shownControlId = null;\n    }\n\n    /**\n     * Destroys a {@link SectionPlane} created by this SectionPlanesPlugin.\n     *\n     * @param {String} id ID of the {@link SectionPlane}.\n     */\n    destroySectionPlane(id) {\n        var sectionPlane = this.viewer.scene.sectionPlanes[id];\n        if (!sectionPlane) {\n            this.error(\"SectionPlane not found: \" + id);\n            return;\n        }\n        this._sectionPlaneDestroyed(sectionPlane);\n        sectionPlane.destroy();\n\n        if (id === this._shownControlId) {\n            this._shownControlId = null;\n        }\n    }\n\n    _sectionPlaneDestroyed(sectionPlane) {\n        if (this._overview) {\n            this._overview.removeSectionPlane(sectionPlane);\n        }\n        const control = this._controls[sectionPlane.id];\n        if (!control) {\n            return;\n        }\n        control.setVisible(false);\n        control._setSectionPlane(null);\n        delete this._controls[sectionPlane.id];\n        this._freeControls.push(control);\n    }\n\n    /**\n     * Destroys all {@link SectionPlane}s created by this SectionPlanesPlugin.\n     */\n    clear() {\n        const ids = Object.keys(this._sectionPlanes);\n        for (var i = 0, len = ids.length; i < len; i++) {\n            this.destroySectionPlane(ids[i]);\n        }\n    }\n\n    /**\n     * @private\n     */\n    send(name, value) {\n        switch (name) {\n\n            case \"snapshotStarting\": // Viewer#getSnapshot() about to take snapshot - hide controls\n                for (let id in this._controls) {\n                    if (this._controls.hasOwnProperty(id)) {\n                        this._controls[id].setCulled(true);\n                    }\n                }\n                break;\n\n            case \"snapshotFinished\": // Viewer#getSnapshot() finished taking snapshot - show controls again\n                for (let id in this._controls) {\n                    if (this._controls.hasOwnProperty(id)) {\n                        this._controls[id].setCulled(false);\n                    }\n                }\n                break;\n\n            case \"clearSectionPlanes\":\n                this.clear();\n                break;\n        }\n    }\n\n    /**\n     * Destroys this SectionPlanesPlugin.\n     *\n     * Also destroys each {@link SectionPlane} created by this SectionPlanesPlugin.\n     *\n     * Does not destroy the canvas the SectionPlanesPlugin was configured with.\n     */\n    destroy() {\n        this.clear();\n        if (this._overview) {\n            this._overview.destroy();\n        }\n        this._destroyFreeControls();\n        super.destroy();\n    }\n\n    _destroyFreeControls() {\n        var control = this._freeControls.pop();\n        while (control) {\n            control._destroy();\n            control = this._freeControls.pop();\n        }\n        this.viewer.scene.off(this._onSceneSectionPlaneCreated);\n    }\n}\n\n/**\n * @desc Information about an ````IfcBuildingStorey````.\n *\n * These are provided by a {@link StoreyViewsPlugin}.\n */\nclass Storey {\n\n    /**\n     * @private\n     */\n    constructor(plugin, modelAABB, storeyAABB, modelId, storeyId, numObjects) {\n\n        /**\n         * The {@link StoreyViewsPlugin} this Storey belongs to.\n         *\n         * @property plugin\n         * @type {StoreyViewsPlugin}\n         */\n        this.plugin = plugin;\n\n        /**\n         * ID of the IfcBuildingStorey.\n         *\n         * This matches IDs of the IfcBuildingStorey's {@link MetaObject} and {@link Entity}.\n         *\n         * @property storeyId\n         * @type {String}\n         */\n        this.storeyId = storeyId;\n\n        /**\n         * ID of the model.\n         *\n         * This matches the ID of the {@link MetaModel} that contains the IfcBuildingStorey's {@link MetaObject}.\n         *\n         * @property modelId\n         * @type {String|Number}\n         */\n        this.modelId = modelId;\n\n        /**\n         * Axis-aligned World-space boundary of the {@link Entity}s that represent the IfcBuildingStorey.\n         *\n         * The boundary is a six-element Float64Array containing the min/max extents of the\n         * axis-aligned boundary, ie. ````[xmin, ymin, zmin, xmax, ymax, zmax]````\n         *\n         * @property storeyAABB\n         * @type {Number[]}\n         */\n        this.storeyAABB = storeyAABB.slice();\n\n        /**\n         * Axis-aligned World-space boundary of the {@link Entity}s that represent the IfcBuildingStorey.\n         *\n         * The boundary is a six-element Float64Array containing the min/max extents of the\n         * axis-aligned boundary, ie. ````[xmin, ymin, zmin, xmax, ymax, zmax]````\n         *\n         * @deprecated\n         * @property storeyAABB\n         * @type {Number[]}\n         */\n        this.aabb = this.storeyAABB;\n\n        /**\n         * Axis-aligned World-space boundary of the {@link Entity}s that represent the model.\n         *\n         * The boundary is a six-element Float64Array containing the min/max extents of the\n         * axis-aligned boundary, ie. ````[xmin, ymin, zmin, xmax, ymax, zmax]````\n         *\n         * @property modelAABB\n         * @type {Number[]}\n         */\n        this.modelAABB = modelAABB.slice();\n\n        /** Number of {@link Entity}s within the IfcBuildingStorey.\n         *\n         * @property numObjects\n         * @type {Number}\n         */\n        this.numObjects = numObjects;\n    }\n}\n\n/**\n * @desc A 2D plan view image of an ````IfcBuildingStorey````.\n *\n * These are created by a {@link StoreyViewsPlugin}.\n */\nclass StoreyMap {\n\n    /**\n     * @private\n     */\n    constructor(storeyId, imageData, format, width, height, padding) {\n\n        /**\n         * ID of the IfcBuildingStorey.\n         *\n         * This matches IDs of the IfcBuildingStorey's {@link MetaObject} and {@link Entity}.\n         *\n         * @property storeyId\n         * @type {String}\n         */\n        this.storeyId = storeyId;\n\n        /**\n         * Base64-encoded plan view image.\n         *\n         * @property imageData\n         * @type {String}\n         */\n        this.imageData = imageData;\n\n        /**\n         * The image format - \"png\" or \"jpeg\".\n         *\n         * @property format\n         * @type {String}\n         */\n        this.format = format;\n\n        /**\n         * Width of the image, in pixels.\n         *\n         * @property width\n         * @type {Number}\n         */\n        this.width = width;\n\n        /**\n         * Height of the image, in pixels.\n         *\n         * @property height\n         * @type {Number}\n         */\n        this.height = height;\n    }\n}\n\nconst tempVec3a$2 = math.vec3();\nconst tempMat4 = math.mat4();\n\nconst EMPTY_IMAGE = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==\";\n\n\n/**\n * @desc A {@link Viewer} plugin that provides methods for visualizing IfcBuildingStoreys.\n *\n *  <a href=\"https://xeokit.github.io/xeokit-sdk/examples/navigation/#StoreyViewsPlugin_recipe3\"><img src=\"http://xeokit.io/img/docs/StoreyViewsPlugin/minimap.gif\"></a>\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/navigation/#StoreyViewsPlugin_recipe3)]\n *\n * ## Overview\n *\n * StoreyViewsPlugin provides a flexible set of methods for visualizing building storeys in 3D and 2D.\n *\n * Use the first two methods to set up 3D views of storeys:\n *\n * * [showStoreyObjects](#instance-method-showStoreyObjects) - shows the {@link Entity}s within a storey, and\n * * [gotoStoreyCamera](#instance-method-gotoStoreyCamera) - positions the {@link Camera} for a plan view of the Entitys within a storey.\n * <br> <br>\n *\n * Use the second two methods to create 2D plan view mini-map images:\n *\n * * [createStoreyMap](#instance-method-createStoreyMap) - creates a 2D plan view image of a storey, and\n * * [pickStoreyMap](#instance-method-pickStoreyMap) - picks the {@link Entity} at the given 2D pixel coordinates within a plan view image.\n *\n * ## Usage\n *\n * Let's start by creating a {@link Viewer} with a StoreyViewsPlugin and an {@link XKTLoaderPlugin}.\n *\n * Then we'll load a BIM building model from an  ```.xkt``` file.\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, StoreyViewsPlugin} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer, arrange the camera\n *\n * const viewer = new Viewer({\n *        canvasId: \"myCanvas\",\n *        transparent: true\n *    });\n *\n * viewer.camera.eye = [-2.56, 8.38, 8.27];\n * viewer.camera.look = [13.44, 3.31, -14.83];\n * viewer.camera.up = [0.10, 0.98, -0.14];\n *\n * // Add an XKTLoaderPlugin\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * // Add a StoreyViewsPlugin\n *\n * const storeyViewsPlugin = new StoreyViewsPlugin(viewer);\n *\n * // Load a BIM model from .xkt format\n *\n * const model = xktLoader.load({\n *      id: \"myModel\",\n *      src: \"./models/xkt/Schependomlaan.xkt\",\n *      edges: true\n * });\n * ````\n *\n * ## Finding Storeys\n *\n * Getting information on a storey in our model:\n *\n * ````javascript\n * const storey = storeyViewsPlugin.storeys[\"2SWZMQPyD9pfT9q87pgXa1\"]; // ID of the IfcBuildingStorey\n *\n * const modelId  = storey.modelId;  // \"myModel\"\n * const storeyId = storey.storeyId; // \"2SWZMQPyD9pfT9q87pgXa1\"\n * const aabb     = storey.aabb;     // Axis-aligned 3D World-space boundary of the IfcBuildingStorey\n * ````\n *\n * We can also get a \"storeys\" event every time the set of storeys changes, ie. every time a storey is created or destroyed:\n *\n * ````javascript\n * storeyViewsPlugin.on(\"storeys\", ()=> {\n *      const storey = storeyViewsPlugin.storeys[\"2SWZMQPyD9pfT9q87pgXa1\"];\n *      //...\n * });\n * ````\n *\n * ## Showing Entitys within Storeys\n *\n * Showing the {@link Entity}s within a storey:\n *\n * ````javascript\n * storeyViewsPlugin.showStoreyObjects(\"2SWZMQPyD9pfT9q87pgXa1\");\n * ````\n *\n * Showing **only** the Entitys in a storey, hiding all others:\n *\n * ````javascript\n * storeyViewsPlugin.showStoreyObjects(\"2SWZMQPyD9pfT9q87pgXa1\", {\n *     hideOthers: true\n * });\n * ````\n * Showing only the storey Entitys:\n *\n * ````javascript\n * storeyViewsPlugin.showStoreyObjects(\"2SWZMQPyD9pfT9q87pgXa1\", {\n *     hideOthers: true\n * });\n * ````\n *\n * When using this option, at some point later you'll probably want to restore all Entitys to their original visibilities and\n * appearances.\n *\n * To do that, save their visibility and appearance states in an {@link ObjectsMemento} beforehand, from\n * which you can restore them later:\n *\n * ````javascript\n * const objectsMemento = new ObjectsMemento();\n *\n * // Save all Entity visibility and appearance states\n *\n * objectsMemento.saveObjects(viewer.scene);\n *\n * // Show storey view Entitys\n *\n * storeyViewsPlugin.showStoreyObjects(\"2SWZMQPyD9pfT9q87pgXa1\");\n *\n * //...\n *\n * // Later, restore all Entitys to their saved visibility and appearance states\n * objectsMemento.restoreObjects(viewer.scene);\n * ````\n *\n * ## Arranging the Camera for Storey Plan Views\n *\n * The {@link StoreyViewsPlugin#gotoStoreyCamera} method positions the {@link Camera} for a plan view of\n * the {@link Entity}s within the given storey.\n *\n * Let's fly the {@link Camera} to a downward-looking orthographic view of the Entitys within our storey.\n *\n * ````javascript\n * storeyViewsPlugin.gotoStoreyCamera(\"2SWZMQPyD9pfT9q87pgXa1\", {\n *     projection: \"ortho\", // Orthographic projection\n *     duration: 2.5,       // 2.5 second transition\n *     done: () => {\n *         viewer.cameraControl.planView = true; // Disable rotation\n *     }\n * });\n * ````\n *\n * Note that we also set {@link CameraControl#planView} ````true````, which prevents the CameraControl from rotating\n * or orbiting. In orthographic mode, this effectively makes the {@link Viewer} behave as if it were a 2D viewer, with\n * picking, panning and zooming still enabled.\n *\n * If you need to be able to restore the Camera to its previous state, you can save it to a {@link CameraMemento}\n * beforehand, from which you can restore it later:\n *\n * ````javascript\n * const cameraMemento = new CameraMemento();\n *\n * // Save camera state\n *\n * cameraMemento.saveCamera(viewer.scene);\n *\n * // Position camera for a downward-looking orthographic view of our storey\n *\n * storeyViewsPlugin.gotoStoreyCamera(\"2SWZMQPyD9pfT9q87pgXa1\", {\n *     projection: \"ortho\",\n *     duration: 2.5,\n *     done: () => {\n *         viewer.cameraControl.planView = true; // Disable rotation\n *     }\n * });\n *\n * //...\n *\n * // Later, restore the Camera to its saved state\n * cameraMemento.restoreCamera(viewer.scene);\n * ````\n *\n * ## Creating StoreyMaps\n *\n * The {@link StoreyViewsPlugin#createStoreyMap} method creates a 2D orthographic plan image of the given storey.\n *\n * This method creates a {@link StoreyMap}, which provides the plan image as a Base64-encoded string.\n *\n * Let's create a 2D plan image of our building storey:\n *\n * ````javascript\n * const storeyMap = storeyViewsPlugin.createStoreyMap(\"2SWZMQPyD9pfT9q87pgXa1\", {\n *     width: 300,\n *     format: \"png\"\n * });\n *\n * const imageData = storeyMap.imageData; // Base64-encoded image data string\n * const width     = storeyMap.width; // 300\n * const height    = storeyMap.height; // Automatically derived from width\n * const format    = storeyMap.format; // \"png\"\n * ````\n *\n * We can also specify a ````height```` for the plan image, as an alternative to ````width````:\n *\n *  ````javascript\n *  const storeyMap = storeyViewsPlugin.createStoreyMap(\"2SWZMQPyD9pfT9q87pgXa1\", {\n *      height: 200,\n *      format: \"png\"\n * });\n * ````\n *\n * ## Picking Entities in StoreyMaps\n *\n * We can use {@link StoreyViewsPlugin#pickStoreyMap} to pick Entities in our building storey, using 2D coordinates from mouse or touch events on our {@link StoreyMap}'s 2D plan image.\n *\n * Let's programmatically pick the Entity at the given 2D pixel coordinates within our image:\n *\n * ````javascript\n * const mouseCoords = [65, 120]; // Mouse coords within the image extents\n *\n * const pickResult = storeyViewsPlugin.pickStoreyMap(storeyMap, mouseCoords);\n *\n * if (pickResult && pickResult.entity) {\n *     pickResult.entity.highlighted = true;\n * }\n * ````\n */\nclass StoreyViewsPlugin extends Plugin {\n\n    /**\n     * @constructor\n     *\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"StoreyViews\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {Boolean} [cfg.fitStoreyMaps=false] If enabled, the elements of each floor map image will be proportionally resized to encompass the entire image. This leads to varying scales among different floor map images. If disabled, each floor map image will display the model's extents, ensuring a consistent scale across all images.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"StoreyViews\", viewer);\n\n        this._objectsMemento = new ObjectsMemento();\n        this._cameraMemento = new CameraMemento();\n\n        /**\n         * A {@link Storey} for each ````IfcBuildingStorey```.\n         *\n         * There will be a {@link Storey} for every existing {@link MetaObject} whose {@link MetaObject#type} equals \"IfcBuildingStorey\".\n         *\n         * These are created and destroyed automatically as models are loaded and destroyed.\n         *\n         * @type {{String:Storey}}\n         */\n        this.storeys = {};\n\n        this._storeysList = null;\n\n        /**\n         * A set of {@link Storey}s for each {@link MetaModel}.\n         *\n         * These are created and destroyed automatically as models are loaded and destroyed.\n         *\n         * @type {{String: {String:Storey}}}\n         */\n        this.modelStoreys = {};\n\n        this._fitStoreyMaps = (!!cfg.fitStoreyMaps);\n\n        this._onModelLoaded = this.viewer.scene.on(\"modelLoaded\", (modelId) => {\n            this._registerModelStoreys(modelId);\n            this.fire(\"storeys\", this.storeys);\n        });\n    }\n\n    _registerModelStoreys(modelId) {\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const metaScene = viewer.metaScene;\n        const metaModel = metaScene.metaModels[modelId];\n        const model = scene.models[modelId];\n        if (!metaModel || !metaModel.rootMetaObjects) {\n            return;\n        }\n        const rootMetaObjects = metaModel.rootMetaObjects;\n        for (let j = 0, lenj = rootMetaObjects.length; j < lenj; j++) {\n            const storeyIds = rootMetaObjects[j].getObjectIDsInSubtreeByType([\"IfcBuildingStorey\"]);\n            for (let i = 0, len = storeyIds.length; i < len; i++) {\n                const storeyId = storeyIds[i];\n                const metaObject = metaScene.metaObjects[storeyId];\n                const childObjectIds = metaObject.getObjectIDsInSubtree();\n                const storeyAABB = scene.getAABB(childObjectIds);\n                const numObjects = (Math.random() > 0.5) ? childObjectIds.length : 0;\n                const storey = new Storey(this, model.aabb, storeyAABB, modelId, storeyId, numObjects);\n                storey._onModelDestroyed = model.once(\"destroyed\", () => {\n                    this._deregisterModelStoreys(modelId);\n                    this.fire(\"storeys\", this.storeys);\n                });\n                this.storeys[storeyId] = storey;\n                this._storeysList = null;\n                if (!this.modelStoreys[modelId]) {\n                    this.modelStoreys[modelId] = {};\n                }\n                this.modelStoreys[modelId][storeyId] = storey;\n            }\n        }\n        this._clipBoundingBoxes();\n    }\n\n    _clipBoundingBoxes() {\n        const storeysList = this.storeysList;\n        const metaScene = this.viewer.metaScene;\n        const camera = this.viewer.camera;\n        const worldUp = camera.worldUp;\n        const xUp = worldUp[0] > worldUp[1] && worldUp[0] > worldUp[2];\n        const yUp = !xUp && worldUp[1] > worldUp[0] && worldUp[1] > worldUp[2];\n        !xUp && !yUp && worldUp[2] > worldUp[0] && worldUp[2] > worldUp[1];\n\n        let bbIndex;\n\n        if(xUp) bbIndex = 0;\n        else if(yUp) bbIndex = 1;\n        else bbIndex = 2;\n        \n        for (let i = 0, len = storeysList.length; i < len; i++) {\n\n            const storeyMetaObjectCur = metaScene.metaObjects[storeysList[i].storeyId];\n            const elevationCur = storeyMetaObjectCur.attributes.elevation;\n\n            if(isNaN(elevationCur)) return;\n\n            const bb = storeysList[i].storeyAABB;\n            bb[bbIndex] = Math.max(bb[1], parseFloat(elevationCur));\n\n            if (i > 0) {\n                const storeyMetaObjectNext = metaScene.metaObjects[storeysList[i - 1].storeyId];\n                const elevationNext = storeyMetaObjectNext.attributes.elevation;\n                bb[4] = Math.min(bb[bbIndex + 3], parseFloat(elevationNext));\n            }\n\n            this.storeys[storeysList[i].storeyId].storeyAABB = bb;\n        }\n\n    }\n\n    _deregisterModelStoreys(modelId) {\n        const storeys = this.modelStoreys[modelId];\n        if (storeys) {\n            const scene = this.viewer.scene;\n            for (let storyObjectId in storeys) {\n                if (storeys.hasOwnProperty(storyObjectId)) {\n                    const storey = storeys[storyObjectId];\n                    const model = scene.models[storey.modelId];\n                    if (model) {\n                        model.off(storey._onModelDestroyed);\n                    }\n                    delete this.storeys[storyObjectId];\n                    this._storeysList = null;\n                }\n            }\n            delete this.modelStoreys[modelId];\n        }\n    }\n\n    /**\n     * When true, the elements of each floor map image will be proportionally resized to encompass the entire image. This leads to varying scales among different\n     * floor map images. If false, each floor map image will display the model's extents, ensuring a consistent scale across all images.\n     * @returns {*|boolean}\n     */\n    get fitStoreyMaps() {\n        return this._fitStoreyMaps;\n    }\n\n    /**\n     * Arranges the {@link Camera} for a 3D orthographic view of the {@link Entity}s within the given storey.\n     *\n     * See also: {@link CameraMemento}, which saves and restores the state of the {@link Scene}'s {@link Camera}\n     *\n     * @param {String} storeyId ID of the ````IfcBuildingStorey```` object.\n     * @param {*} [options] Options for arranging the Camera.\n     * @param {String} [options.projection] Projection type to transition the Camera to. Accepted values are \"perspective\" and \"ortho\".\n     * @param {Function} [options.done] Callback to fire when the Camera has arrived. When provided, causes an animated flight to the saved state. Otherwise jumps to the saved state.\n     */\n    gotoStoreyCamera(storeyId, options = {}) {\n\n        const storey = this.storeys[storeyId];\n\n        if (!storey) {\n            this.error(\"IfcBuildingStorey not found with this ID: \" + storeyId);\n            if (options.done) {\n                options.done();\n            }\n            return;\n        }\n\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const camera = scene.camera;\n        const storeyAABB = storey.storeyAABB;\n\n        if (storeyAABB[3] < storeyAABB[0] || storeyAABB[4] < storeyAABB[1] || storeyAABB[5] < storeyAABB[2]) { // Don't fly to an inverted boundary\n            if (options.done) {\n                options.done();\n            }\n            return;\n        }\n        if (storeyAABB[3] === storeyAABB[0] && storeyAABB[4] === storeyAABB[1] && storeyAABB[5] === storeyAABB[2]) { // Don't fly to an empty boundary\n            if (options.done) {\n                options.done();\n            }\n            return;\n        }\n        const look2 = math.getAABB3Center(storeyAABB);\n        const diag = math.getAABB3Diag(storeyAABB);\n        const fitFOV = 45; // fitFOV;\n        const sca = Math.abs(diag / Math.tan(fitFOV * math.DEGTORAD));\n\n        const orthoScale2 = diag * 1.3;\n\n        const eye2 = tempVec3a$2;\n\n        eye2[0] = look2[0] + (camera.worldUp[0] * sca);\n        eye2[1] = look2[1] + (camera.worldUp[1] * sca);\n        eye2[2] = look2[2] + (camera.worldUp[2] * sca);\n\n        const up2 = camera.worldForward;\n\n        if (options.done) {\n\n            viewer.cameraFlight.flyTo(utils.apply(options, {\n                eye: eye2,\n                look: look2,\n                up: up2,\n                orthoScale: orthoScale2\n            }), () => {\n                options.done();\n            });\n\n        } else {\n\n            viewer.cameraFlight.jumpTo(utils.apply(options, {\n                eye: eye2,\n                look: look2,\n                up: up2,\n                orthoScale: orthoScale2\n            }));\n\n            viewer.camera.ortho.scale = orthoScale2;\n        }\n    }\n\n    /**\n     * Shows the {@link Entity}s within the given storey.\n     *\n     * Optionally hides all other Entitys.\n     *\n     * See also: {@link ObjectsMemento}, which saves and restores a memento of the visual state\n     * of the {@link Entity}'s that represent objects within a {@link Scene}.\n     *\n     * @param {String} storeyId ID of the ````IfcBuildingStorey```` object.\n     * @param {*} [options] Options for showing the Entitys within the storey.\n     * @param {Boolean} [options.hideOthers=false] When ````true````, hide all other {@link Entity}s.\n     */\n    showStoreyObjects(storeyId, options = {}) {\n\n        const storey = this.storeys[storeyId];\n\n        if (!storey) {\n            this.error(\"IfcBuildingStorey not found with this ID: \" + storeyId);\n            return;\n        }\n\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const metaScene = viewer.metaScene;\n        const storeyMetaObject = metaScene.metaObjects[storeyId];\n\n        if (!storeyMetaObject) {\n            return;\n        }\n\n        if (options.hideOthers) {\n            scene.setObjectsVisible(viewer.scene.visibleObjectIds, false);\n        }\n\n        this.withStoreyObjects(storeyId, (entity, metaObject) => {\n            if (entity) {\n                entity.visible = true;\n            }\n        });\n    }\n\n    /**\n     * Executes a callback on each of the objects within the given storey.\n     *\n     * ## Usage\n     *\n     * In the example below, we'll show all the {@link Entity}s, within the given ````IfcBuildingStorey````,\n     * that have {@link MetaObject}s with type ````IfcSpace````. Note that the callback will only be given\n     * an {@link Entity} when one exists for the given {@link MetaObject}.\n     *\n     * ````JavaScript\n     * myStoreyViewsPlugin.withStoreyObjects(storeyId, (entity, metaObject) => {\n     *      if (entity && metaObject && metaObject.type === \"IfcSpace\") {\n     *          entity.visible = true;\n     *      }\n     * });\n     * ````\n     *\n     * @param {String} storeyId ID of the ````IfcBuildingStorey```` object.\n     * @param {Function} callback The callback.\n     */\n    withStoreyObjects(storeyId, callback) {\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const metaScene = viewer.metaScene;\n        const rootMetaObject = metaScene.metaObjects[storeyId];\n        if (!rootMetaObject) {\n            return;\n        }\n        const storeySubObjects = rootMetaObject.getObjectIDsInSubtree();\n        for (var i = 0, len = storeySubObjects.length; i < len; i++) {\n            const objectId = storeySubObjects[i];\n            const metaObject = metaScene.metaObjects[objectId];\n            const entity = scene.objects[objectId];\n            if (entity) {\n                callback(entity, metaObject);\n            }\n        }\n    }\n\n    /**\n     * Creates a 2D map of the given storey.\n     *\n     * @param {String} storeyId ID of the ````IfcBuildingStorey```` object.\n     * @param {*} [options] Options for creating the image.\n     * @param {Number} [options.width=300] Image width in pixels. Height will be automatically determined from this, if not given.\n     * @param {Number} [options.height=300] Image height in pixels, as an alternative to width. Width will be automatically determined from this, if not given.\n     * @param {String} [options.format=\"png\"] Image format. Accepted values are \"png\" and \"jpeg\".\n     * @param {Boolean} [options.captureSectionPlanes=false] Whether the storey map is sliced or not.\n     * @returns {StoreyMap} The StoreyMap.\n     */\n    createStoreyMap(storeyId, options = {}) {\n\n        const storey = this.storeys[storeyId];\n        if (!storey) {\n            this.error(\"IfcBuildingStorey not found with this ID: \" + storeyId);\n            return EMPTY_IMAGE;\n        }\n\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const format = options.format || \"png\";\n        const aabb = (this._fitStoreyMaps) ? storey.storeyAABB : storey.modelAABB;\n        const aspect = Math.abs((aabb[5] - aabb[2]) / (aabb[3] - aabb[0]));\n        const padding = options.padding || 0;\n        const captureSectionPlanes = !!options.captureSectionPlanes;\n\n        let width;\n        let height;\n\n        if (options.width && options.height) {\n            width = options.width;\n            height = options.height;\n\n        } else if (options.height) {\n            height = options.height;\n            width = Math.round(height / aspect);\n\n        } else if (options.width) {\n            width = options.width;\n            height = Math.round(width * aspect);\n\n        } else {\n            width = 300;\n            height = Math.round(width * aspect);\n        }\n\n        const mask = {\n            visible: true,\n        };\n\n        this._objectsMemento.saveObjects(scene, mask);\n        this._cameraMemento.saveCamera(scene);\n\n        this.showStoreyObjects(storeyId, utils.apply(options, {\n            hideOthers: true\n        }));\n        \n        if (captureSectionPlanes)\n            this._toggleSectionPlanes(false);\n\n        this._arrangeStoreyMapCamera(storey);\n\n        const src = viewer.getSnapshot({\n            width: width,\n            height: height,\n            format: format,\n        });\n\n        this._objectsMemento.restoreObjects(scene, mask);\n        this._cameraMemento.restoreCamera(scene);\n        if (captureSectionPlanes)\n            this._toggleSectionPlanes(true);\n\n        return new StoreyMap(storeyId, src, format, width, height, padding);\n    }\n\n    _toggleSectionPlanes(visible) {\n        const planes = this.viewer.scene.sectionPlanes;\n        for (const key in planes) {\n            planes[key].active = visible;\n        }\n    }\n\n    _arrangeStoreyMapCamera(storey) {\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const camera = scene.camera;\n        const aabb = (this._fitStoreyMaps) ? storey.storeyAABB : storey.modelAABB;\n        const look = math.getAABB3Center(aabb);\n        const sca = 0.5;\n        const eye = tempVec3a$2;\n        eye[0] = look[0] + (camera.worldUp[0] * sca);\n        eye[1] = look[1] + (camera.worldUp[1] * sca);\n        eye[2] = look[2] + (camera.worldUp[2] * sca);\n        const up = camera.worldForward;\n        viewer.cameraFlight.jumpTo({eye: eye, look: look, up: up});\n        const xHalfSize = (aabb[3] - aabb[0]) / 2;\n        const yHalfSize = (aabb[4] - aabb[1]) / 2;\n        const zHalfSize = (aabb[5] - aabb[2]) / 2;\n        const xmin = -xHalfSize;\n        const xmax = +xHalfSize;\n        const ymin = -yHalfSize;\n        const ymax = +yHalfSize;\n        const zmin = -zHalfSize;\n        const zmax = +zHalfSize;\n        viewer.camera.customProjection.matrix = math.orthoMat4c(xmin, xmax, zmin, zmax, ymin, ymax, tempMat4);\n        viewer.camera.projection = \"customProjection\";\n    }\n\n    /**\n     * Attempts to pick an {@link Entity} at the given pixel coordinates within a StoreyMap image.\n     *\n     * @param {StoreyMap} storeyMap The StoreyMap.\n     * @param {Number[]} imagePos 2D pixel coordinates within the bounds of {@link StoreyMap#imageData}.\n     * @param {*} [options] Picking options.\n     * @param {Boolean} [options.pickSurface=false] Whether to return the picked position on the surface of the Entity.\n     * @returns {PickResult} The pick result, if an Entity was successfully picked, else null.\n     */\n    pickStoreyMap(storeyMap, imagePos, options = {}) {\n\n        const storeyId = storeyMap.storeyId;\n        const storey = this.storeys[storeyId];\n\n        if (!storey) {\n            this.error(\"IfcBuildingStorey not found with this ID: \" + storeyId);\n            return null\n        }\n\n        const normX = 1.0 - (imagePos[0] / storeyMap.width);\n        const normZ = 1.0 - (imagePos[1] / storeyMap.height);\n\n        const aabb = (this._fitStoreyMaps) ? storey.storeyAABB : storey.modelAABB;\n\n        const xmin = aabb[0];\n        const ymin = aabb[1];\n        const zmin = aabb[2];\n        const xmax = aabb[3];\n        const ymax = aabb[4];\n        const zmax = aabb[5];\n\n        const xWorldSize = xmax - xmin;\n        const yWorldSize = ymax - ymin;\n        const zWorldSize = zmax - zmin;\n\n        const origin = math.vec3([xmin + (xWorldSize * normX), ymin + (yWorldSize * 0.5), zmin + (zWorldSize * normZ)]);\n        const direction = math.vec3([0, -1, 0]);\n        const look = math.addVec3(origin, direction, tempVec3a$2);\n        const worldForward = this.viewer.camera.worldForward;\n        const matrix = math.lookAtMat4v(origin, look, worldForward, tempMat4);\n\n        const pickResult = this.viewer.scene.pick({  // Picking with arbitrarily-positioned ray\n            pickSurface: options.pickSurface,\n            pickInvisible: true,\n            matrix\n        });\n\n        return pickResult;\n    }\n\n    storeyMapToWorldPos(storeyMap, imagePos, options = {}) {\n\n        const storeyId = storeyMap.storeyId;\n        const storey = this.storeys[storeyId];\n\n        if (!storey) {\n            this.error(\"IfcBuildingStorey not found with this ID: \" + storeyId);\n            return null\n        }\n\n        const normX = 1.0 - (imagePos[0] / storeyMap.width);\n        const normZ = 1.0 - (imagePos[1] / storeyMap.height);\n\n        const aabb = (this._fitStoreyMaps) ? storey.storeyAABB : storey.modelAABB;\n\n        const xmin = aabb[0];\n        const ymin = aabb[1];\n        const zmin = aabb[2];\n        const xmax = aabb[3];\n        const ymax = aabb[4];\n        const zmax = aabb[5];\n\n        const xWorldSize = xmax - xmin;\n        const yWorldSize = ymax - ymin;\n        const zWorldSize = zmax - zmin;\n\n        const origin = math.vec3([xmin + (xWorldSize * normX), ymin + (yWorldSize * 0.5), zmin + (zWorldSize * normZ)]);\n\n        return origin;\n    }\n\n\n    /**\n     * Gets the ID of the storey that contains the given 3D World-space position.\n     *.\n     * @param {Number[]} worldPos 3D World-space position.\n     * @returns {String} ID of the storey containing the position, or null if the position falls outside all the storeys.\n     */\n    getStoreyContainingWorldPos(worldPos, modelId = null) {\n        const storeys = modelId ? this._filterStoreys(modelId) : this.storeys;\n        for (let storeyId in storeys) {\n            const storey = storeys[storeyId];\n            if (math.point3AABB3AbsoluteIntersect(storey.storeyAABB, worldPos)) {\n                return storeyId;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * Gets the ID of the storey which's bounding box contains the y point of the world position\n     *\n     * @param {Number[]} worldPos 3D World-space position.\n     * @returns {String} ID of the storey containing the position, or null if the position falls outside all the storeys.\n     */\n    getStoreyInVerticalRange(worldPos, modelId = null) {\n        const storeys = modelId ? this._filterStoreys(modelId) : this.storeys;\n        for (let storeyId in storeys) {\n            const storey = storeys[storeyId];\n            const aabb = [0, 0, 0, 0, 0, 0], pos = [0, 0, 0];\n            aabb[1] = storey.storeyAABB[1];\n            aabb[4] = storey.storeyAABB[4];\n            pos[1] = worldPos[1];\n            if (math.point3AABB3AbsoluteIntersect(aabb, pos)) {\n                return storeyId;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * Returns whether a position is above or below a building\n     *\n     * @param {Number[]} worldPos 3D World-space position.\n     * @returns {String} ID of the lowest/highest story or null.\n     */\n    isPositionAboveOrBelowBuilding(worldPos, modelId = null) {\n        const storeys = modelId ? this._filterStoreys(modelId) : this.storeys;\n        const keys = Object.keys(storeys);\n        if(keys.length <= 0) return null;\n        const ids = [keys[0], keys[keys.length - 1]];\n        if (worldPos[1] < storeys[ids[0]].storeyAABB[1])\n            return ids[0];\n        else if (worldPos[1] > storeys[ids[1]].storeyAABB[4])\n            return ids[1];\n        return null;\n    }\n\n    /**\n     * Converts a 3D World-space position to a 2D position within a StoreyMap image.\n     *\n     * Use {@link StoreyViewsPlugin#pickStoreyMap} to convert 2D image positions to 3D world-space.\n     *\n     * @param {StoreyMap} storeyMap The StoreyMap.\n     * @param {Number[]} worldPos 3D World-space position within the storey.\n     * @param {Number[]} imagePos 2D pixel position within the {@link StoreyMap#imageData}.\n     * @returns {Boolean} True if ````imagePos```` is within the bounds of the {@link StoreyMap#imageData}, else ````false```` if it falls outside.\n     */\n    worldPosToStoreyMap(storeyMap, worldPos, imagePos) {\n\n        const storeyId = storeyMap.storeyId;\n        const storey = this.storeys[storeyId];\n\n        if (!storey) {\n            this.error(\"IfcBuildingStorey not found with this ID: \" + storeyId);\n            return false\n        }\n\n        const aabb = (this._fitStoreyMaps) ? storey.storeyAABB : storey.modelAABB;\n\n        const xmin = aabb[0];\n        const ymin = aabb[1];\n        const zmin = aabb[2];\n\n        const xmax = aabb[3];\n        const ymax = aabb[4];\n        const zmax = aabb[5];\n\n        const xWorldSize = xmax - xmin;\n        const yWorldSize = ymax - ymin;\n        const zWorldSize = zmax - zmin;\n\n        const camera = this.viewer.camera;\n        const worldUp = camera.worldUp;\n\n        const xUp = worldUp[0] > worldUp[1] && worldUp[0] > worldUp[2];\n        const yUp = !xUp && worldUp[1] > worldUp[0] && worldUp[1] > worldUp[2];\n        !xUp && !yUp && worldUp[2] > worldUp[0] && worldUp[2] > worldUp[1];\n\n        const ratioX = (storeyMap.width / xWorldSize);\n        const ratioY = yUp ? (storeyMap.height / zWorldSize) : (storeyMap.height / yWorldSize); // Assuming either Y or Z is \"up\", but never X\n\n        imagePos[0] = Math.floor(storeyMap.width - ((worldPos[0] - xmin) * ratioX));\n        imagePos[1] = Math.floor(storeyMap.height - ((worldPos[2] - zmin) * ratioY));\n\n        return (imagePos[0] >= 0 && imagePos[0] < storeyMap.width && imagePos[1] >= 0 && imagePos[1] <= storeyMap.height);\n    }\n\n    /**\n     * Converts a 3D World-space direction vector to a 2D vector within a StoreyMap image.\n     *\n     * @param {StoreyMap} storeyMap The StoreyMap.\n     * @param {Number[]} worldDir 3D World-space direction vector.\n     * @param {Number[]} imageDir Normalized 2D direction vector.\n     */\n    worldDirToStoreyMap(storeyMap, worldDir, imageDir) {\n        const camera = this.viewer.camera;\n        const eye = camera.eye;\n        const look = camera.look;\n        const eyeLookDir = math.subVec3(look, eye, tempVec3a$2);\n        const worldUp = camera.worldUp;\n        const xUp = worldUp[0] > worldUp[1] && worldUp[0] > worldUp[2];\n        const yUp = !xUp && worldUp[1] > worldUp[0] && worldUp[1] > worldUp[2];\n        !xUp && !yUp && worldUp[2] > worldUp[0] && worldUp[2] > worldUp[1];\n        if (xUp) {\n            imageDir[0] = eyeLookDir[1];\n            imageDir[1] = eyeLookDir[2];\n        } else if (yUp) {\n            imageDir[0] = eyeLookDir[0];\n            imageDir[1] = eyeLookDir[2];\n        } else {\n            imageDir[0] = eyeLookDir[0];\n            imageDir[1] = eyeLookDir[1];\n        }\n        math.normalizeVec2(imageDir);\n    }\n\n    /**\n     * Destroys this StoreyViewsPlugin.\n     */\n    destroy() {\n        this.viewer.scene.off(this._onModelLoaded);\n        super.destroy();\n    }\n\n    /**\n     * Gets Storeys in a list, spatially sorted on the vertical World axis, the lowest Storey first.\n     *\n     * @returns {null}\n     */\n    get storeysList() {\n        if (!this._storeysList) {\n            this._storeysList = Object.values(this.storeys);\n            this._storeysList.sort(this._getSpatialSortFunc());\n        }\n        return this._storeysList;\n    }\n\n    _getSpatialSortFunc() {\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const camera = scene.camera;\n        return this._spatialSortFunc || (this._spatialSortFunc = (storey1, storey2) => {\n            let idx = 0;\n            if (camera.xUp) {\n                idx = 0;\n            } else if (camera.yUp) {\n                idx = 1;\n            } else {\n                idx = 2;\n            }\n            const metaScene = this.viewer.metaScene;\n            const storey1MetaObject = metaScene.metaObjects[storey1.storeyId];\n            const storey2MetaObject = metaScene.metaObjects[storey2.storeyId];\n\n            if (storey1MetaObject && (storey1MetaObject.attributes && storey1MetaObject.attributes.elevation !== undefined) &&\n                storey2MetaObject && (storey2MetaObject.attributes && storey2MetaObject.attributes.elevation !== undefined)) {\n                const elevation1 = Number.parseFloat(storey1MetaObject.attributes.elevation);\n                const elevation2 = Number.parseFloat(storey2MetaObject.attributes.elevation);\n                if (elevation1 > elevation2) {\n                    return -1;\n                }\n                if (elevation1 < elevation2) {\n                    return 1;\n                }\n                return 0;\n            } else {\n                if (storey1.aabb[idx] > storey2.aabb[idx]) {\n                    return -1;\n                }\n                if (storey1.aabb[idx] < storey2.aabb[idx]) {\n                    return 1;\n                }\n                return 0;\n            }\n        });\n    }\n\n    _filterStoreys(modelId) {\n        return Object.fromEntries(\n            Object.entries(this.storeys).filter(([_, value]) => value.modelId === modelId)\n        );\n    }\n}\n\nconst zeroVec = new Float64Array([0, 0, 1]);\nconst quat = new Float64Array(4);\n\n/**\n * Controls a {@link SectionPlane} with mouse and touch input.\n */\nclass FaceAlignedSectionPlanesControl {\n\n    /** @private */\n    constructor(plugin) {\n\n        /**\n         * ID of this FaceAlignedSectionPlanesControl.\n         *\n         * FaceAlignedSectionPlanesControl are mapped by this ID in {@link FaceAlignedSectionPlanesPlugin#controls}.\n         *\n         * @property id\n         * @type {String|Number}\n         */\n        this.id = null;\n\n        this._viewer = plugin.viewer;\n        this._plugin = plugin;\n        this._visible = false;\n        this._pos = math.vec3(); // Full-precision position of the center of the FaceAlignedSectionPlanesControl\n        this._origin = math.vec3();\n        this._rtcPos = math.vec3();\n\n        this._baseDir = math.vec3(); // Saves direction of clip plane when we start dragging an arrow or ring.\n        this._rootNode = null; // Root of Node graph that represents this control in the 3D scene\n        this._displayMeshes = null; // Meshes that are always visible\n        this._affordanceMeshes = null; // Meshes displayed momentarily for affordance\n\n        this._ignoreNextSectionPlaneDirUpdate = false;\n\n        this._createNodes();\n        this._bindEvents();\n    }\n\n    /**\n     * Called by FaceAlignedSectionPlanesPlugin to assign this FaceAlignedSectionPlanesControl to a SectionPlane.\n     * FaceAlignedSectionPlanesPlugin keeps FaceAlignedSectionPlanesControls in a reuse pool.\n     * Call with a null or undefined value to disconnect the FaceAlignedSectionPlanesControl ffrom whatever SectionPlane it was assigned to.\n     * @private\n     */\n    _setSectionPlane(sectionPlane) {\n        if (this._sectionPlane) {\n            this._sectionPlane.off(this._onSectionPlanePos);\n            this._sectionPlane.off(this._onSectionPlaneDir);\n            this._onSectionPlanePos = null;\n            this._onSectionPlaneDir = null;\n            this._sectionPlane = null;\n        }\n        if (sectionPlane) {\n            this.id = sectionPlane.id;\n            this._setPos(sectionPlane.pos);\n            this._setDir(sectionPlane.dir);\n            this._sectionPlane = sectionPlane;\n            this._onSectionPlanePos = sectionPlane.on(\"pos\", () => {\n                this._setPos(this._sectionPlane.pos);\n            });\n            this._onSectionPlaneDir = sectionPlane.on(\"dir\", () => {\n                if (!this._ignoreNextSectionPlaneDirUpdate) {\n                    this._setDir(this._sectionPlane.dir);\n                } else {\n                    this._ignoreNextSectionPlaneDirUpdate = false;\n                }\n            });\n        }\n    }\n\n    /**\n     * Gets the {@link SectionPlane} controlled by this FaceAlignedSectionPlanesControl.\n     * @returns {SectionPlane} The SectionPlane.\n     */\n    get sectionPlane() {\n        return this._sectionPlane;\n    }\n\n    /** @private */\n    _setPos(xyz) {\n\n        this._pos.set(xyz);\n\n        worldToRTCPos(this._pos, this._origin, this._rtcPos);\n\n        this._rootNode.origin = this._origin;\n        this._rootNode.position = this._rtcPos;\n    }\n\n    /** @private */\n    _setDir(xyz) {\n        this._baseDir.set(xyz);\n        this._rootNode.quaternion = math.vec3PairToQuaternion(zeroVec, xyz, quat);\n    }\n\n    _setSectionPlaneDir(dir) {\n        if (this._sectionPlane) {\n            this._ignoreNextSectionPlaneDirUpdate = true;\n            this._sectionPlane.dir = dir;\n        }\n    }\n\n    /**\n     * Sets if this FaceAlignedSectionPlanesControl is visible.\n     *\n     * @type {Boolean}\n     */\n    setVisible(visible = true) {\n        if (this._visible === visible) {\n            return;\n        }\n        this._visible = visible;\n        var id;\n        for (id in this._displayMeshes) {\n            if (this._displayMeshes.hasOwnProperty(id)) {\n                this._displayMeshes[id].visible = visible;\n            }\n        }\n        if (!visible) {\n            for (id in this._affordanceMeshes) {\n                if (this._affordanceMeshes.hasOwnProperty(id)) {\n                    this._affordanceMeshes[id].visible = visible;\n                }\n            }\n        }\n    }\n\n    /**\n     * Gets if this FaceAlignedSectionPlanesControl is visible.\n     *\n     * @type {Boolean}\n     */\n    getVisible() {\n        return this._visible;\n    }\n\n    /**\n     * Sets if this FaceAlignedSectionPlanesControl is culled. This is called by FaceAlignedSectionPlanesPlugin to\n     * temporarily hide the FaceAlignedSectionPlanesControl while a snapshot is being taken by Viewer#getSnapshot().\n     * @param culled\n     */\n    setCulled(culled) {\n        var id;\n        for (id in this._displayMeshes) {\n            if (this._displayMeshes.hasOwnProperty(id)) {\n                this._displayMeshes[id].culled = culled;\n            }\n        }\n        if (!culled) {\n            for (id in this._affordanceMeshes) {\n                if (this._affordanceMeshes.hasOwnProperty(id)) {\n                    this._affordanceMeshes[id].culled = culled;\n                }\n            }\n        }\n    }\n\n    /**\n     * Builds the Entities that represent this FaceAlignedSectionPlanesControl.\n     * @private\n     */\n    _createNodes() {\n\n        const NO_STATE_INHERIT = false;\n        const scene = this._viewer.scene;\n        const radius = 1.0;\n        const tubeRadius = 0.01;\n        const arrowRadius = 0.07;\n\n        this._rootNode = new Node$1(scene, {\n            position: [0, 0, 0],\n            scale: [5, 5, 5]\n        });\n\n        const rootNode = this._rootNode;\n\n        const shapes = {// Reusable geometries\n\n            arrowHead: new ReadableGeometry(rootNode, buildCylinderGeometry({\n                radiusTop: 0.001,\n                radiusBottom: arrowRadius,\n                radialSegments: 32,\n                heightSegments: 1,\n                height: 0.2,\n                openEnded: false\n            })),\n\n            arrowHeadBig: new ReadableGeometry(rootNode, buildCylinderGeometry({\n                radiusTop: 0.001,\n                radiusBottom: 0.09,\n                radialSegments: 32,\n                heightSegments: 1,\n                height: 0.25,\n                openEnded: false\n            })),\n\n            axis: new ReadableGeometry(rootNode, buildCylinderGeometry({\n                radiusTop: tubeRadius,\n                radiusBottom: tubeRadius,\n                radialSegments: 20,\n                heightSegments: 1,\n                height: radius,\n                openEnded: false\n            }))\n        };\n\n        const materials = { // Reusable materials\n\n            red: new PhongMaterial(rootNode, {\n                diffuse: [1, 0.0, 0.0],\n                emissive: [1, 0.0, 0.0],\n                ambient: [0.0, 0.0, 0.0],\n                specular: [.6, .6, .3],\n                shininess: 80,\n                lineWidth: 2\n            }),\n\n            green: new PhongMaterial(rootNode, {\n                diffuse: [0, 1.0, 0.0],\n                emissive: [1, 0.0, 0.0],\n                ambient: [0.0, 0.0, 0.0],\n                specular: [.6, .6, .3],\n                shininess: 80,\n                lineWidth: 2\n            }),\n\n            blue: new PhongMaterial(rootNode, {\n                diffuse: [0, 0.0, 1.0],\n                emissive: [1, 0.0, 0.0],\n                ambient: [0.0, 0.0, 0.0],\n                specular: [.6, .6, .3],\n                shininess: 80,\n                lineWidth: 2\n            }),\n\n            highlightRed: new EmphasisMaterial(rootNode, { // Emphasis for red rotation affordance hoop\n                edges: false,\n                fill: true,\n                fillColor: [1, 0, 0],\n                fillAlpha: 0.6\n            })\n        };\n\n        this._displayMeshes = {\n\n            plane: rootNode.addChild(new Mesh(rootNode, {\n                geometry: new ReadableGeometry(rootNode, {\n                    primitive: \"triangles\",\n                    positions: [\n                        0.5, 0.5, 0.0, 0.5, -0.5, 0.0, // 0\n                        -0.5, -0.5, 0.0, -0.5, 0.5, 0.0, // 1\n                        0.5, 0.5, -0.0, 0.5, -0.5, -0.0, // 2\n                        -0.5, -0.5, -0.0, -0.5, 0.5, -0.0 // 3\n                    ],\n                    indices: [0, 1, 2, 2, 3, 0]\n                }),\n                material: new PhongMaterial(rootNode, {\n                    emissive: [0, 0.0, 0],\n                    diffuse: [0, 0, 0],\n                    backfaces: true\n                }),\n                opacity: 0.6,\n                ghosted: true,\n                pickable: false,\n                collidable: true,\n                clippable: false,\n                visible: false,\n                scale: [2.4, 2.4, 1]\n            }), NO_STATE_INHERIT),\n\n            planeFrame: rootNode.addChild(new Mesh(rootNode, { // Visible frame\n                geometry: new ReadableGeometry(rootNode, buildTorusGeometry({\n                    center: [0, 0, 0],\n                    radius: 1.7,\n                    tube: tubeRadius * 2,\n                    radialSegments: 4,\n                    tubeSegments: 4,\n                    arc: Math.PI * 2.0\n                })),\n                material: new PhongMaterial(rootNode, {\n                    emissive: [0, 0, 0],\n                    diffuse: [0, 0, 0],\n                    specular: [0, 0, 0],\n                    shininess: 0\n                }),\n                pickable: false,\n                collidable: false,\n                clippable: false,\n                visible: false,\n                scale: [1, 1, .1],\n                rotation: [0, 0, 45]\n            }), NO_STATE_INHERIT),\n\n            center: rootNode.addChild(new Mesh(rootNode, {\n                geometry: new ReadableGeometry(rootNode, buildSphereGeometry({\n                    radius: 0.05\n                })),\n                material: materials.center,\n                pickable: false,\n                collidable: true,\n                clippable: false,\n                visible: false\n            }), NO_STATE_INHERIT),\n\n            zAxisArrow: rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.arrowHead,\n                material: materials.blue,\n                matrix: (function () {\n                    const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());\n                    const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [0.8, 0, 0], math.identityMat4());\n                    return math.mulMat4(rotate, translate, math.identityMat4());\n                })(),\n                pickable: false,\n                collidable: true,\n                clippable: false,\n                visible: false\n            }), NO_STATE_INHERIT),\n\n            zShaft: rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.axis,\n                material: materials.blue,\n                matrix: (function () {\n                    const translate = math.translateMat4c(0, radius / 2, 0, math.identityMat4());\n                    const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [1, 0, 0], math.identityMat4());\n                    return math.mulMat4(rotate, translate, math.identityMat4());\n                })(),\n                clippable: false,\n                pickable: false,\n                collidable: true,\n                visible: false\n            }), NO_STATE_INHERIT)\n        };\n\n        this._affordanceMeshes = {\n\n            planeFrame: rootNode.addChild(new Mesh(rootNode, {\n                geometry: new ReadableGeometry(rootNode, buildTorusGeometry({\n                    center: [0, 0, 0],\n                    radius: 2,\n                    tube: tubeRadius,\n                    radialSegments: 4,\n                    tubeSegments: 4,\n                    arc: Math.PI * 2.0\n                })),\n                material: new PhongMaterial(rootNode, {\n                    ambient: [1, 1, 1],\n                    diffuse: [0, 0, 0],\n                    emissive: [1, 1, 0]\n                }),\n                highlighted: true,\n                highlightMaterial: new EmphasisMaterial(rootNode, {\n                    edges: false,\n                    filled: true,\n                    fillColor: [1, 1, 0],\n                    fillAlpha: 1.0\n                }),\n                pickable: false,\n                collidable: false,\n                clippable: false,\n                visible: false,\n                scale: [1, 1, 1],\n                rotation: [0, 0, 45]\n            }), NO_STATE_INHERIT),\n\n            zAxisArrow: rootNode.addChild(new Mesh(rootNode, {\n                geometry: shapes.arrowHeadBig,\n                material: materials.blue,\n                matrix: (function () {\n                    const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());\n                    const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [0.8, 0, 0], math.identityMat4());\n                    return math.mulMat4(rotate, translate, math.identityMat4());\n                })(),\n                pickable: false,\n                collidable: true,\n                clippable: false,\n                visible: false\n            }), NO_STATE_INHERIT)\n        };\n    }\n\n    _bindEvents() {\n\n        const rootNode = this._rootNode;\n        const lastCanvasPos = math.vec2();\n        const camera = this._viewer.camera;\n        const scene = this._viewer.scene;\n\n        let deltaUpdate = 0;\n        let waitForTick = false;\n\n        { // Keep gizmo screen size constant\n\n            const tempVec3a = math.vec3([0, 0, 0]);\n            let lastDist = -1;\n\n            this._onCameraViewMatrix = scene.camera.on(\"viewMatrix\", () => {\n            });\n\n            this._onCameraProjMatrix = scene.camera.on(\"projMatrix\", () => {\n            });\n\n            this._onSceneTick = scene.on(\"tick\", () => {\n\n                waitForTick = false;\n                const dist = Math.abs(math.lenVec3(math.subVec3(scene.camera.eye, this._pos, tempVec3a)));\n\n                if (dist !== lastDist) {\n                    if (camera.projection === \"perspective\") {\n                        const worldSize = (Math.tan(camera.perspective.fov * math.DEGTORAD)) * dist;\n                        const size = 0.07 * worldSize;\n                        rootNode.scale = [size, size, size];\n                        lastDist = dist;\n                    }\n                }\n\n                if (camera.projection === \"ortho\") {\n                    const worldSize = camera.ortho.scale / 10;\n                    const size = worldSize;\n                    rootNode.scale = [size, size, size];\n                    lastDist = dist;\n                }\n\n                if (deltaUpdate !== 0) {\n                    moveSectionPlane(deltaUpdate);\n                    deltaUpdate = 0;\n                }\n            });\n        }\n\n        const getClickCoordsWithinElement = (function () {\n            const canvasPos = new Float64Array(2);\n            return function (event) {\n                if (!event) {\n                    event = window.event;\n                    canvasPos[0] = event.x;\n                    canvasPos[1] = event.y;\n                } else {\n                    var element = event.target;\n                    var totalOffsetLeft = 0;\n                    var totalOffsetTop = 0;\n\n                    while (element.offsetParent) {\n                        totalOffsetLeft += element.offsetLeft;\n                        totalOffsetTop += element.offsetTop;\n                        element = element.offsetParent;\n                    }\n                    canvasPos[0] = event.pageX - totalOffsetLeft;\n                    canvasPos[1] = event.pageY - totalOffsetTop;\n                }\n                return canvasPos;\n            };\n        })();\n\n        const moveSectionPlane = (delta) => {\n            const pos = this._sectionPlane.pos;\n            const dir = this._sectionPlane.dir;\n            math.addVec3(pos, math.mulVec3Scalar(dir, 0.1 * delta * this._plugin.getDragSensitivity(), math.vec3()));\n            this._sectionPlane.pos = pos;\n        };\n\n        {\n            let down = false;\n\n            this._plugin._controlElement.addEventListener(\"mousedown\", this._canvasMouseDownListener = (e) => {\n                e.preventDefault();\n                if (!this._visible) {\n                    return;\n                }\n                this._viewer.cameraControl.pointerEnabled = false;\n                switch (e.which) {\n                    case 1: // Left button\n                        down = true;\n                        var canvasPos = getClickCoordsWithinElement(e);\n                        lastCanvasPos[0] = canvasPos[0];\n                        lastCanvasPos[1] = canvasPos[1];\n                        break;\n                }\n            });\n\n            this._plugin._controlElement.addEventListener(\"mousemove\", this._canvasMouseMoveListener = (e) => {\n                if (!this._visible) {\n                    return;\n                }\n                if (!down) {\n                    return;\n                }\n                if (waitForTick) {    // Limit changes detection to one per frame\n                    return;\n                }\n                var canvasPos = getClickCoordsWithinElement(e);\n                const x = canvasPos[0];\n                const y = canvasPos[1];\n                moveSectionPlane(y - lastCanvasPos[1]);\n                lastCanvasPos[0] = x;\n                lastCanvasPos[1] = y;\n            });\n\n            this._plugin._controlElement.addEventListener(\"mouseup\", this._canvasMouseUpListener = (e) => {\n                if (!this._visible) {\n                    return;\n                }\n                this._viewer.cameraControl.pointerEnabled = true;\n                if (!down) {\n                    return;\n                }\n                switch (e.which) {\n                                    }\n                down = false;\n            });\n\n            this._plugin._controlElement.addEventListener(\"wheel\", this._canvasWheelListener = (e) => {\n                if (!this._visible) {\n                    return;\n                }\n                deltaUpdate += Math.max(-1, Math.min(1, -e.deltaY * 40));\n            });\n        }\n\n        {\n            let touchStartY, touchEndY;\n            let lastTouchY = null;\n\n            this._plugin._controlElement.addEventListener(\"touchstart\", this._handleTouchStart = (e) => {\n                e.stopPropagation();\n                e.preventDefault();\n                if (!this._visible) {\n                    return;\n                }\n                touchStartY = e.touches[0].clientY;\n                lastTouchY = touchStartY;\n                deltaUpdate = 0;\n            });\n\n            this._plugin._controlElement.addEventListener(\"touchmove\", this._handleTouchMove = (e) => {\n                e.stopPropagation();\n                e.preventDefault();\n                if (!this._visible) {\n                    return;\n                }\n                if (waitForTick) {    // Limit changes detection to one per frame\n                    return;\n                }\n                waitForTick = true;\n                touchEndY = e.touches[0].clientY;\n                if (lastTouchY !== null) {\n                    deltaUpdate += touchEndY - lastTouchY;\n                }\n                lastTouchY = touchEndY;\n            });\n\n            this._plugin._controlElement.addEventListener(\"touchend\", this._handleTouchEnd = (e) => {\n                e.stopPropagation();\n                e.preventDefault();\n                if (!this._visible) {\n                    return;\n                }\n                touchStartY = null;\n                touchEndY = null;\n                deltaUpdate = 0;\n            });\n        }\n    }\n\n    _destroy() {\n        this._unbindEvents();\n        this._destroyNodes();\n    }\n\n    _unbindEvents() {\n\n        const viewer = this._viewer;\n        const scene = viewer.scene;\n        const canvas = scene.canvas.canvas;\n        const camera = viewer.camera;\n        const controlElement = this._plugin._controlElement;\n\n        scene.off(this._onSceneTick);\n\n        canvas.removeEventListener(\"mousedown\", this._canvasMouseDownListener);\n        canvas.removeEventListener(\"mousemove\", this._canvasMouseMoveListener);\n        canvas.removeEventListener(\"mouseup\", this._canvasMouseUpListener);\n        canvas.removeEventListener(\"wheel\", this._canvasWheelListener);\n\n        controlElement.removeEventListener(\"touchstart\", this._handleTouchStart);\n        controlElement.removeEventListener(\"touchmove\", this._handleTouchMove);\n        controlElement.removeEventListener(\"touchend\", this._handleTouchEnd);\n\n        camera.off(this._onCameraViewMatrix);\n        camera.off(this._onCameraProjMatrix);\n    }\n\n    _destroyNodes() {\n        this._setSectionPlane(null);\n        this._rootNode.destroy();\n        this._displayMeshes = {};\n        this._affordanceMeshes = {};\n    }\n}\n\n/**\n * Renders a 3D plane within an {@link Overview} to indicate its {@link SectionPlane}'s current position and orientation.\n *\n * @private\n */\nclass Plane {\n\n    /** @private */\n    constructor(overview, overviewScene, sectionPlane) {\n\n        /**\n         * The ID of this SectionPlanesOverviewPlane.\n         *\n         * @type {String}\n         */\n        this.id = sectionPlane.id;\n\n        /**\n         * The {@link SectionPlane} represented by this SectionPlanesOverviewPlane.\n         *\n         * @type {SectionPlane}\n         */\n        this._sectionPlane = sectionPlane;\n\n        this._mesh = new Mesh(overviewScene, {\n            id: sectionPlane.id,\n            geometry: new ReadableGeometry(overviewScene, buildBoxGeometry({\n                xSize: .5,\n                ySize: .5,\n                zSize: .001\n            })),\n            material: new PhongMaterial(overviewScene, {\n                emissive: [1, 1, 1],\n                diffuse: [0, 0, 0],\n                backfaces: false\n            }),\n            edgeMaterial: new EdgeMaterial(overviewScene, {\n                edgeColor: [0.0, 0.0, 0.0],\n                edgeAlpha: 1.0,\n                edgeWidth: 1\n            }),\n            highlightMaterial: new EmphasisMaterial(overviewScene, {\n                fill: true,\n                fillColor: [0.5, 1, 0.5],\n                fillAlpha: 0.7,\n                edges: true,\n                edgeColor: [0.0, 0.0, 0.0],\n                edgeAlpha: 1.0,\n                edgeWidth: 1\n            }),\n            selectedMaterial: new EmphasisMaterial(overviewScene, {\n                fill: true,\n                fillColor: [0, 0, 1],\n                fillAlpha: 0.7,\n                edges: true,\n                edgeColor: [1.0, 0.0, 0.0],\n                edgeAlpha: 1.0,\n                edgeWidth: 1\n            }),\n            highlighted: true,\n            scale: [3, 3, 3],\n            position: [0, 0, 0],\n            rotation: [0, 0, 0],\n            opacity: 0.3,\n            edges: true\n        });\n\n\n        {\n            const vec = math.vec3([0, 0, 0]);\n            const pos2 = math.vec3();\n            const zeroVec = math.vec3([0, 0, 1]);\n            const quat = math.vec4(4);\n            const pos3 = math.vec3();\n\n            const update = () => {\n\n                const origin = this._sectionPlane.scene.center;\n\n                const negDir = [-this._sectionPlane.dir[0], -this._sectionPlane.dir[1], -this._sectionPlane.dir[2]];\n                math.subVec3(origin, this._sectionPlane.pos, vec);\n                const dist = -math.dotVec3(negDir, vec);\n\n                math.normalizeVec3(negDir);\n                math.mulVec3Scalar(negDir, dist, pos2);\n                const quaternion = math.vec3PairToQuaternion(zeroVec, this._sectionPlane.dir, quat);\n\n                pos3[0] = pos2[0] * 0.1;\n                pos3[1] = pos2[1] * 0.1;\n                pos3[2] = pos2[2] * 0.1;\n\n                this._mesh.quaternion = quaternion;\n                this._mesh.position = pos3;\n            };\n\n            this._onSectionPlanePos = this._sectionPlane.on(\"pos\", update);\n            this._onSectionPlaneDir = this._sectionPlane.on(\"dir\", update);\n\n            // update();\n        }\n\n        this._highlighted = false;\n        this._selected = false;\n    }\n\n    /**\n     * Sets if this SectionPlanesOverviewPlane is highlighted.\n     *\n     * @type {Boolean}\n     * @private\n     */\n    setHighlighted(highlighted) {\n        this._highlighted = !!highlighted;\n        this._mesh.highlighted = this._highlighted;\n        this._mesh.highlightMaterial.fillColor = highlighted ? [0, 0.7, 0] : [0, 0, 0];\n        // this._selectedMesh.highlighted = true;\n    }\n\n    /**\n     * Gets if this SectionPlanesOverviewPlane is highlighted.\n     *\n     * @type {Boolean}\n     * @private\n     */\n    getHighlighted() {\n        return this._highlighted;\n    }\n\n    /**\n     * Sets if this SectionPlanesOverviewPlane is selected.\n     *\n     * @type {Boolean}\n     * @private\n     */\n    setSelected(selected) {\n        this._selected = !!selected;\n        this._mesh.edgeMaterial.edgeWidth = selected ? 3 : 1;\n        this._mesh.highlightMaterial.edgeWidth = selected ? 3 : 1;\n\n    }\n\n    /**\n     * Gets if this SectionPlanesOverviewPlane is selected.\n     *\n     * @type {Boolean}\n     * @private\n     */\n    getSelected() {\n        return this._selected;\n    }\n\n    /** @private */\n    destroy() {\n        this._sectionPlane.off(this._onSectionPlanePos);\n        this._sectionPlane.off(this._onSectionPlaneDir);\n        this._mesh.destroy();\n    }\n}\n\n/**\n * @desc An interactive 3D overview for navigating the {@link SectionPlane}s created by its {@link FaceAlignedSectionPlanesPlugin}.\n *\n * * Located at {@link FaceAlignedSectionPlanesPlugin#overview}.\n * * Renders the overview on a separate canvas at a corner of the {@link Viewer}'s {@link Scene} {@link Canvas}.\n * * The overview shows a 3D plane object for each {@link SectionPlane} in the {@link Scene}.\n * * Click a plane object in the overview to toggle the visibility of a 3D gizmo to edit the position and orientation of its {@link SectionPlane}.\n *\n * @private\n */\nclass Overview {\n\n    /**\n     * @private\n     */\n    constructor(plugin, cfg) {\n\n        if (!cfg.onHoverEnterPlane || !cfg.onHoverLeavePlane || !cfg.onClickedNothing || !cfg.onClickedPlane) {\n            throw \"Missing config(s): onHoverEnterPlane, onHoverLeavePlane, onClickedNothing || onClickedPlane\";\n        }\n\n        /**\n         * The {@link FaceAlignedSectionPlanesPlugin} that owns this SectionPlanesOverview.\n         *\n         * @type {FaceAlignedSectionPlanesPlugin}\n         */\n        this.plugin = plugin;\n\n        this._viewer = plugin.viewer;\n\n        this._onHoverEnterPlane = cfg.onHoverEnterPlane;\n        this._onHoverLeavePlane = cfg.onHoverLeavePlane;\n        this._onClickedNothing = cfg.onClickedNothing;\n        this._onClickedPlane = cfg.onClickedPlane;\n        this._visible = true;\n\n        this._planes = {};\n\n        //--------------------------------------------------------------------------------------------------------------\n        // Init canvas\n        //--------------------------------------------------------------------------------------------------------------\n\n        this._canvas = cfg.overviewCanvas;\n\n        //--------------------------------------------------------------------------------------------------------------\n        // Init scene\n        //--------------------------------------------------------------------------------------------------------------\n\n        this._scene = new Scene(this._viewer, {\n            canvasId: this._canvas.id,\n            transparent: true\n        });\n        this._scene.clearLights();\n        new DirLight(this._scene, {\n            dir: [0.4, -0.4, 0.8],\n            color: [0.8, 1.0, 1.0],\n            intensity: 1.0,\n            space: \"view\"\n        });\n        new DirLight(this._scene, {\n            dir: [-0.8, -0.3, -0.4],\n            color: [0.8, 0.8, 0.8],\n            intensity: 1.0,\n            space: \"view\"\n        });\n        new DirLight(this._scene, {\n            dir: [0.8, -0.6, -0.8],\n            color: [1.0, 1.0, 1.0],\n            intensity: 1.0,\n            space: \"view\"\n        });\n\n        this._scene.camera;\n        this._scene.camera.perspective.fov = 70;\n\n        this._zUp = false;\n\n        //--------------------------------------------------------------------------------------------------------------\n        // Synchronize overview scene camera with viewer camera\n        //--------------------------------------------------------------------------------------------------------------\n\n        {\n            const camera = this._scene.camera;\n            const matrix = math.rotationMat4c(-90 * math.DEGTORAD, 1, 0, 0);\n            const eyeLookVec = math.vec3();\n            const eyeLookVecOverview = math.vec3();\n            const upOverview = math.vec3();\n\n            this._synchCamera = () => {\n                const eye = this._viewer.camera.eye;\n                const look = this._viewer.camera.look;\n                const up = this._viewer.camera.up;\n                math.mulVec3Scalar(math.normalizeVec3(math.subVec3(eye, look, eyeLookVec)), 7);\n                if (this._zUp) { // +Z up\n                    math.transformVec3(matrix, eyeLookVec, eyeLookVecOverview);\n                    math.transformVec3(matrix, up, upOverview);\n                    camera.look = [0, 0, 0];\n                    camera.eye = math.transformVec3(matrix, eyeLookVec, eyeLookVecOverview);\n                    camera.up = math.transformPoint3(matrix, up, upOverview);\n                } else { // +Y up\n                    camera.look = [0, 0, 0];\n                    camera.eye = eyeLookVec;\n                    camera.up = up;\n                }\n            };\n        }\n\n        this._onViewerCameraMatrix = this._viewer.camera.on(\"matrix\", this._synchCamera);\n\n        this._onViewerCameraWorldAxis = this._viewer.camera.on(\"worldAxis\", this._synchCamera);\n\n        this._onViewerCameraFOV = this._viewer.camera.perspective.on(\"fov\", (fov) => {\n            this._scene.camera.perspective.fov = fov;\n        });\n\n        //--------------------------------------------------------------------------------------------------------------\n        // Bind overview canvas events\n        //--------------------------------------------------------------------------------------------------------------\n\n        {\n            var hoveredEntity = null;\n\n            this._onInputMouseMove = this._scene.input.on(\"mousemove\", (coords) => {\n                const hit = this._scene.pick({\n                    canvasPos: coords\n                });\n                if (hit) {\n                    if (!hoveredEntity || hit.entity.id !== hoveredEntity.id) {\n                        if (hoveredEntity) {\n                            const plane = this._planes[hoveredEntity.id];\n                            if (plane) {\n                                this._onHoverLeavePlane(hoveredEntity.id);\n                            }\n                        }\n                        hoveredEntity = hit.entity;\n                        const plane = this._planes[hoveredEntity.id];\n                        if (plane) {\n                            this._onHoverEnterPlane(hoveredEntity.id);\n                        }\n                    }\n                } else {\n                    if (hoveredEntity) {\n                        this._onHoverLeavePlane(hoveredEntity.id);\n                        hoveredEntity = null;\n                    }\n                }\n            });\n\n            this._scene.canvas.canvas.addEventListener(\"mouseup\", this._onCanvasMouseUp = () => {\n                if (hoveredEntity) {\n                    const plane = this._planes[hoveredEntity.id];\n                    if (plane) {\n                        this._onClickedPlane(hoveredEntity.id);\n                    }\n                } else {\n                    this._onClickedNothing();\n                }\n            });\n\n            this._scene.canvas.canvas.addEventListener(\"mouseout\", this._onCanvasMouseOut = () => {\n                if (hoveredEntity) {\n                    this._onHoverLeavePlane(hoveredEntity.id);\n                    hoveredEntity = null;\n                }\n            });\n        }\n\n        //--------------------------------------------------------------------------------------------------------------\n        // Configure overview\n        //--------------------------------------------------------------------------------------------------------------\n\n        this.setVisible(cfg.overviewVisible);\n    }\n\n    /** Called by SectionPlanesPlugin#createSectionPlane()\n     * @private\n     */\n    addSectionPlane(sectionPlane) {\n        this._planes[sectionPlane.id] = new Plane(this, this._scene, sectionPlane);\n    }\n\n    /**  @private\n     */\n    setPlaneHighlighted(id, highlighted) {\n        const plane = this._planes[id];\n        if (plane) {\n            plane.setHighlighted(highlighted);\n        }\n    }\n\n    /**  @private\n     */\n    setPlaneSelected(id, selected) {\n        const plane = this._planes[id];\n        if (plane) {\n            plane.setSelected(selected);\n        }\n    }\n\n    /** @private\n     */\n    removeSectionPlane(sectionPlane) {\n        const plane = this._planes[sectionPlane.id];\n        if (plane) {\n            plane.destroy();\n            delete this._planes[sectionPlane.id];\n        }\n    }\n\n    /**\n     * Sets if this SectionPlanesOverview is visible.\n     *\n     * @param {Boolean} visible Whether or not this SectionPlanesOverview is visible.\n     */\n    setVisible(visible = true) {\n        this._visible = visible;\n        this._canvas.style.visibility = visible ? \"visible\" : \"hidden\";\n    }\n\n    /**\n     * Gets if this SectionPlanesOverview is visible.\n     *\n     * @return {Boolean} True when this SectionPlanesOverview is visible.\n     */\n    getVisible() {\n        return this._visible;\n    }\n\n    /**  @private\n     */\n    destroy() {\n        this._viewer.camera.off(this._onViewerCameraMatrix);\n        this._viewer.camera.off(this._onViewerCameraWorldAxis);\n        this._viewer.camera.perspective.off(this._onViewerCameraFOV);\n\n        this._scene.input.off(this._onInputMouseMove);\n        this._scene.canvas.canvas.removeEventListener(\"mouseup\", this._onCanvasMouseUp);\n        this._scene.canvas.canvas.removeEventListener(\"mouseout\", this._onCanvasMouseOut);\n        this._scene.destroy();\n    }\n}\n\nconst tempAABB = math.AABB3();\nconst tempVec3 = math.vec3();\n\n/**\n * FaceAlignedSectionPlanesPlugin is a {@link Viewer} plugin that creates and edits face-aligned {@link SectionPlane}s.\n *\n * [<img src=\"https://xeokit.github.io/xeokit-sdk/assets/images/FaceAlignedSectionPlanesPlugin.gif\">](https://xeokit.github.io/xeokit-sdk/examples/index.html#gizmos_FaceAlignedSectionPlanesPlugin)\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/slicing/#FaceAlignedSectionPlanesPlugin)]\n *\n * ## Overview\n *\n * * Use the FaceAlignedSectionPlanesPlugin to\n * create and edit {@link SectionPlane}s to slice portions off your models and reveal internal structures.\n *\n * * As shown in the screen capture above, FaceAlignedSectionPlanesPlugin shows an overview of all your SectionPlanes (on the right, in\n * this example).\n * * Click a plane in the overview to activate a 3D control with which you can interactively\n * reposition its SectionPlane in the main canvas.\n * * Configure the plugin with an HTML element that the user can click-and-drag on to reposition the SectionPlane for which the control is active.\n * * Use {@link BCFViewpointsPlugin} to save and load SectionPlanes in BCF viewpoints.\n *\n * ## Usage\n *\n * In the example below, we'll use a {@link GLTFLoaderPlugin} to load a model, and a FaceAlignedSectionPlanesPlugin\n * to slice it open with two {@link SectionPlane}s. We'll show the overview in the bottom right of the Viewer\n * canvas. Finally, we'll programmatically activate the 3D editing control, so that we can use it to interactively\n * reposition our second SectionPlane.\n *\n * ````JavaScript\n * import {Viewer, GLTFLoaderPlugin, FaceAlignedSectionPlanesPlugin} from \"xeokit-sdk.es.js\";\n *\n * // Create a Viewer and arrange its Camera\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\"\n * });\n *\n * viewer.camera.eye = [-5.02, 2.22, 15.09];\n * viewer.camera.look = [4.97, 2.79, 9.89];\n * viewer.camera.up = [-0.05, 0.99, 0.02];\n *\n * // Add a GLTFLoaderPlugin\n *\n * const gltfLoader = new GLTFLoaderPlugin(viewer);\n *\n * // Add a FaceAlignedSectionPlanesPlugin, with overview visible\n *\n * const faceAlignedSectionPlanes = new FaceAlignedSectionPlanesPlugin(viewer, {\n *     overviewCanvasID: \"myOverviewCanvas\",\n *     overviewVisible: true,\n *     controlElementId: \"myControlElement\", // ID of element to capture drag events that move the SectionPlane\n *     dragSensitivity: 1  // Sensitivity factor that governs the rate at which dragging moves the SectionPlane\n * });\n *\n * // Load a model\n *\n * const model = gltfLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/gltf/schependomlaan/scene.glb\"\n * });\n *\n * // Create a couple of section planes\n * // These will be shown in the overview\n *\n * faceAlignedSectionPlanes.createSectionPlane({\n *     id: \"mySectionPlane\",\n *     pos: [1.04, 1.95, 9.74],\n *     dir: [1.0, 0.0, 0.0]\n * });\n *\n * faceAlignedSectionPlanes.createSectionPlane({\n *     id: \"mySectionPlane2\",\n *     pos: [2.30, 4.46, 14.93],\n *     dir: [0.0, -0.09, -0.79]\n * });\n *\n * // Show the FaceAlignedSectionPlanesPlugin's 3D editing gizmo,\n * // to interactively reposition one of our SectionPlanes\n *\n * faceAlignedSectionPlanes.showControl(\"mySectionPlane2\");\n *\n * const mySectionPlane2 = faceAlignedSectionPlanes.sectionPlanes[\"mySectionPlane2\"];\n *\n * // Programmatically reposition one of our SectionPlanes\n * // This also updates its position as shown in the overview gizmo\n *\n * mySectionPlane2.pos = [11.0, 6.0, -12];\n * mySectionPlane2.dir = [0.4, 0.0, 0.5];\n * ````\n */\nclass FaceAlignedSectionPlanesPlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg Plugin configuration.\n     * @param {String} [cfg.id=\"SectionPlanes\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {String} [cfg.overviewCanvasId] ID of a canvas element to display the overview.\n     * @param {String} [cfg.overviewVisible=true] Initial visibility of the overview canvas.\n     * @param {String} cfg.controlElementId ID of an HTML element that catches drag events to move the active SectionPlane.\n     * @param {Number} [cfg.dragSensitivity=1] Sensitivity factor that governs the rate at which dragging on the control element moves SectionPlane.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"FaceAlignedSectionPlanesPlugin\", viewer);\n\n        this._freeControls = [];\n        this._sectionPlanes = viewer.scene.sectionPlanes;\n        this._controls = {};\n        this._shownControlId = null;\n        this._dragSensitivity = cfg.dragSensitivity || 1;\n\n        if (cfg.overviewCanvasId !== null && cfg.overviewCanvasId !== undefined) {\n\n            const overviewCanvas = document.getElementById(cfg.overviewCanvasId);\n\n            if (!overviewCanvas) {\n                this.warn(\"Can't find overview canvas: '\" + cfg.overviewCanvasId + \"' - will create plugin without overview\");\n\n            } else {\n\n                this._overview = new Overview(this, {\n                    overviewCanvas: overviewCanvas,\n                    visible: cfg.overviewVisible,\n\n                    onHoverEnterPlane: ((id) => {\n                        this._overview.setPlaneHighlighted(id, true);\n                    }),\n\n                    onHoverLeavePlane: ((id) => {\n                        this._overview.setPlaneHighlighted(id, false);\n                    }),\n\n                    onClickedPlane: ((id) => {\n                        if (this.getShownControl() === id) {\n                            this.hideControl();\n                            return;\n                        }\n                        this.showControl(id);\n                        const sectionPlane = this.sectionPlanes[id];\n                        const sectionPlanePos = sectionPlane.pos;\n                        tempAABB.set(this.viewer.scene.aabb);\n                        math.getAABB3Center(tempAABB, tempVec3);\n                        tempAABB[0] += sectionPlanePos[0] - tempVec3[0];\n                        tempAABB[1] += sectionPlanePos[1] - tempVec3[1];\n                        tempAABB[2] += sectionPlanePos[2] - tempVec3[2];\n                        tempAABB[3] += sectionPlanePos[0] - tempVec3[0];\n                        tempAABB[4] += sectionPlanePos[1] - tempVec3[1];\n                        tempAABB[5] += sectionPlanePos[2] - tempVec3[2];\n                        this.viewer.cameraFlight.flyTo({\n                            aabb: tempAABB,\n                            fitFOV: 65\n                        });\n                    }),\n\n                    onClickedNothing: (() => {\n                        this.hideControl();\n                    })\n                });\n            }\n        }\n\n        if (cfg.controlElementId === null || cfg.controlElementId === undefined) {\n            this.error(\"Parameter expected: controlElementId\");\n        } else {\n            this._controlElement = document.getElementById(cfg.controlElementId);\n            if (!this._controlElement) {\n                this.warn(\"Can't find control element: '\" + cfg.controlElementId + \"' - will create plugin without control element\");\n\n            }\n        }\n\n        this._onSceneSectionPlaneCreated = viewer.scene.on(\"sectionPlaneCreated\", (sectionPlane) => {\n\n            // SectionPlane created, either via FaceAlignedSectionPlanesPlugin#createSectionPlane(), or by directly\n            // instantiating a SectionPlane independently of FaceAlignedSectionPlanesPlugin, which can be done\n            // by BCFViewpointsPlugin#loadViewpoint().\n\n            this._sectionPlaneCreated(sectionPlane);\n        });\n    }\n\n    /**\n     * Sets the factor that governs how fast a SectionPlane moves as we drag on the control element.\n     *\n     * @param {Number} dragSensitivity  The dragging sensitivity factor.\n     */\n    setDragSensitivity(dragSensitivity) {\n      this._dragSensitivity = dragSensitivity || 1;\n    }\n\n    /**\n     * Gets the factor that governs how fast a SectionPlane moves as we drag on the control element.\n     *\n     * @return {Number} The dragging sensitivity factor.\n     */\n    getDragSensitivity() {\n        return this._dragSensitivity;\n    }\n\n    /**\n     * Sets if the overview canvas is visible.\n     *\n     * @param {Boolean} visible Whether or not the overview canvas is visible.\n     */\n    setOverviewVisible(visible) {\n        if (this._overview) {\n            this._overview.setVisible(visible);\n        }\n    }\n\n    /**\n     * Gets if the overview canvas is visible.\n     *\n     * @return {Boolean} True when the overview canvas is visible.\n     */\n    getOverviewVisible() {\n        if (this._overview) {\n            return this._overview.getVisible();\n        }\n    }\n\n    /**\n     * Returns a map of the {@link SectionPlane}s created by this FaceAlignedSectionPlanesPlugin.\n     *\n     * @returns {{String:SectionPlane}} A map containing the {@link SectionPlane}s, each mapped to its {@link SectionPlane#id}.\n     */\n    get sectionPlanes() {\n        return this._sectionPlanes;\n    }\n\n    /**\n     * Creates a {@link SectionPlane}.\n     *\n     * The {@link SectionPlane} will be registered by {@link SectionPlane#id} in {@link FaceAlignedSectionPlanesPlugin#sectionPlanes}.\n     *\n     * @param {Object} params {@link SectionPlane} configuration.\n     * @param {String} [params.id] Unique ID to assign to the {@link SectionPlane}. Must be unique among all components in the {@link Viewer}'s {@link Scene}. Auto-generated when omitted.\n     * @param {Number[]} [params.pos=[0,0,0]] World-space position of the {@link SectionPlane}.\n     * @param {Number[]} [params.dir=[0,0,-1]] World-space vector indicating the orientation of the {@link SectionPlane}.\n     * @param {Boolean} [params.active=true] Whether the {@link SectionPlane} is initially active. Only clips while this is true.\n     * @returns {SectionPlane} The new {@link SectionPlane}.\n     */\n    createSectionPlane(params = {}) {\n\n        if (params.id !== undefined && params.id !== null && this.viewer.scene.components[params.id]) {\n            this.error(\"Viewer component with this ID already exists: \" + params.id);\n            delete params.id;\n        }\n\n        // Note that SectionPlane constructor fires \"sectionPlaneCreated\" on the Scene,\n        // which FaceAlignedSectionPlanesPlugin handles and calls #_sectionPlaneCreated to create gizmo and add to overview canvas.\n\n        const sectionPlane = new SectionPlane(this.viewer.scene, {\n            id: params.id,\n            pos: params.pos,\n            dir: params.dir,\n            active: true \n        });\n        return sectionPlane;\n    }\n\n    _sectionPlaneCreated(sectionPlane) {\n        const control = (this._freeControls.length > 0) ? this._freeControls.pop() : new FaceAlignedSectionPlanesControl(this);\n        control._setSectionPlane(sectionPlane);\n        control.setVisible(false);\n        this._controls[sectionPlane.id] = control;\n        if (this._overview) {\n            this._overview.addSectionPlane(sectionPlane);\n        }\n        sectionPlane.once(\"destroyed\", () => {\n            this._sectionPlaneDestroyed(sectionPlane);\n        });\n    }\n\n    /**\n     * Inverts the direction of {@link SectionPlane#dir} on every existing SectionPlane.\n     *\n     * Inverts all SectionPlanes, including those that were not created with FaceAlignedSectionPlanesPlugin.\n     */\n    flipSectionPlanes() {\n        const sectionPlanes = this.viewer.scene.sectionPlanes;\n        for (let id in sectionPlanes) {\n            const sectionPlane = sectionPlanes[id];\n            sectionPlane.flipDir();\n        }\n    }\n\n    /**\n     * Shows the 3D editing gizmo for a {@link SectionPlane}.\n     *\n     * @param {String} id ID of the {@link SectionPlane}.\n     */\n    showControl(id) {\n        const control = this._controls[id];\n        if (!control) {\n            this.error(\"Control not found: \" + id);\n            return;\n        }\n        this.hideControl();\n        control.setVisible(true);\n        if (this._overview) {\n            this._overview.setPlaneSelected(id, true);\n        }\n        this._shownControlId = id;\n    }\n\n    /**\n     * Gets the ID of the {@link SectionPlane} that the 3D editing gizmo is shown for.\n     *\n     * Returns ````null```` when the editing gizmo is not shown.\n     *\n     * @returns {String} ID of the the {@link SectionPlane} that the 3D editing gizmo is shown for, if shown, else ````null````.\n     */\n    getShownControl() {\n        return this._shownControlId;\n    }\n\n    /**\n     * Hides the 3D {@link SectionPlane} editing gizmo if shown.\n     */\n    hideControl() {\n        for (let id in this._controls) {\n            if (this._controls.hasOwnProperty(id)) {\n                this._controls[id].setVisible(false);\n                if (this._overview) {\n                    this._overview.setPlaneSelected(id, false);\n                }\n            }\n        }\n        this._shownControlId = null;\n    }\n\n    /**\n     * Destroys a {@link SectionPlane} created by this FaceAlignedSectionPlanesPlugin.\n     *\n     * @param {String} id ID of the {@link SectionPlane}.\n     */\n    destroySectionPlane(id) {\n        let sectionPlane = this.viewer.scene.sectionPlanes[id];\n        if (!sectionPlane) {\n            this.error(\"SectionPlane not found: \" + id);\n            return;\n        }\n        this._sectionPlaneDestroyed(sectionPlane);\n        sectionPlane.destroy();\n\n        if (id === this._shownControlId) {\n            this._shownControlId = null;\n        }\n    }\n\n    _sectionPlaneDestroyed(sectionPlane) {\n        if (this._overview) {\n            this._overview.removeSectionPlane(sectionPlane);\n        }\n        const control = this._controls[sectionPlane.id];\n        if (!control) {\n            return;\n        }\n        control.setVisible(false);\n        control._setSectionPlane(null);\n        delete this._controls[sectionPlane.id];\n        this._freeControls.push(control);\n    }\n\n    /**\n     * Destroys all {@link SectionPlane}s created by this FaceAlignedSectionPlanesPlugin.\n     */\n    clear() {\n        const ids = Object.keys(this._sectionPlanes);\n        for (let i = 0, len = ids.length; i < len; i++) {\n            this.destroySectionPlane(ids[i]);\n        }\n    }\n\n    /**\n     * @private\n     */\n    send(name, value) {\n        switch (name) {\n\n            case \"snapshotStarting\": // Viewer#getSnapshot() about to take snapshot - hide controls\n                for (let id in this._controls) {\n                    if (this._controls.hasOwnProperty(id)) {\n                        this._controls[id].setCulled(true);\n                    }\n                }\n                break;\n\n            case \"snapshotFinished\": // Viewer#getSnapshot() finished taking snapshot - show controls again\n                for (let id in this._controls) {\n                    if (this._controls.hasOwnProperty(id)) {\n                        this._controls[id].setCulled(false);\n                    }\n                }\n                break;\n\n            case \"clearSectionPlanes\":\n                this.clear();\n                break;\n        }\n    }\n\n    /**\n     * Destroys this FaceAlignedSectionPlanesPlugin.\n     *\n     * Also destroys each {@link SectionPlane} created by this FaceAlignedSectionPlanesPlugin.\n     *\n     * Does not destroy the canvas the FaceAlignedSectionPlanesPlugin was configured with.\n     */\n    destroy() {\n        this.clear();\n        if (this._overview) {\n            this._overview.destroy();\n        }\n        this._destroyFreeControls();\n        super.destroy();\n    }\n\n    _destroyFreeControls() {\n        let control = this._freeControls.pop();\n        while (control) {\n            control._destroy();\n            control = this._freeControls.pop();\n        }\n        this.viewer.scene.off(this._onSceneSectionPlaneCreated);\n    }\n}\n\n/**\n * Default data access strategy for {@link STLLoaderPlugin}.\n *\n * This implementation simply loads STL files using XMLHttpRequest.\n */\nclass STLDefaultDataSource {\n\n    constructor(cfg = {}) {\n        this.cacheBuster = (cfg.cacheBuster !== false);\n    }\n\n    _cacheBusterURL(url) {\n        if (!this.cacheBuster) {\n            return url;\n        }\n        const timestamp = new Date().getTime();\n        if (url.indexOf('?') > -1) {\n            return url + '&_=' + timestamp;\n        } else {\n            return url + '?_=' + timestamp;\n        }\n    }\n\n    /**\n     * Gets STL data.\n     *\n     * @param {String|Number} src Identifies the STL file.\n     * @param {Function} ok Fired on successful loading of the STL file.\n     * @param {Function} error Fired on error while loading the STL file.\n     */\n    getSTL(src, ok, error) {\n        src = this._cacheBusterURL(src);\n        const request = new XMLHttpRequest();\n        request.overrideMimeType(\"application/json\");\n        request.open('GET', src, true);\n        request.responseType = 'arraybuffer';\n        request.onreadystatechange = function () {\n            if (request.readyState === 4) {\n                if (request.status === 200) {\n                    ok(request.response);\n                } else {\n                    error(request.statusText);\n                }\n            }\n        };\n        request.send(null);\n    }\n}\n\nconst tempVec3a$1 = math.vec3();\n\n/**\n * @private\n */\nclass STLSceneGraphLoader {\n\n    load(plugin, modelNode, src, options, ok, error) {\n\n        options = options || {};\n\n        const spinner = plugin.viewer.scene.canvas.spinner;\n        spinner.processes++;\n\n        plugin.dataSource.getSTL(src, function (data) { // OK\n                parse(plugin, modelNode, data, options);\n                try {\n                    const binData = ensureBinary(data);\n                    if (isBinary(binData)) {\n                        parseBinary(plugin, binData, modelNode, options);\n                    } else {\n                        parseASCII(plugin, ensureString(data), modelNode, options);\n                    }\n                    spinner.processes--;\n                    core.scheduleTask(function () {\n                        modelNode.fire(\"loaded\", true, false);\n                    });\n                    if (ok) {\n                        ok();\n                    }\n                } catch (e) {\n                    spinner.processes--;\n                    plugin.error(e);\n                    if (error) {\n                        error(e);\n                    }\n                    modelNode.fire(\"error\", e);\n                }\n            },\n            function (msg) {\n                spinner.processes--;\n                plugin.error(msg);\n                if (error) {\n                    error(msg);\n                }\n                modelNode.fire(\"error\", msg);\n            });\n    }\n\n    parse(plugin, modelNode, data, options) {\n        const spinner = plugin.viewer.scene.canvas.spinner;\n        spinner.processes++;\n        try {\n            const binData = ensureBinary(data);\n            if (isBinary(binData)) {\n                parseBinary(plugin, binData, modelNode, options);\n            } else {\n                parseASCII(plugin, ensureString(data), modelNode, options);\n            }\n            spinner.processes--;\n            core.scheduleTask(function () {\n                modelNode.fire(\"loaded\", true, false);\n            });\n        } catch (e) {\n            spinner.processes--;\n            modelNode.fire(\"error\", e);\n        }\n    }\n}\n\nfunction parse(plugin, modelNode, data, options) {\n    try {\n        const binData = ensureBinary(data);\n        if (isBinary(binData)) {\n            parseBinary(plugin, binData, modelNode, options);\n        } else {\n            parseASCII(plugin, ensureString(data), modelNode, options);\n        }\n    } catch (e) {\n        modelNode.fire(\"error\", e);\n    }\n}\n\nfunction isBinary(data) {\n    const reader = new DataView(data);\n    const numFaces = reader.getUint32(80, true);\n    const faceSize = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);\n    const numExpectedBytes = 80 + (32 / 8) + (numFaces * faceSize);\n    if (numExpectedBytes === reader.byteLength) {\n        return true;\n    }\n    const solid = [115, 111, 108, 105, 100];\n    for (var i = 0; i < 5; i++) {\n        if (solid[i] !== reader.getUint8(i, false)) {\n            return true;\n        }\n    }\n    return false;\n}\n\nfunction parseBinary(plugin, data, modelNode, options) {\n    const reader = new DataView(data);\n    const faces = reader.getUint32(80, true);\n    let r;\n    let g;\n    let b;\n    let hasColors = false;\n    let colors;\n    let defaultR;\n    let defaultG;\n    let defaultB;\n    let lastR = null;\n    let lastG = null;\n    let lastB = null;\n    let newMesh = false;\n    for (let index = 0; index < 80 - 10; index++) {\n        if ((reader.getUint32(index, false) === 0x434F4C4F /*COLO*/) &&\n            (reader.getUint8(index + 4) === 0x52 /*'R'*/) &&\n            (reader.getUint8(index + 5) === 0x3D /*'='*/)) {\n            hasColors = true;\n            colors = [];\n            defaultR = reader.getUint8(index + 6) / 255;\n            defaultG = reader.getUint8(index + 7) / 255;\n            defaultB = reader.getUint8(index + 8) / 255;\n            reader.getUint8(index + 9) / 255;\n        }\n    }\n    const material = new MetallicMaterial(modelNode, { // Share material with all meshes\n        roughness: 0.5\n    });\n    // var material = new PhongMaterial(modelNode, { // Share material with all meshes\n    //     diffuse: [0.4, 0.4, 0.4],\n    //     reflectivity: 1,\n    //     specular: [0.5, 0.5, 1.0]\n    // });\n    let dataOffset = 84;\n    let faceLength = 12 * 4 + 2;\n    let positions = [];\n    let normals = [];\n    let splitMeshes = options.splitMeshes;\n    for (let face = 0; face < faces; face++) {\n        let start = dataOffset + face * faceLength;\n        let normalX = reader.getFloat32(start, true);\n        let normalY = reader.getFloat32(start + 4, true);\n        let normalZ = reader.getFloat32(start + 8, true);\n        if (hasColors) {\n            let packedColor = reader.getUint16(start + 48, true);\n            if ((packedColor & 0x8000) === 0) {\n                r = (packedColor & 0x1F) / 31;\n                g = ((packedColor >> 5) & 0x1F) / 31;\n                b = ((packedColor >> 10) & 0x1F) / 31;\n            } else {\n                r = defaultR;\n                g = defaultG;\n                b = defaultB;\n            }\n            if (splitMeshes && r !== lastR || g !== lastG || b !== lastB) {\n                if (lastR !== null) {\n                    newMesh = true;\n                }\n                lastR = r;\n                lastG = g;\n                lastB = b;\n            }\n        }\n        for (let i = 1; i <= 3; i++) {\n            let vertexstart = start + i * 12;\n            positions.push(reader.getFloat32(vertexstart, true));\n            positions.push(reader.getFloat32(vertexstart + 4, true));\n            positions.push(reader.getFloat32(vertexstart + 8, true));\n            normals.push(normalX, normalY, normalZ);\n            if (hasColors) {\n                colors.push(r, g, b, 1); // TODO: handle alpha\n            }\n        }\n        if (splitMeshes && newMesh) {\n            addMesh(modelNode, positions, normals, colors, material, options);\n            positions = [];\n            normals = [];\n            colors = colors ? [] : null;\n            newMesh = false;\n        }\n    }\n    if (positions.length > 0) {\n        addMesh(modelNode, positions, normals, colors, material, options);\n    }\n}\n\nfunction parseASCII(plugin, data, modelNode, options) {\n    const faceRegex = /facet([\\s\\S]*?)endfacet/g;\n    let faceCounter = 0;\n    const floatRegex = /[\\s]+([+-]?(?:\\d+.\\d+|\\d+.|\\d+|.\\d+)(?:[eE][+-]?\\d+)?)/.source;\n    const vertexRegex = new RegExp('vertex' + floatRegex + floatRegex + floatRegex, 'g');\n    const normalRegex = new RegExp('normal' + floatRegex + floatRegex + floatRegex, 'g');\n    const positions = [];\n    const normals = [];\n    const colors = null;\n    let normalx;\n    let normaly;\n    let normalz;\n    let result;\n    let verticesPerFace;\n    let normalsPerFace;\n    let text;\n    while ((result = faceRegex.exec(data)) !== null) {\n        verticesPerFace = 0;\n        normalsPerFace = 0;\n        text = result[0];\n        while ((result = normalRegex.exec(text)) !== null) {\n            normalx = parseFloat(result[1]);\n            normaly = parseFloat(result[2]);\n            normalz = parseFloat(result[3]);\n            normalsPerFace++;\n        }\n        while ((result = vertexRegex.exec(text)) !== null) {\n            positions.push(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]));\n            normals.push(normalx, normaly, normalz);\n            verticesPerFace++;\n        }\n        if (normalsPerFace !== 1) {\n            plugin.error(\"Error in normal of face \" + faceCounter);\n        }\n        if (verticesPerFace !== 3) {\n            plugin.error(\"Error in positions of face \" + faceCounter);\n        }\n        faceCounter++;\n    }\n    const material = new MetallicMaterial(modelNode, {\n        roughness: 0.5\n    });\n    // var material = new PhongMaterial(modelNode, {\n    //     diffuse: [0.4, 0.4, 0.4],\n    //     reflectivity: 1,\n    //     specular: [0.5, 0.5, 1.0]\n    // });\n    addMesh(modelNode, positions, normals, colors, material, options);\n}\n\nfunction addMesh(modelNode, positions, normals, colors, material, options) {\n\n    const indices = new Int32Array(positions.length / 3);\n    for (let ni = 0, len = indices.length; ni < len; ni++) {\n        indices[ni] = ni;\n    }\n\n    normals = normals && normals.length > 0 ? normals : null;\n    colors = colors && colors.length > 0 ? colors : null;\n\n    if (options.smoothNormals) {\n        math.faceToVertexNormals(positions, normals, options);\n    }\n\n    const origin = tempVec3a$1;\n\n    worldToRTCPositions(positions, positions, origin);\n\n    const geometry = new ReadableGeometry(modelNode, {\n        primitive: \"triangles\",\n        positions: positions,\n        normals: normals,\n        colors: colors,\n        indices: indices\n    });\n\n    const mesh = new Mesh(modelNode, {\n        origin: (origin[0] !== 0 || origin[1] !== 0 || origin[2] !== 0) ? origin : null,\n        geometry: geometry,\n        material: material,\n        edges: options.edges\n    });\n\n    modelNode.addChild(mesh);\n}\n\nfunction ensureString(buffer) {\n    if (typeof buffer !== 'string') {\n        return decodeText(new Uint8Array(buffer));\n    }\n    return buffer;\n}\n\nfunction ensureBinary(buffer) {\n    if (typeof buffer === 'string') {\n        const arrayBuffer = new Uint8Array(buffer.length);\n        for (let i = 0; i < buffer.length; i++) {\n            arrayBuffer[i] = buffer.charCodeAt(i) & 0xff; // implicitly assumes little-endian\n        }\n        return arrayBuffer.buffer || arrayBuffer;\n    } else {\n        return buffer;\n    }\n}\n\nfunction decodeText(array) {\n    if (typeof TextDecoder !== 'undefined') {\n        return new TextDecoder().decode(array);\n    }\n    let s = '';\n    for (let i = 0, il = array.length; i < il; i++) {\n        s += String.fromCharCode(array[i]); // Implicitly assumes little-endian.\n    }\n    return decodeURIComponent(escape(s));\n}\n\n/**\n * {@link Viewer} plugin that loads models from <a href=\"https://en.wikipedia.org/wiki/STL_(file_format)\">STL</a> files.\n *\n * ## Overview\n *\n * * Creates an {@link Entity} representing each model it loads, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.\n * * Creates an {@link Entity} for each object within the model, which will have {@link Entity#isObject} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.\n * * When loading, can set the World-space position, scale and rotation of each model within World space, along with initial properties for all the model's {@link Entity}s.\n * * Supports both binary and ASCII formats.\n * * Supports double-precision vertex positions.\n * * Supports custom data source configuration.\n *\n * ## Smoothing STL Normals\n *\n * STL models are normally flat-shaded, however providing a ````smoothNormals```` parameter when loading gives a smooth\n * appearance. Triangles in STL are disjoint, where each triangle has its own separate vertex positions, normals and\n * (optionally) colors. This means that you can have gaps between triangles in an STL model. Normals for each triangle\n * are perpendicular to the triangle's surface, which gives the model a faceted appearance by default.\n *\n * The ```smoothNormals``` parameter causes the plugin to recalculate the STL normals, so that each normal's direction is\n * the average of the orientations of the triangles adjacent to its vertex. When smoothing, each vertex normal is set to\n * the average of the orientations of all other triangles that have a vertex at the same position, excluding those triangles\n * whose direction deviates from the direction of the vertice's triangle by a threshold given in\n * the ````smoothNormalsAngleThreshold```` loading parameter. This makes smoothing robust for hard edges.\n *\n * ## Creating Entities for Objects\n *\n * An STL model is normally a single mesh, however providing a ````splitMeshes```` parameter when loading\n * will create a separate object {@link Entity} for each group of faces that share the same vertex colors. This option\n * only works with binary STL files.\n *\n * See the {@link STLLoaderPlugin#load} method for more info on loading options.\n *\n * ## Usage\n *\n * In the example below, we'll use an STLLoaderPlugin to load an STL model of a spur gear. When the model has loaded,\n * we'll use the {@link CameraFlightAnimation} to fly the {@link Camera} to look at boundary of the model. We'll\n * then get the model's {@link Entity} from the {@link Scene} and highlight the whole model.\n *\n *  * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_STL_SpurGear)]\n *\n * ````javascript\n * // Create a xeokit Viewer\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * // Add an STLLoaderPlugin to the Viewer\n * var plugin = new STLLoaderPlugin(viewer);\n *\n * // Load the STL model\n * var model = plugin.load({ // Model is an Entity\n *      id: \"myModel\",\n *      src: \"./models/stl/binary/spurGear.stl\",\n *      scale: [0.1, 0.1, 0.1],\n *      rotate: [90, 0, 0],\n *      translate: [100,0,0],\n *      edges: true,\n *      smoothNormals: true,                // Default\n *      smoothNormalsAngleThreshold: 20,    // Default\n *      splitMeshes: true                   // Default\n * });\n *\n * // When the model has loaded, fit it to view\n * model.on(\"loaded\", function() { // Model is an Entity\n *      viewer.cameraFlight.flyTo(model);\n * });\n *\n * // Find the model Entity by ID\n * model = viewer.scene.models[\"myModel\"];\n *\n * // Update properties of the model Entity\n * model.highlight = [1,0,0];\n *\n * // Destroy the model Entity\n * model.destroy();\n * ````\n *\n * ## Loading from a Pre-Loaded STL File\n *\n * If we already have our STL file in memory (perhaps pre-loaded, or even generated in-client), then we can just pass that\n * file data straight into the {@link STLLoaderPlugin#load} method. In the example below, to show how it's done, we'll pre-load\n * our STL file data, then pass it straight into that method.\n *\n *  * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_STL_dataAsParam)]\n *\n * ````javascript\n * loadSTL(\"./models/stl/binary/spurGear.stl\", (stlData) =>{\n *\n *      const model = stlLoader.load({\n *          id: \"myModel\",\n *          stl: stlData,\n *          smoothNormals: true\n *      });\n *\n *      model.on(\"loaded\", () => {\n *          viewer.cameraFlight.jumpTo(model);\n *          viewer.scene.on(\"tick\", () => {\n *              viewer.camera.orbitYaw(0.4);\n *          })\n *      });\n *  })\n *\n * function loadSTL(src, ok, error) {\n *     const request = new XMLHttpRequest();\n *     request.overrideMimeType(\"application/json\");\n *     request.open('GET', src, true);\n *     request.responseType = 'arraybuffer';\n *     request.onreadystatechange = function () {\n *         if (request.readyState === 4) {\n *             if (request.status === 200) {\n *                 ok(request.response);\n *             } else if (error) {\n *                     error(request.statusText);\n *             }\n *         }\n *     };\n *     request.send(null);\n * }\n *````\n *\n * ## Configuring a Custom Data Source\n *\n * In the example below, we'll create the STLLoaderPlugin again, this time configuring it with a\n * custom data source object, through which it can load STL files. For this example, our data source just loads\n * them via HTTP, for simplicity. Once we've created the STLLoaderPlugin, we'll load our STL file as before.\n *\n *  * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_STL_dataSource)]\n *\n * ````javascript\n * // Our custom STL data access strategy - implementation happens to be the same as STLDefaultDataSource\n *\n * class MyDataSource {\n *      getSTL(src, ok, error) {\n *          const request = new XMLHttpRequest();\n *          request.overrideMimeType(\"application/json\");\n *          request.open('GET', src, true);\n *          request.responseType = 'arraybuffer';\n *          request.onreadystatechange = function () {\n *              if (request.readyState === 4) {\n *                  if (request.status === 200) {\n *                      ok(request.response);\n *                  } else {\n *                      error(request.statusText);\n *                  }\n *              }\n *          };\n *          request.send(null);\n *      }\n *  }\n *\n * const stlLoader = new STLLoaderPlugin(viewer, {\n *      dataSource: new MyDataSource()\n *  });\n *\n * // Load the STL model as before\n * var model = plugin.load({\n *      id: \"myModel\",\n *      src: \"./models/stl/binary/spurGear.stl\",\n *      scale: [0.1, 0.1, 0.1],\n *      rotate: [90, 0, 0],\n *      translate: [100,0,0],\n *      edges: true,\n *      smoothNormals: true,                // Default\n *      smoothNormalsAngleThreshold: 20,    // Default\n *      splitMeshes: true                   // Default\n * });\n *\n * //...\n *````\n *\n * @class STLLoaderPlugin\n */\nclass STLLoaderPlugin extends Plugin {\n\n    /**\n     * @constructor\n     *\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} [cfg]  Plugin configuration.\n     * @param {String} [cfg.id=\"STLLoader\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {Object} [cfg.dataSource] A custom data source through which the STLLoaderPlugin can load STL files. Defaults to an instance of {@link STLDefaultDataSource}, which loads over HTTP.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"STLLoader\", viewer, cfg);\n\n        /**\n         * @private\n         */\n        this._sceneGraphLoader = new STLSceneGraphLoader();\n\n        this.dataSource = cfg.dataSource;\n    }\n\n    /**\n     * Sets a custom data source through which the STLLoaderPlugin can load STL files.\n     *\n     * Default value is {@link STLDefaultDataSource}, which loads via an XMLHttpRequest.\n     *\n     * @type {Object}\n     */\n    set dataSource(value) {\n        this._dataSource = value || new STLDefaultDataSource();\n    }\n\n    /**\n     * Gets the custom data source through which the STLLoaderPlugin can load STL files.\n     *\n     * Default value is {@link STLDefaultDataSource}, which loads via an XMLHttpRequest.\n     *\n     * @type {Object}\n     */\n    get dataSource() {\n        return this._dataSource;\n    }\n\n    /**\n     * Loads an STL model from a file into this STLLoaderPlugin's {@link Viewer}.\n     *\n     * @param {*} params Loading parameters.\n     * @param {String} params.id ID to assign to the model's root {@link Entity}, unique among all components in the Viewer's {@link Scene}.\n     * @param {String} [params.src] Path to an STL file. Overrides the ````stl```` parameter.\n     * @param {String} [params.stl] Contents of an STL file, either binary of ASCII. Overridden by the ````src```` parameter.\n     * @param {Boolean} [params.edges=false] Whether or not to renders the model with edges emphasized.\n     * @param {Number[]} [params.origin=[0,0,0]] The model's World-space double-precision 3D origin. Use this to position the model within xeokit's World coordinate system, using double-precision coordinates.\n     * @param {Number[]} [params.position=[0,0,0]] The model single-precision 3D position, relative to the ````origin```` parameter.\n     * @param {Number[]} [params.scale=[1,1,1]] The model's scale.\n     * @param {Number[]} [params.rotation=[0,0,0]] The model's orientation, given as Euler angles in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [params.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] The model's world transform matrix. Overrides the position, scale and rotation parameters. Relative to ````origin````.\n     * @param {Boolean} [params.backfaces=false] When true, allows visible backfaces, wherever specified in the STL.  When false, ignores backfaces.\n     * @param {Boolean} [params.smoothNormals=true] When true, automatically converts face-oriented normals to vertex normals for a smooth appearance.\n     * @param {Number} [params.smoothNormalsAngleThreshold=20] When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n     * @param {Number} [params.edgeThreshold=20] When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n     * @param {Boolean} [params.splitMeshes=true] When true, creates a separate {@link Mesh} for each group of faces that share the same vertex colors. Only works with binary STL.\n     * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}\n     */\n    load(params) {\n\n        if (params.id && this.viewer.scene.components[params.id]) {\n            this.error(\"Component with this ID already exists in viewer: \" + params.id + \" - will autogenerate this ID\");\n            delete params.id;\n        }\n\n        const modelNode = new Node$1(this.viewer.scene, utils.apply(params, {\n            isModel: true\n        }));\n\n        const src = params.src;\n        const stl = params.stl;\n\n        if (!src && !stl) {\n            this.error(\"load() param expected: either 'src' or 'stl'\");\n            return modelNode;\n        }\n\n        if (src) {\n            this._sceneGraphLoader.load(this, modelNode, src, params);\n        } else {\n            this._sceneGraphLoader.parse(this, modelNode, stl, params);\n        }\n\n        return modelNode;\n    }\n}\n\n/**\n * @desc A {@link TreeViewPlugin} render class.\n * \n */\nclass RenderService {\n\n  /**\n  * @constructor\n  *\n  * @param {HTMLElement} treeViewContainer Container element for the tree which uses this render service.\n  */\n  constructor(treeViewContainer) {\n    this._treeViewContainer = treeViewContainer;\n  }\n\n  /*\n  * Creates the root node of the tree.\n  * @return {HTMLElement} The root node of the tree.\n  */\n  createRootNode() {\n    return document.createElement('ul')\n  }\n\n  /*\n  * Creates node of the tree.\n  * @param {Object} node The node to create.\n\n  * @return {HTMLElement} The html element for the node.\n  */\n  createNodeElement(node, expandHandler, checkHandler, contextmenuHandler, titleClickHandler) {\n    const nodeElement = document.createElement('li');\n    nodeElement.id = node.nodeId;\n\n    if (node.xrayed) {\n        nodeElement.classList.add('xrayed-node');\n    }\n    \n    if (node.children.length > 0) {\n        const switchElement = document.createElement('a');\n        switchElement.href = '#';\n        switchElement.id = `switch-${node.nodeId}`;\n        switchElement.textContent = '+';\n        switchElement.classList.add('plus');\n        if (expandHandler) switchElement.addEventListener('click', expandHandler);\n        nodeElement.appendChild(switchElement);\n    }\n    \n    const checkbox = document.createElement('input');\n    checkbox.id = `checkbox-${node.nodeId}`;\n    checkbox.type = \"checkbox\";\n    checkbox.checked = node.checked;\n    checkbox.style[\"pointer-events\"] = \"all\";\n    if (checkHandler) checkbox.addEventListener(\"change\", checkHandler);\n    nodeElement.appendChild(checkbox);\n    \n    const span = document.createElement('span');\n    span.textContent = node.title;\n    nodeElement.appendChild(span);\n\n    if (contextmenuHandler) {\n      addContextMenuListener(span, contextmenuHandler);\n    }\n\n    if (titleClickHandler) {\n      span.onclick = titleClickHandler;\n    }\n\n    return nodeElement;\n  }\n\n  createDisabledNodeElement(rootName) {\n    const li = document.createElement('li');\n\n    const switchElement = document.createElement('a');\n    switchElement.href = '#';\n    switchElement.textContent = '!';\n    switchElement.classList.add('warn');\n    switchElement.classList.add('warning');\n    li.appendChild(switchElement);\n    \n    const span = document.createElement('span');\n    span.textContent = rootName;\n    li.appendChild(span);\n\n    return li;\n  }\n\n  addChildren(element, nodes) {\n    const ul = document.createElement('ul');\n    nodes.forEach((nodeElement) => {\n      ul.appendChild(nodeElement);\n    });\n\n    element.parentElement.appendChild(ul);\n  }\n\n  expand(element, expandHandler, collapseHandler) {\n    element.classList.remove('plus');\n    element.classList.add('minus');\n    element.textContent = '-';\n    element.removeEventListener('click', expandHandler);\n    element.addEventListener('click', collapseHandler);\n  }\n\n  collapse(element, expandHandler, collapseHandler) {\n    if (!element) {\n      return;\n    }\n    const parent = element.parentElement;\n    if (!parent) {\n        return;\n    }\n    const ul = parent.querySelector('ul');\n    if (!ul) {\n        return;\n    }\n    parent.removeChild(ul);\n    element.classList.remove('minus');\n    element.classList.add('plus');\n    element.textContent = '+';\n    element.removeEventListener('click', collapseHandler);\n    element.addEventListener('click', expandHandler);\n  }\n\n  isExpanded(element) {\n    const parentElement = element.parentElement;\n    return parentElement.getElementsByTagName('li')[0] !== undefined;\n  }\n\n  getId(element) {\n    const parentElement = element.parentElement;\n    return parentElement.id;\n  }\n\n  getIdFromCheckbox(element) {\n    return element.id.replace('checkbox-', '');\n  }\n\n  getSwitchElement(nodeId) {\n    return this._treeViewContainer.querySelector(`[id=\"switch-${nodeId}\"]`);\n  }\n\n  isChecked(element) {\n    return element.checked;\n  }\n\n  setCheckbox(nodeId, checked, indeterminate = false) {\n    const checkbox = this._treeViewContainer.querySelector(`[id=\"checkbox-${nodeId}\"]`);\n    if (checkbox) {\n      if (checked !== checkbox.checked) {\n        checkbox.checked = checked;\n      }\n      if (indeterminate !== checkbox.indeterminate) {\n        checkbox.indeterminate = indeterminate;\n        if (indeterminate) {\n          checkbox.checked = false;\n        }\n      }\n    }\n  }\n\n  setXRayed(nodeId, xrayed) {\n    const treeNode = this._treeViewContainer.querySelector(`[id=\"${nodeId}\"]`);\n    if (treeNode) {\n      if (xrayed) {\n        treeNode.classList.add('xrayed-node');\n      } else {\n        treeNode.classList.remove('xrayed-node');\n      }\n    }\n  }\n\n  setHighlighted(nodeId, highlighted) { \n    const treeNode = this._treeViewContainer.querySelector(`[id=\"${nodeId}\"]`);\n    if (treeNode) {\n      if (highlighted) {\n        treeNode.scrollIntoView({block: \"center\"});\n        treeNode.classList.add('highlighted-node');\n      } else {\n        treeNode.classList.remove('highlighted-node');\n      }\n    }\n  }\n}\n\nconst treeViews = [];\n\n/**\n * @desc A {@link Viewer} plugin that provides an HTML tree view to navigate the IFC elements in models.\n * <br>\n *\n * <a href=\"https://xeokit.github.io/xeokit-sdk/examples/index.html#BIMOffline_XKT_WestRiverSideHospital\" style=\"border: 1px solid black;\"><img src=\"http://xeokit.io/img/docs/TreeViewPlugin/TreeViewPlugin.png\"></a>\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#BIMOffline_XKT_WestRiverSideHospital)]\n *\n * ## Overview\n *\n * * A fast HTML tree view, with zero external dependencies, that works with huge numbers of objects.\n * * Each tree node has a checkbox to control the visibility of its object.\n * * Has three hierarchy modes: \"containment\", \"types\" and \"storeys\".\n * * Automatically contains all models (that have metadata) that are currently in the {@link Scene}.\n * * Sorts tree nodes by default - spatially, from top-to-bottom for ````IfcBuildingStorey```` nodes, and alphanumerically for other nodes.\n * * Allows custom CSS styling.\n * * Use {@link ContextMenu} to create a context menu for the tree nodes.\n *\n * ## Credits\n *\n * TreeViewPlugin is based on techniques described in [*Super Fast Tree View in JavaScript*](https://chrissmith.xyz/super-fast-tree-view-in-javascript/) by [Chris Smith](https://twitter.com/chris22smith).\n *\n * ## Usage\n *\n * In the example below, we'll add a TreeViewPlugin which, by default, will automatically show the structural\n * hierarchy of the IFC elements in each model we load.\n *\n * Then we'll use an {@link XKTLoaderPlugin} to load the Schependomlaan model from an\n * [.xkt file](https://github.com/xeokit/xeokit-sdk/tree/master/examples/models/xkt/schependomlaan).\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/navigation/#TreeViewPlugin_Containment)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, TreeViewPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * viewer.camera.eye = [-2.56, 8.38, 8.27];\n * viewer.camera.look = [13.44, 3.31, -14.83];\n * viewer.camera.up = [0.10, 0.98, -0.14];\n *\n * const treeView = new TreeViewPlugin(viewer, {\n *     containerElement: document.getElementById(\"myTreeViewContainer\")\n * });\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/xkt/Schependomlaan.xkt\",\n *     edges: true\n * });\n * ````\n *\n * ## Manually Adding Models\n *\n * Instead of adding models automatically, we can control which models appear in our TreeViewPlugin by adding them manually.\n *\n * In the next example, we'll configure the TreeViewPlugin to not add models automatically. Then, once the model\n * has loaded, we'll add it manually using {@link TreeViewPlugin#addModel}.\n *\n * ````javascript\n * const treeView = new TreeViewPlugin(viewer, {\n *      containerElement: document.getElementById(\"myTreeViewContainer\"),\n *      autoAddModels: false  // <<---------------- Don't auto-add models\n * });\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./models/xkt/Schependomlaan.xkt\",\n *     edges: true\n * });\n *\n * model.on(\"loaded\", () => {\n *      treeView.addModel(model.id);\n * });\n * ````\n *\n * Adding models manually also allows us to set some options for the model. For example, the ````rootName```` option allows us to provide a custom name for\n * the root node, which is sometimes desirable when the model's \"IfcProject\" element's name is not suitable:\n *\n * ````javascript\n * model.on(\"loaded\", () => {\n *      treeView.addModel(model.id, {\n *          rootName: \"Schependomlaan Model\"\n *      });\n * });\n * ````\n *\n * ## Initially Expanding the Hierarchy\n *\n * We can also configure TreeViewPlugin to initially expand each model's nodes to a given depth.\n *\n * Let's automatically expand the first three nodes from the root, for every model added:\n *\n * ````javascript\n * const treeView = new TreeViewPlugin(viewer, {\n *      containerElement: document.getElementById(\"myTreeViewContainer\"),\n *      autoExpandDepth: 3\n * });\n * ````\n *\n * ## Showing a Node by ID\n *\n * We can show a given node using its ID. This causes the TreeViewPlugin to collapse, then expand and scroll the node into view, then highlight the node.\n *\n * See the documentation for the {@link TreeViewPlugin#showNode} method for more information, including how to define a custom highlighted appearance for the node using CSS.\n *\n * Let's make the TreeViewPlugin show the node corresponding to whatever object {@link Entity} that we pick:\n *\n * ````javascript\n * viewer.cameraControl.on(\"picked\", function (e) {\n *     var objectId = e.entity.id;\n *     treeView.showNode(objectId);\n * });\n * ````\n *\n * This will de-highlight any node that was previously shown by this method.\n *\n * Note that this method only works if the picked {@link Entity} is an object that belongs to a model that's represented in the TreeViewPlugin.\n *\n * ## Customizing Appearance\n *\n * We can customize the appearance of our TreeViewPlugin by defining custom CSS for its HTML\n * elements. See our example's [source code](https://github.com/xeokit/xeokit-sdk/blob/master/examples/BIMOffline_XKT_Schependomlaan.html)\n * for an example of custom CSS rules.\n *\n * ## Model Hierarchies\n *\n * TreeViewPlugin has three hierarchies for organizing its nodes:\n *\n * * \"containment\" - organizes the tree nodes to indicate the containment hierarchy of the {@link MetaObject}s.\n * * \"types\" - groups nodes by their IFC types.\n * * \"storeys\" - groups nodes within their ````IfcBuildingStoreys````, and sub-groups them by their IFC types.\n *\n * <br>\n * The table below shows what the hierarchies look like:\n * <br>\n *\n * | 1. Containment Hierarchy | 2. Types Hierarchy | 3. Storeys Hierarchy |\n * |---|---|---|\n * | <img src=\"http://xeokit.io/img/docs/TreeViewPlugin/structureMode.png\"> | <img src=\"http://xeokit.io/img/docs/TreeViewPlugin/typesMode.png\"> | <img src=\"http://xeokit.io/img/docs/TreeViewPlugin/storeysMode.png\"> |\n * <br>\n *\n * Let's create a TreeViewPlugin that groups nodes by their building stories and IFC types:\n *\n * ````javascript\n * const treeView = new TreeViewPlugin(viewer, {\n *      containerElement: document.getElementById(\"myTreeViewContainer\"),\n *      hierarchy: \"stories\"\n * });\n * ````\n *\n * ## Sorting Nodes\n *\n * TreeViewPlugin sorts its tree nodes by default. For a \"storeys\" hierarchy, it orders ````IfcBuildingStorey```` nodes\n * spatially, with the node for the highest story at the top, down to the lowest at the bottom.\n *\n * For all the hierarchy types (\"containment\", \"classes\" and \"storeys\"), TreeViewPlugin sorts the other node types\n * alphanumerically on their titles.\n *\n * If for some reason you need to prevent sorting, create your TreeViewPlugin with the option disabled, like so:\n *\n * ````javascript\n * const treeView = new TreeViewPlugin(viewer, {\n *      containerElement: document.getElementById(\"myTreeViewContainer\"),\n *      hierarchy: \"stories\",\n *      sortNodes: false // <<------ Disable node sorting\n * });\n * ````\n *\n * Note that, for all hierarchy modes, node sorting is only done for each model at the time that it is added to the TreeViewPlugin, and will not\n * update dynamically if we later transform the {@link Entity}s corresponding to the nodes.\n *\n * ## Pruning empty nodes\n *\n * Sometimes a model contains subtrees of objects that don't have any geometry. These are models whose\n * {@link MetaModel} contains trees of {@link MetaObject}s that don't have any {@link Entity}s in the {@link Scene}.\n *\n * For these models, the tree view would contain nodes that don't do anything in the Scene when we interact with them,\n * which is undesirable.\n *\n * By default, TreeViewPlugin will not create nodes for those objects. However, we can override that behaviour if we want\n * to have nodes for those objects (perhaps for debugging the model):\n *\n * ````javascript\n * const treeView = new TreeViewPlugin(viewer, {\n *      containerElement: document.getElementById(\"myTreeViewContainer\"),\n *      hierarchy: \"stories\",\n *      pruneEmptyNodes: false // <<------ Create nodes for object subtrees without geometry\n * });\n * ````\n *\n * ## Context Menu\n *\n * TreeViewPlugin fires a \"contextmenu\" event whenever we right-click on a tree node.\n *\n * The event contains:\n *\n * * ````event```` - the original [contextmenu](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event) [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)\n * * ````viewer```` - the {@link Viewer}\n * * ````treeViewPlugin```` - the TreeViewPlugin\n * * ````treeViewNode```` - the {@link TreeViewNode} representing the tree node\n *<br><br>\n *\n * Let's use {@link ContextMenu} to show a simple context menu for the node we clicked.\n *\n * [[Run an example](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_Canvas_TreeViewPlugin_Custom)]\n *\n * ````javascript\n * import {ContextMenu} from \"../src/extras/ContextMenu/ContextMenu.js\";\n *\n * const treeViewContextMenu = new ContextMenu({\n *     items: [\n *         [\n *             [\n *                 {\n *                     title: \"Hide\",\n *                     doAction: function (context) {\n *                         context.treeViewPlugin.withNodeTree(context.treeViewNode, (treeViewNode) => {\n *                             if (treeViewNode.objectId) {\n *                                 const entity = context.viewer.scene.objects[treeViewNode.objectId];\n *                                 if (entity) {\n *                                     entity.visible = false;\n *                                 }\n *                             }\n *                         });\n *                     }\n *                 },\n *                 {\n *                     title: \"Hide all\",\n *                     doAction: function (context) {\n *                         context.viewer.scene.setObjectsVisible(context.viewer.scene.visibleObjectIds, false);\n *                     }\n *                 }\n *             ],\n *             [\n *                 {\n *                     title: \"Show\",\n *                     doAction: function (context) {\n *                         context.treeViewPlugin.withNodeTree(context.treeViewNode, (treeViewNode) => {\n *                             if (treeViewNode.objectId) {\n *                                 const entity = context.viewer.scene.objects[treeViewNode.objectId];\n *                                 if (entity) {\n *                                     entity.visible = true;\n *                                     entity.xrayed = false;\n *                                     entity.selected = false;\n *                                 }\n *                             }\n *                         });\n *                     }\n *                 },\n *                 {\n *                     title: \"Show all\",\n *                     doAction: function (context) {\n *                         const scene = context.viewer.scene;\n *                         scene.setObjectsVisible(scene.objectIds, true);\n *                         scene.setObjectsXRayed(scene.xrayedObjectIds, false);\n *                         scene.setObjectsSelected(scene.selectedObjectIds, false);\n *                     }\n *                 }\n *             ]\n *         ]\n *     ]\n * });\n *\n * treeView.on(\"contextmenu\", (e) => {\n *\n *     const event = e.event;                           // MouseEvent\n *     const viewer = e.viewer;                         // Viewer\n *     const treeViewPlugin = e.treeViewPlugin;         // TreeViewPlugin\n *     const treeViewNode = e.treeViewNode;             // TreeViewNode\n *\n *     treeViewContextMenu.show(e.event.pageX, e.event.pageY);\n *\n *     treeViewContextMenu.context = {\n *         viewer: e.viewer,\n *         treeViewPlugin: e.treeViewPlugin,\n *         treeViewNode: e.treeViewNode\n *     };\n * });\n * ````\n *\n * ## Clicking Node Titles\n *\n * TreeViewPlugin fires a \"nodeTitleClicked\" event whenever we left-click on a tree node.\n *\n * Like the \"contextmenu\" event, this event contains:\n *\n * * ````event```` - the original [click](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event) [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)\n * * ````viewer```` - the {@link Viewer}\n * * ````treeViewPlugin```` - the TreeViewPlugin\n * * ````treeViewNode```` - the {@link TreeViewNode} representing the tree node\n *<br><br>\n *\n * Let's register a callback to isolate and fit-to-view the {@link Entity}(s) represented by the node. This callback is\n * going to X-ray all the other Entitys, fly the camera to fit the Entity(s) for the clicked node, then hide the other Entitys.\n *\n * [[Run an example](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_Canvas_TreeViewPlugin_Custom)]\n *\n * ````javascript\n * treeView.on(\"nodeTitleClicked\", (e) => {\n *     const scene = viewer.scene;\n *     const objectIds = [];\n *     e.treeViewPlugin.withNodeTree(e.treeViewNode, (treeViewNode) => {\n *         if (treeViewNode.objectId) {\n *             objectIds.push(treeViewNode.objectId);\n *         }\n *     });\n *     scene.setObjectsXRayed(scene.objectIds, true);\n *     scene.setObjectsVisible(scene.objectIds, true);\n *     scene.setObjectsXRayed(objectIds, false);\n *     viewer.cameraFlight.flyTo({\n *         aabb: scene.getAABB(objectIds),\n *         duration: 0.5\n *     }, () => {\n *         setTimeout(function () {\n *             scene.setObjectsVisible(scene.xrayedObjectIds, false);\n *             scene.setObjectsXRayed(scene.xrayedObjectIds, false);\n *         }, 500);\n *     });\n * });\n * ````\n *\n * To make the cursor change to a pointer when we hover over the node titles, and also to make the titles change to blue, we'll also define this CSS for the ````<span>```` elements\n * that represent the titles of our TreeViewPlugin nodes:\n *\n * ````css\n * #treeViewContainer ul li span:hover {\n *      color: blue;\n *      cursor: pointer;\n * }\n * ````\n *\n * @class TreeViewPlugin\n */\nclass TreeViewPlugin extends Plugin {\n\n    /**\n     * @constructor\n     *\n     * @param {Viewer} viewer The Viewer.\n     * @param {*} cfg Plugin configuration.\n     * @param {String} [cfg.containerElementId]  ID of an existing HTML element to contain the TreeViewPlugin - either this or containerElement is mandatory. When both values are given, the element reference is always preferred to the ID.\n     * @param {HTMLElement} cfg.containerElement DOM element to contain the TreeViewPlugin.\n     * @param {Boolean} [cfg.autoAddModels=true] When ````true```` (default), will automatically add each model as it's created. Set this ````false```` if you want to manually add models using {@link TreeViewPlugin#addModel} instead.\n     * @param {Number} [cfg.autoExpandDepth] Optional depth to which to initially expand the tree.\n     * @param {String} [cfg.hierarchy=\"containment\"] How to organize the tree nodes: \"containment\", \"storeys\" or \"types\". See the class documentation for details.\n     * @param {Boolean} [cfg.sortNodes=true] When true, will sort the children of each node. For a \"storeys\" hierarchy, the\n     * ````IfcBuildingStorey```` nodes will be ordered spatially, from the highest storey down to the lowest, on the\n     * vertical World axis. For all hierarchy types, other node types will be ordered in the ascending alphanumeric order of their titles.\n     * @param {Boolean} [cfg.pruneEmptyNodes=true] When true, will not contain nodes that don't have content in the {@link Scene}. These are nodes whose {@link MetaObject}s don't have {@link Entity}s.\n     * @param {RenderService} [cfg.renderService] Optional {@link RenderService} to use. Defaults to the {@link TreeViewPlugin}'s default {@link RenderService}.\n     * @param {Boolean} [cfg.showIndeterminate=false] When true, will show indeterminate state for checkboxes when some but not all child nodes are checked\n     * @param {Boolean} [cfg.showProjectNode=false] When true, will show top level project node when hierarchy is set to \"storeys\"\n     * @param {Function} [cfg.elevationSortFunction] Optional function to replace the default elevation sort function. The function should take two nodes and return -1, 0 or 1. \n     * @param {Function} [cfg.defaultSortFunction] Optional function to replace the default sort function. The function should take two nodes and return -1, 0 or 1.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"TreeViewPlugin\", viewer);\n\n        /**\n         * Contains messages for any errors found while last rebuilding this TreeView.\n         * @type {String[]}\n         */\n        this.errors = [];\n\n        /**\n         * True if errors were found generating this TreeView.\n         * @type {boolean}\n         */\n        this.valid = true;\n\n        const containerElement = cfg.containerElement || document.getElementById(cfg.containerElementId);\n\n        if (!(containerElement instanceof HTMLElement)) {\n            this.error(\"Mandatory config expected: valid containerElementId or containerElement\");\n            return;\n        }\n\n        for (let i = 0; ; i++) {\n            if (!treeViews[i]) {\n                treeViews[i] = this;\n                this._index = i;\n                this._id = `tree-${i}`;\n                break;\n            }\n        }\n\n\n        this._containerElement = containerElement;\n        this._metaModels = {};\n        this._autoAddModels = (cfg.autoAddModels !== false);\n        this._autoExpandDepth = (cfg.autoExpandDepth || 0);\n        this._sortNodes = (cfg.sortNodes !== false);\n        this._viewer = viewer;\n        this._rootElement = null;\n        this._muteSceneEvents = false;\n        this._muteTreeEvents = false;\n        this._rootNodes = [];\n        this._objectNodes = {}; // Object ID -> Node\n        this._nodeNodes = {}; // Node ID -> Node\n        this._rootNames = {}; // Node ID -> Root name\n        this._sortNodes = cfg.sortNodes;\n        this._pruneEmptyNodes = cfg.pruneEmptyNodes;\n        this._showListItemElementId = null;\n        this._renderService = cfg.renderService || new RenderService(this._containerElement);\n        this._showIndeterminate = cfg.showIndeterminate ?? false;\n        this._showProjectNode = cfg.showProjectNode ?? false;\n        this._elevationSortFunction = cfg.elevationSortFunction ?? undefined;\n        this._defaultSortFunction = cfg.defaultSortFunction ?? undefined;\n\n        if (!this._renderService) {\n            throw new Error('TreeViewPlugin: no render service set');\n        }\n\n        this._containerElement.oncontextmenu = (e) => {\n            e.preventDefault();\n        };\n\n        this._onObjectVisibility = this._viewer.scene.on(\"objectVisibility\", (entity) => {\n            if (this._muteSceneEvents) {\n                return;\n            }\n            const objectId = entity.id;\n            const node = this._objectNodes[objectId];\n            if (!node) {\n                return; // Not in this tree\n            }\n            const visible = entity.visible;\n            const updated = (visible !== node.checked);\n            if (!updated) {\n                return;\n            }\n            this._muteTreeEvents = true;\n            node.checked = visible;\n            if (visible) {\n                node.numVisibleEntities++;\n            } else {\n                node.numVisibleEntities--;\n            }\n\n            this._renderService.setCheckbox(node.nodeId, visible);\n\n            let parent = node.parent;\n            while (parent) {\n                parent.checked = visible;\n                if (visible) {\n                    parent.numVisibleEntities++;\n                } else {\n                    parent.numVisibleEntities--;\n                }\n                const indeterminate = this._showIndeterminate \n                  && parent.numVisibleEntities > 0 \n                  && parent.numVisibleEntities < parent.numEntities;\n                parent.checked = parent.numVisibleEntities > 0;\n                this._renderService.setCheckbox(parent.nodeId, parent.checked, indeterminate);\n\n                parent = parent.parent;\n            }\n\n            this._muteTreeEvents = false;\n        });\n\n        this._onObjectXrayed = this._viewer.scene.on('objectXRayed', (entity) => {\n            if (this._muteSceneEvents) {\n                return;\n            }\n            const objectId = entity.id;\n            const node = this._objectNodes[objectId];\n            if (!node) {\n                return; // Not in this tree\n            }\n            this._muteTreeEvents = true;\n            const xrayed = entity.xrayed;\n            const updated = (xrayed !== node.xrayed);\n            if (!updated) {\n                return;\n            }\n            node.xrayed = xrayed;\n\n            this._renderService.setXRayed(node.nodeId, xrayed);\n            this._muteTreeEvents = false;\n        });\n\n        this._switchExpandHandler = (event) => {\n            event.preventDefault();\n            event.stopPropagation();\n            const switchElement = event.target;\n            this._expandSwitchElement(switchElement);\n        };\n\n        this._switchCollapseHandler = (event) => {\n            event.preventDefault();\n            event.stopPropagation();\n            const switchElement = event.target;\n            this._collapseSwitchElement(switchElement);\n        };\n\n        this._checkboxChangeHandler = (event) => {\n            if (this._muteTreeEvents) {\n                return;\n            }\n            this._muteSceneEvents = true;\n            const checkbox = event.target;\n            const visible = this._renderService.isChecked(checkbox);\n            const nodeId = this._renderService.getIdFromCheckbox(checkbox);\n\n            const checkedNode = this._nodeNodes[nodeId];\n            const objects = this._viewer.scene.objects;\n            let numUpdated = 0;\n            \n            this._withNodeTree(checkedNode, (node) => {\n                const objectId = node.objectId;\n                const entity = objects[objectId];\n                const isLeaf = (node.children.length === 0);\n                node.numVisibleEntities = visible ? node.numEntities : 0;\n                if (isLeaf && (visible !== node.checked)) {\n                    numUpdated++;\n                }\n                node.checked = visible;\n\n                this._renderService.setCheckbox(node.nodeId, visible);\n                \n                if (entity) {\n                    entity.visible = visible;\n                }\n            });\n\n            let parent = checkedNode.parent;\n            while (parent) {\n                \n                if (visible) {\n                    parent.numVisibleEntities += numUpdated;\n                } else {\n                    parent.numVisibleEntities -= numUpdated;\n                }\n                const indeterminate = this._showIndeterminate \n                  && parent.numVisibleEntities > 0 \n                  && parent.numVisibleEntities < parent.numEntities;\n                parent.checked = parent.numVisibleEntities > 0;\n                this._renderService.setCheckbox(parent.nodeId, parent.checked, indeterminate);\n                \n                parent = parent.parent;\n            }\n            this._muteSceneEvents = false;\n        };\n\n        this._hierarchy = cfg.hierarchy || \"containment\";\n        this._autoExpandDepth = cfg.autoExpandDepth || 0;\n\n        if (this._autoAddModels) {\n            const modelIds = Object.keys(this.viewer.metaScene.metaModels);\n            for (let i = 0, len = modelIds.length; i < len; i++) {\n                const modelId = modelIds[i];\n                const metaModel = this.viewer.metaScene.metaModels[modelId];\n                if (metaModel.finalized) {\n                    this.addModel(modelId);\n                }\n            }\n            this.viewer.scene.on(\"modelLoaded\", (modelId) => {\n                if (this.viewer.metaScene.metaModels[modelId]) {\n                    this.addModel(modelId);\n                }\n            });\n        }\n\n        this.hierarchy = cfg.hierarchy;\n    }\n\n    /**\n     * Sets how the nodes are organized within this tree view.\n     *\n     * Accepted values are:\n     *\n     * * \"containment\" - organizes the nodes to indicate the containment hierarchy of the IFC objects.\n     * * \"types\" - groups the nodes within their IFC types.\n     * * \"storeys\" - groups the nodes within ````IfcBuildingStoreys```` and sub-groups them by their IFC types.\n     *\n     * <br>\n     * This can be updated dynamically.\n     *\n     * Default value is \"containment\".\n     *\n     * @type {String}\n     */\n    set hierarchy(hierarchy) {\n        hierarchy = hierarchy || \"containment\";\n        if (hierarchy !== \"containment\" && hierarchy !== \"storeys\" && hierarchy !== \"types\") {\n            this.error(\"Unsupported value for `hierarchy' - defaulting to 'containment'\");\n            hierarchy = \"containment\";\n        }\n        if (this._hierarchy === hierarchy) {\n            return;\n        }\n        this._hierarchy = hierarchy;\n        this._createNodes();\n    }\n\n    /**\n     * Gets how the nodes are organized within this tree view.\n     *\n     * @type {String}\n     */\n    get hierarchy() {\n        return this._hierarchy;\n    }\n\n    /**\n     * Adds a model to this tree view.\n     *\n     * The model will be automatically removed when destroyed.\n     *\n     * To automatically add each model as it's created, instead of manually calling this method each time,\n     * provide a ````autoAddModels: true```` to the TreeViewPlugin constructor.\n     *\n     * @param {String} modelId ID of a model {@link Entity} in {@link Scene#models}.\n     * @param {Object} [options] Options for model in the tree view.\n     * @param {String} [options.rootName] Optional display name for the root node. Ordinary, for \"containment\"\n     * and \"storeys\" hierarchy types, the tree would derive the root node name from the model's \"IfcProject\" element\n     * name. This option allows to override that name when it is not suitable as a display name.\n     */\n    addModel(modelId, options = {}) {\n        if (!this._containerElement) {\n            return;\n        }\n        const model = this.viewer.scene.models[modelId];\n        if (!model) {\n            throw \"Model not found: \" + modelId;\n        }\n        const metaModel = this.viewer.metaScene.metaModels[modelId];\n        if (!metaModel) {\n            this.error(\"MetaModel not found: \" + modelId);\n            return;\n        }\n        if (this._metaModels[modelId]) {\n            this.warn(\"Model already added: \" + modelId);\n            return;\n        }\n        this._metaModels[modelId] = metaModel;\n\n        if (options && options.rootName) {\n            this._rootNames[modelId] = options.rootName;\n        }\n        \n        model.on(\"destroyed\", () => {\n            this.removeModel(model.id);\n        });\n        this._createNodes();\n    }\n\n    /**\n     * Removes a model from this tree view.\n     *\n     * Does nothing if model not currently in tree view.\n     *\n     * @param {String} modelId ID of a model {@link Entity} in {@link Scene#models}.\n     */\n    removeModel(modelId) {\n        if (!this._containerElement) {\n            return;\n        }\n        const metaModel = this._metaModels[modelId];\n        if (!metaModel) {\n            return;\n        }\n\n        if (this._rootNames[modelId]) {\n            delete this._rootNames[modelId];\n        }\n\n        delete this._metaModels[modelId];\n        this._createNodes();\n    }\n\n    /**\n     * Highlights the tree view node that represents the given object {@link Entity}.\n     *\n     * This causes the tree view to collapse, then expand to reveal the node, then highlight the node.\n     *\n     * If a node is previously highlighted, de-highlights that node and collapses the tree first.\n     *\n     * Note that if the TreeViewPlugin was configured with ````pruneEmptyNodes: true```` (default configuration), then the\n     * node won't exist in the tree if it has no Entitys in the {@link Scene}. in that case, nothing will happen.\n     *\n     * Within the DOM, the node is represented by an ````<li>```` element. This method will add a ````.highlighted-node```` class to\n     * the element to make it appear highlighted, removing that class when de-highlighting it again. See the CSS rules\n     * in the TreeViewPlugin examples for an example of that class.\n     *\n     * @param {String} objectId ID of the {@link Entity}.\n     */\n    showNode(objectId) {\n        this.unShowNode();\n\n        const node = this._objectNodes[objectId];\n        if (!node) {\n            return; // Node may not exist for the given object if (this._pruneEmptyNodes == true)\n        }\n\n        this.collapse();\n\n        const nodeId = node.nodeId;\n\n        const switchElement = this._renderService.getSwitchElement(nodeId);\n        if (switchElement) {\n            this._expandSwitchElement(switchElement);\n            switchElement.scrollIntoView();\n            return true;\n        }\n        \n        const path = [];\n        path.unshift(node);\n        let parent = node.parent;\n        while (parent) {\n            path.unshift(parent);\n            parent = parent.parent;\n        }\n\n        for (let i = 0, len = path.length; i < len; i++) {\n            const switchElement = this._renderService.getSwitchElement(path[i].nodeId);\n            if (switchElement) {\n                this._expandSwitchElement(switchElement);\n            }\n        }\n\n        this._renderService.setHighlighted(nodeId, true);\n\n        this._showListItemElementId = nodeId;\n    }\n\n    /**\n     * De-highlights the node previously shown with {@link TreeViewPlugin#showNode}.\n     *\n     * Does nothing if no node is currently shown.\n     *\n     * If the node is currently scrolled into view, keeps the node in view.\n     */\n    unShowNode() {\n        if (!this._showListItemElementId) {\n            return;\n        }\n\n        this._renderService.setHighlighted(this._showListItemElementId, false);\n        \n        this._showListItemElementId = null;\n    }\n\n    /**\n     * Expands the tree to the given depth.\n     *\n     * Collapses the tree first.\n     *\n     * @param {Number} depth Depth to expand to.\n     */\n    expandToDepth(depth) {\n        this.collapse();\n        const expand = (node, countDepth) => {\n            if (countDepth === depth) {\n                return;\n            }\n\n            const switchElement = this._renderService.getSwitchElement(node.nodeId);\n            if (switchElement) {\n                this._expandSwitchElement(switchElement);\n                const childNodes = node.children;\n                for (var i = 0, len = childNodes.length; i < len; i++) {\n                    const childNode = childNodes[i];\n                    expand(childNode, countDepth + 1);\n                }\n            }\n        };\n        for (let i = 0, len = this._rootNodes.length; i < len; i++) {\n            const rootNode = this._rootNodes[i];\n            expand(rootNode, 0);\n        }\n    }\n\n    /**\n     * Closes all the nodes in the tree.\n     */\n    collapse() {\n        for (let i = 0, len = this._rootNodes.length; i < len; i++) {\n            const rootNode = this._rootNodes[i];\n            const nodeId = rootNode.nodeId;\n            this._collapseNode(nodeId);\n        }\n    }\n\n    /**\n     * Iterates over a subtree of the tree view's {@link TreeViewNode}s, calling the given callback for each\n     * node in depth-first pre-order.\n     *\n     * @param {TreeViewNode} node Root of the subtree.\n     * @param {Function} callback Callback called at each {@link TreeViewNode}, with the TreeViewNode given as the argument.\n     */\n    withNodeTree(node, callback) {\n        callback(node);\n        const children = node.children;\n        if (!children) {\n            return;\n        }\n        for (let i = 0, len = children.length; i < len; i++) {\n            this.withNodeTree(children[i], callback);\n        }\n    }\n\n    /**\n     * Destroys this TreeViewPlugin.\n     */\n    destroy() {\n        if (!this._containerElement) {\n            return;\n        }\n        this._metaModels = {};\n        if (this._rootElement && !this._destroyed) {\n            this._rootElement.parentNode.removeChild(this._rootElement);\n            this._viewer.scene.off(this._onObjectVisibility);\n            this._destroyed = true;\n        }\n        delete treeViews[this._index];\n        super.destroy();\n    }\n\n    _createNodes() {\n        if (this._rootElement) {\n            this._rootElement.parentNode.removeChild(this._rootElement);\n            this._rootElement = null;\n        }\n\n        this._rootNodes = [];\n        this._objectNodes = {};\n        this._nodeNodes = {};\n        this._validate();\n        if (this.valid || (this._hierarchy !== \"storeys\")) {\n            this._createEnabledNodes();\n        } else {\n            this._createDisabledNodes();\n        }\n    }\n\n    _validate() {\n        this.errors = [];\n        switch (this._hierarchy) {\n            case \"storeys\":\n                this.valid = this._validateMetaModelForStoreysHierarchy();\n                break;\n            case \"types\":\n                this.valid = (this._rootNodes.length > 0);\n                break;\n            case \"containment\":\n            default:\n                this.valid = (this._rootNodes.length > 0);\n                break;\n        }\n        return this.valid;\n    }\n\n    _validateMetaModelForStoreysHierarchy(level = 0, ctx, buildingNode) {\n        // ctx = ctx || {\n        //     foundIFCBuildingStoreys: false\n        // };\n        // const metaObjectType = metaObject.type;\n        // const children = metaObject.children;\n        // if (metaObjectType === \"IfcBuilding\") {\n        //     buildingNode = true;\n        // } else if (metaObjectType === \"IfcBuildingStorey\") {\n        //     if (!buildingNode) {\n        //         errors.push(\"Can't build storeys hierarchy: IfcBuildingStorey found without parent IfcBuilding\");\n        //         return false;\n        //     }\n        //     ctx.foundIFCBuildingStoreys = true;\n        // }\n        // if (children) {\n        //     for (let i = 0, len = children.length; i < len; i++) {\n        //         const childMetaObject = children[i];\n        //         if (!this._validateMetaModelForStoreysHierarchy(childMetaObject, errors, level + 1, ctx, buildingNode)) {\n        //             return false;\n        //         }\n        //     }\n        // }\n        // if (level === 0) {\n        //     if (!ctx.foundIFCBuildingStoreys) {\n        //         // errors.push(\"Can't build storeys hierarchy: no IfcBuildingStoreys found\");\n        //     }\n        // }\n        return true;\n    }\n\n    _createEnabledNodes() {\n        if (this._pruneEmptyNodes) {\n            this._findEmptyNodes();\n        }\n        switch (this._hierarchy) {\n            case \"storeys\":\n                this._createStoreysNodes();\n                if (this._rootNodes.length === 0) {\n                    this.error(\"Failed to build storeys hierarchy\");\n                }\n                break;\n            case \"types\":\n                this._createTypesNodes();\n                break;\n            case \"containment\":\n            default:\n                this._createContainmentNodes();\n        }\n        if (this._sortNodes) {\n            this._doSortNodes();\n        }\n        this._synchNodesToEntities();\n        this._createTrees();\n        this.expandToDepth(this._autoExpandDepth);\n    }\n\n    _createDisabledNodes() {\n\n        const rootNode = this._renderService.createRootNode();\n        this._rootElement = rootNode;\n        this._containerElement.appendChild(rootNode);\n\n        const rootMetaObjects = this._viewer.metaScene.rootMetaObjects;\n\n        for (let objectId in rootMetaObjects) {\n            const rootMetaObject = rootMetaObjects[objectId];\n            const metaObjectType = rootMetaObject.type;\n            const metaObjectName = rootMetaObject.name;\n            const rootName = ((metaObjectName && metaObjectName !== \"\"\n                && metaObjectName !== \"Undefined\"\n                && metaObjectName !== \"Default\") ? metaObjectName : metaObjectType);\n\n            const childNode = this._renderService.createDisabledNodeElement(rootName);\n            rootNode.appendChild(childNode);\n        }\n    }\n\n\n    _findEmptyNodes() {\n        const rootMetaObjects = this._viewer.metaScene.rootMetaObjects;\n        for (let objectId in rootMetaObjects) {\n            this._findEmptyNodes2(rootMetaObjects[objectId]);\n        }\n    }\n\n    _findEmptyNodes2(metaObject, countEntities = 0) {\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const children = metaObject.children;\n        const objectId = metaObject.id;\n        const entity = scene.objects[objectId];\n        metaObject._countEntities = 0;\n        if (entity) {\n            metaObject._countEntities++;\n        }\n        if (children) {\n            for (let i = 0, len = children.length; i < len; i++) {\n                const childMetaObject = children[i];\n                childMetaObject._countEntities = this._findEmptyNodes2(childMetaObject);\n                metaObject._countEntities += childMetaObject._countEntities;\n            }\n        }\n        return metaObject._countEntities;\n    }\n\n    _createStoreysNodes() {\n        const rootMetaObjects = this._viewer.metaScene.rootMetaObjects;\n        for (let id in rootMetaObjects) {\n            this._createStoreysNodes2(rootMetaObjects[id], null, null, null, null);\n        }\n    }\n\n    _createStoreysNodes2(metaObject, projectNode, buildingNode, storeyNode, typeNodes) {\n        if (this._pruneEmptyNodes && (metaObject._countEntities === 0)) {\n            return;\n        }\n        const metaObjectType = metaObject.type;\n        const metaObjectName = metaObject.name;\n        const children = metaObject.children;\n        const objectId = metaObject.id;\n\n        if (this._showProjectNode && metaObjectType === 'IfcProject') {\n            projectNode = {\n                nodeId: `${this._id}-${objectId}`,\n                objectId,\n                title: (metaObject.metaModels.length === 0) ? metaObjectName : this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== \"\" && metaObjectName !== \"Undefined\" && metaObjectName !== \"Default\") ? metaObjectName : metaObjectType),\n                type: metaObjectType,\n                parent: null,\n                numEntities: 0,\n                numVisibleEntities: 0,\n                checked: false,\n                xrayed: false,\n                children: [],\n            };\n            this._rootNodes.push(projectNode);\n            this._objectNodes[projectNode.objectId] = projectNode;\n            this._nodeNodes[projectNode.nodeId] = projectNode;\n        } else if (metaObjectType === \"IfcBuilding\") {\n            buildingNode = {\n                nodeId: `${this._id}-${objectId}`,\n                objectId: objectId,\n                title: (metaObject.metaModels.length === 0) ? metaObjectName : this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== \"\" && metaObjectName !== \"Undefined\" && metaObjectName !== \"Default\") ? metaObjectName : metaObjectType),\n                type: metaObjectType,\n                parent: projectNode,\n                numEntities: 0,\n                numVisibleEntities: 0,\n                checked: false,\n                xrayed: false,\n                children: []\n            };\n            if (projectNode) {\n                projectNode.children.push(buildingNode);\n            } else {\n                this._rootNodes.push(buildingNode);\n            }\n            this._objectNodes[buildingNode.objectId] = buildingNode;\n            this._nodeNodes[buildingNode.nodeId] = buildingNode;\n        } else if (metaObjectType === \"IfcBuildingStorey\") {\n            if (!buildingNode) {\n                this.error(\"Failed to build storeys hierarchy for model - model does not have an IfcBuilding object, or is not an IFC model\");\n                return;\n            }\n            storeyNode = {\n                nodeId: `${this._id}-${objectId}`,\n                objectId: objectId,\n                title: (metaObjectName && metaObjectName !== \"\" && metaObjectName !== \"Undefined\" && metaObjectName !== \"Default\") ? metaObjectName : metaObjectType,\n                type: metaObjectType,\n                parent: buildingNode,\n                numEntities: 0,\n                numVisibleEntities: 0,\n                checked: false,\n                xrayed: false,\n                children: []\n            };\n            buildingNode.children.push(storeyNode);\n            this._objectNodes[storeyNode.objectId] = storeyNode;\n            this._nodeNodes[storeyNode.nodeId] = storeyNode;\n            typeNodes = {};\n        } else {\n            if (storeyNode) {\n                const objects = this._viewer.scene.objects;\n                const object = objects[objectId];\n                if (object) {\n                    typeNodes = typeNodes || {};\n                    let typeNode = typeNodes[metaObjectType];\n                    if (!typeNode) {\n                        typeNode = {\n                            nodeId: `${this._id}-${storeyNode.objectId}-${metaObjectType}`,\n                            objectId: `${storeyNode.objectId}-${metaObjectType}`,\n                            title: metaObjectType,\n                            type: metaObjectType,\n                            parent: storeyNode,\n                            numEntities: 0,\n                            numVisibleEntities: 0,\n                            checked: false,\n                            xrayed: false,\n                            children: []\n                        };\n                        storeyNode.children.push(typeNode);\n                        this._objectNodes[typeNode.objectId] = typeNode;\n                        this._nodeNodes[typeNode.nodeId] = typeNode;\n                        typeNodes[metaObjectType] = typeNode;\n                    }\n                    const node = {\n                        nodeId: `${this._id}-${objectId}`,\n                        objectId: objectId,\n                        title: (metaObjectName && metaObjectName !== \"\" && metaObjectName !== \"Undefined\" && metaObjectName !== \"Default\") ? metaObjectName : metaObjectType,\n                        type: metaObjectType,\n                        parent: typeNode,\n                        numEntities: 0,\n                        numVisibleEntities: 0,\n                        checked: false,\n                        xrayed: false,\n                        children: []\n                    };\n                    typeNode.children.push(node);\n                    this._objectNodes[node.objectId] = node;\n                    this._nodeNodes[node.nodeId] = node;\n                }\n            }\n        }\n        if (children) {\n            for (let i = 0, len = children.length; i < len; i++) {\n                const childMetaObject = children[i];\n                this._createStoreysNodes2(childMetaObject, projectNode, buildingNode, storeyNode, typeNodes);\n            }\n        }\n    }\n\n    _createTypesNodes() {\n        const rootMetaObjects = this._viewer.metaScene.rootMetaObjects;\n        for (let id in rootMetaObjects) {\n            this._createTypesNodes2(rootMetaObjects[id], null, null);\n        }\n    }\n\n    _createTypesNodes2(metaObject, rootNode, typeNodes) {\n        if (this._pruneEmptyNodes && (metaObject._countEntities === 0)) {\n            return;\n        }\n        const metaObjectType = metaObject.type;\n        const metaObjectName = metaObject.name;\n        const children = metaObject.children;\n        const objectId = metaObject.id;\n        if (!metaObject.parent) {\n            rootNode = {\n                nodeId: `${this._id}-${objectId}`,\n                objectId: objectId,\n                title: metaObject.metaModels.length === 0 ? metaObjectName : this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== \"\" && metaObjectName !== \"Undefined\" && metaObjectName !== \"Default\") ? metaObjectName : metaObjectType),\n                type: metaObjectType,\n                parent: null,\n                numEntities: 0,\n                numVisibleEntities: 0,\n                checked: false,\n                xrayed: false,\n                children: []\n            };\n            this._rootNodes.push(rootNode);\n            this._objectNodes[rootNode.objectId] = rootNode;\n            this._nodeNodes[rootNode.nodeId] = rootNode;\n            typeNodes = {};\n        } else {\n            if (rootNode) {\n                const objects = this._viewer.scene.objects;\n                const object = objects[objectId];\n                if (object) {\n                    let typeNode = typeNodes[metaObjectType];\n                    if (!typeNode) {\n                        typeNode = {\n                            nodeId: `${this._id}-${rootNode.objectId}-${metaObjectType}`,\n                            objectId: `${rootNode.objectId}-${metaObjectType}`,\n                            title: metaObjectType,\n                            type: metaObjectType,\n                            parent: rootNode,\n                            numEntities: 0,\n                            numVisibleEntities: 0,\n                            checked: false,\n                            xrayed: false,\n                            children: []\n                        };\n                        rootNode.children.push(typeNode);\n                        this._objectNodes[typeNode.objectId] = typeNode;\n                        this._nodeNodes[typeNode.nodeId] = typeNode;\n                        typeNodes[metaObjectType] = typeNode;\n                    }\n                    const node = {\n                        nodeId: `${this._id}-${objectId}`,\n                        objectId: objectId,\n                        title: (metaObjectName && metaObjectName !== \"\" && metaObjectName !== \"Default\") ? metaObjectName : metaObjectType,\n                        type: metaObjectType,\n                        parent: typeNode,\n                        numEntities: 0,\n                        numVisibleEntities: 0,\n                        checked: false,\n                        xrayed: false,\n                        children: []\n                    };\n                    typeNode.children.push(node);\n                    this._objectNodes[node.objectId] = node;\n                    this._nodeNodes[node.nodeId] = node;\n                }\n            }\n        }\n        if (children) {\n            for (let i = 0, len = children.length; i < len; i++) {\n                const childMetaObject = children[i];\n                this._createTypesNodes2(childMetaObject, rootNode, typeNodes);\n            }\n        }\n    }\n\n    _createContainmentNodes() {\n        const rootMetaObjects = this._viewer.metaScene.rootMetaObjects;\n        for (let id in rootMetaObjects) {\n            this._createContainmentNodes2(rootMetaObjects[id], null);\n        }\n    }\n\n    _createContainmentNodes2(metaObject, parent) {\n        if (this._pruneEmptyNodes && (metaObject._countEntities === 0)) {\n            return;\n        }\n        const metaObjectType = metaObject.type;\n        const metaObjectName = metaObject.name || metaObjectType;\n        const children = metaObject.children;\n        const objectId = metaObject.id;\n        const node = {\n            nodeId: `${this._id}-${objectId}`,\n            objectId: objectId,\n            title: (!parent) ? metaObject.metaModels.length === 0 ? metaObjectName : (this._rootNames[metaObject.metaModels[0].id] || metaObjectName) : (metaObjectName && metaObjectName !== \"\" && metaObjectName !== \"Undefined\" && metaObjectName !== \"Default\") ? metaObjectName : metaObjectType,\n            type: metaObjectType,\n            parent: parent,\n            numEntities: 0,\n            numVisibleEntities: 0,\n            checked: false,\n            xrayed: false,\n            children: []\n        };\n        if (parent) {\n            parent.children.push(node);\n        } else {\n            this._rootNodes.push(node);\n        }\n        this._objectNodes[node.objectId] = node;\n        this._nodeNodes[node.nodeId] = node;\n        if (children) {\n            for (let i = 0, len = children.length; i < len; i++) {\n                const childMetaObject = children[i];\n                this._createContainmentNodes2(childMetaObject, node);\n            }\n        }\n    }\n\n    _doSortNodes() {\n        for (let i = 0, len = this._rootNodes.length; i < len; i++) {\n            const rootNode = this._rootNodes[i];\n            this._sortChildren(rootNode);\n        }\n    }\n\n    _sortChildren(node) {\n        const children = node.children;\n        if (!children || children.length === 0) {\n            return;\n        }\n        const firstChild = children[0];\n        if ((this._hierarchy === \"storeys\" || this._hierarchy === \"containment\") &&  firstChild.type === \"IfcBuildingStorey\") {\n            if (this._elevationSortFunction) children.sort(this._elevationSortFunction);\n            else children.sort(this._getSpatialSortFunc());\n        } else {\n            if (this._defaultSortFunction) children.sort(this._defaultSortFunction);\n            else children.sort(this._alphaSortFunc);\n        }\n        for (let i = 0, len = children.length; i < len; i++) {\n            const node = children[i];\n            this._sortChildren(node);\n        }\n    }\n\n    _getSpatialSortFunc() {\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const camera = scene.camera;\n        return this._spatialSortFunc || (this._spatialSortFunc = (storey1, storey2) => {\n            if (camera.xUp) ; else if (camera.yUp) ; else ;\n            const metaScene = this.viewer.metaScene;\n            const storey1MetaObject = metaScene.metaObjects[storey1.objectId];\n            const storey2MetaObject = metaScene.metaObjects[storey2.objectId];\n\n            if (storey1MetaObject && (storey1MetaObject.attributes && storey1MetaObject.attributes.elevation !== undefined) &&\n                storey2MetaObject && (storey2MetaObject.attributes && storey2MetaObject.attributes.elevation !== undefined)) {\n                const elevation1 = Number.parseFloat(storey1MetaObject.attributes.elevation);\n                const elevation2 = Number.parseFloat(storey2MetaObject.attributes.elevation);\n                if (elevation1 > elevation2) {\n                    return -1;\n                }\n                if (elevation1 < elevation2) {\n                    return 1;\n                }\n                return 0;\n            } else {\n                return 0;\n            }\n        });\n    }\n\n    _alphaSortFunc(node1, node2) {\n        const title1 = node1.title.toUpperCase(); // FIXME: Should be case sensitive?\n        const title2 = node2.title.toUpperCase();\n        if (title1 < title2) {\n            return -1;\n        }\n        if (title1 > title2) {\n            return 1;\n        }\n        return 0;\n    }\n\n    _synchNodesToEntities() {\n        const objectIds = Object.keys(this.viewer.metaScene.metaObjects);\n        const metaObjects = this._viewer.metaScene.metaObjects;\n        const objects = this._viewer.scene.objects;\n        for (let i = 0, len = objectIds.length; i < len; i++) {\n            const objectId = objectIds[i];\n            const metaObject = metaObjects[objectId];\n            if (metaObject) {\n                const node = this._objectNodes[objectId];\n                if (node) {\n                    const entity = objects[objectId];\n                    if (entity) {\n                        const visible = entity.visible;\n                        node.numEntities = 1;\n                        node.xrayed = entity.xrayed;\n                        if (visible) {\n                            node.numVisibleEntities = 1;\n                            node.checked = true;\n                        } else {\n                            node.numVisibleEntities = 0;\n                            node.checked = false;\n                        }\n                        let parent = node.parent; // Synch parents\n                        while (parent) {\n                            parent.numEntities++;\n                            if (visible) {\n                                parent.numVisibleEntities++;\n                                parent.checked = true;\n                            }\n                            parent = parent.parent;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    _withNodeTree(node, callback) {\n        callback(node);\n        const children = node.children;\n        if (!children) {\n            return;\n        }\n        for (let i = 0, len = children.length; i < len; i++) {\n            this._withNodeTree(children[i], callback);\n        }\n    }\n\n    _createTrees() {\n        if (this._rootNodes.length === 0) {\n            return;\n        }\n        const rootNodeElements = this._rootNodes.map((rootNode) => {\n            return this._createNodeElement(rootNode);\n        });\n\n        const rootNode = this._renderService.createRootNode();\n        rootNodeElements.forEach((nodeElement) => {\n            rootNode.appendChild(nodeElement);\n        });\n\n        this._containerElement.appendChild(rootNode);\n        this._rootElement = rootNode;\n    }\n\n    _createNodeElement(node) {\n        const contextmenuHandler = (event) =>{\n                this.fire(\"contextmenu\", {\n                event: event,\n                viewer: this._viewer,\n                treeViewPlugin: this,\n                treeViewNode: node\n            });\n            event.preventDefault();\n        };\n        const onclickHandler = (event) => {\n            this.fire(\"nodeTitleClicked\", {\n                event: event,\n                viewer: this._viewer,\n                treeViewPlugin: this,\n                treeViewNode: node\n            });\n            event.preventDefault();\n        };\n\n        return this._renderService.createNodeElement(node, this._switchExpandHandler, this._checkboxChangeHandler, contextmenuHandler, onclickHandler);\n    }\n\n    _expandSwitchElement(switchElement) {\n        const expanded = this._renderService.isExpanded(switchElement); \n        if (expanded) {\n            return;\n        }\n\n        const nodeId = this._renderService.getId(switchElement);\n\n        const nodeElements = this._nodeNodes[nodeId].children.map((node) => {\n            return this._createNodeElement(node);\n        });\n\n        this._renderService.addChildren(switchElement, nodeElements);\n\n        this._renderService.expand(switchElement, this._switchExpandHandler, this._switchCollapseHandler);\n    }\n\n    _collapseNode(nodeId) {\n        const switchElement = this._renderService.getSwitchElement(nodeId);\n        this._collapseSwitchElement(switchElement);\n    }\n\n    _collapseSwitchElement(switchElement) {\n        this._renderService.collapse(switchElement, this._switchExpandHandler, this._switchCollapseHandler);\n    }\n}\n\n/**\n * For each Entity in its Scene, efficiently combines updates from multiple culling systems into a single \"culled\" state.\n *\n * Two culling systems are supported:\n *\n * * View culling - culls Entities when they fall outside the current view frustum, and\n * * Detail culling - momentarily culls less visually-significant Entities while we are moving the camera.\n *\n * @private\n */\nclass ObjectCullStates {\n\n    /**\n     * @private\n     * @param scene\n     */\n    constructor(scene) {\n\n        this._scene = scene;\n\n        this._objects = []; // Array of all Entity instances that represent objects\n        this._objectsViewCulled = []; // A flag for each object to indicate its view-cull status\n        this._objectsDetailCulled = []; // A flag for each object to indicate its detail-cull status\n        this._objectsChanged = []; // A flag for each object, set whenever its cull status has changed since last _applyChanges()\n        this._objectsChangedList = []; // A list of objects whose cull status has changed, applied and cleared by _applyChanges()\n\n        this._modelInfos = {};\n\n        this._numObjects = 0;\n        this._lenObjectsChangedList = 0;\n\n        this._dirty = true;\n\n        this._onModelLoaded = scene.on(\"modelLoaded\", (modelId) => {\n            const model = scene.models[modelId];\n            if (model) {\n                this._addModel(model);\n            }\n        });\n\n        this._onTick = scene.on(\"tick\", () => {\n            if (this._dirty) {\n                this._build();\n            }\n            this._applyChanges();\n        });\n    }\n\n    _addModel(model) {\n        const modelInfo = {\n            model: model,\n            onDestroyed: model.on(\"destroyed\", () => {\n                this._removeModel(model);\n            })\n        };\n        this._modelInfos[model.id] = modelInfo;\n        this._dirty = true;\n    }\n\n    _removeModel(model) {\n        const modelInfo = this._modelInfos[model.id];\n        if (modelInfo) {\n            modelInfo.model.off(modelInfo.onDestroyed);\n            delete this._modelInfos[model.id];\n            this._dirty = true;\n        }\n    }\n\n    _build() {\n        if (!this._dirty) {\n            return;\n        }\n        this._applyChanges();\n        const objects = this._scene.objects;\n        for (let i = 0; i < this._numObjects; i++) {\n            this._objects[i] = null;\n        }\n        this._numObjects = 0;\n        for (let objectId in objects) {\n            const entity = objects[objectId];\n            this._objects[this._numObjects++] = entity;\n        }\n        this._lenObjectsChangedList = 0;\n        this._dirty = false;\n    }\n\n    _applyChanges() {\n        if (this._lenObjectsChangedList > 0) {\n            for (let i = 0; i < this._lenObjectsChangedList; i++) {\n                const objectIdx = this._objectsChangedList[i];\n                const object = this._objects[objectIdx];\n                const viewCulled = this._objectsViewCulled[objectIdx];\n                const detailCulled = this._objectsDetailCulled[objectIdx];\n                const culled = (viewCulled || detailCulled);\n                object.culled = culled;\n                this._objectsChanged[objectIdx] = false;\n            }\n            this._lenObjectsChangedList = 0;\n        }\n    }\n\n    /**\n     * Array of {@link Entity} instances that represent objects in the {@link Scene}.\n     *\n     * ObjectCullStates rebuilds this from {@link Scene#objects} whenever ````Scene```` fires a ````modelLoaded```` event.\n     *\n     * @returns {Entity[]}\n     */\n    get objects() {\n        if (this._dirty) {\n            this._build();\n        }\n        return this._objects;\n    }\n\n    /**\n     * Number of objects in {@link ObjectCullStates#objects},\n     *\n     * Updated whenever ````Scene```` fires a ````modelLoaded```` event.\n     *\n     * @returns {Number}\n     */\n    get numObjects() {\n        if (this._dirty) {\n            this._build();\n        }\n        return this._numObjects;\n    }\n\n    /**\n     * Updates an object's view-cull status.\n     *\n     * @param {Number} objectIdx Index of the object in {@link ObjectCullStates#objects}\n     * @param {boolean} culled Whether to view-cull or not.\n     */\n    setObjectViewCulled(objectIdx, culled) {\n        if (this._dirty) {\n            this._build();\n        }\n        if (this._objectsViewCulled[objectIdx] === culled) {\n            return;\n        }\n        this._objectsViewCulled[objectIdx] = culled;\n        if (!this._objectsChanged[objectIdx]) {\n            this._objectsChanged[objectIdx] = true;\n            this._objectsChangedList[this._lenObjectsChangedList++] = objectIdx;\n        }\n    }\n\n    /**\n     * Updates an object's detail-cull status.\n     *\n     * @param {Number} objectIdx Index of the object in {@link ObjectCullStates#objects}\n     * @param {boolean} culled Whether to detail-cull or not.\n     */\n    setObjectDetailCulled(objectIdx, culled) {\n        if (this._dirty) {\n            this._build();\n        }\n        if (this._objectsDetailCulled[objectIdx] === culled) {\n            return;\n        }\n        this._objectsDetailCulled[objectIdx] = culled;\n        if (!this._objectsChanged[objectIdx]) {\n            this._objectsChanged[objectIdx] = true;\n            this._objectsChangedList[this._lenObjectsChangedList++] = objectIdx;\n        }\n    }\n\n    /**\n     * Destroys this ObjectCullStAtes.\n     */\n    _destroy() {\n        this._clear();\n        this._scene.off(this._onModelLoaded);\n        this._scene.off(this._onTick);\n    }\n\n    _clear() {\n        for (let modelId in this._modelInfos) {\n            const modelInfo = this._modelInfos[modelId];\n            modelInfo.model.off(modelInfo.onDestroyed);\n        }\n        this._modelInfos = {};\n        this._dirty = true;\n    }\n}\n\nconst sceneObjectCullStates = {};\n\n/**\n * @private\n */\nfunction getObjectCullStates(scene) {\n    const sceneId = scene.id;\n    let objectCullStates = sceneObjectCullStates[sceneId];\n    if (!objectCullStates) {\n        objectCullStates = new ObjectCullStates(scene);\n        sceneObjectCullStates[sceneId] = objectCullStates;\n        scene.on(\"destroyed\", () => {\n            delete sceneObjectCullStates[sceneId];\n            objectCullStates._destroy();\n        });\n    }\n    return objectCullStates;\n}\n\nconst MAX_KD_TREE_DEPTH = 8; // Increase if greater precision needed\n\nconst kdTreeDimLength = new Float32Array(3);\n\n/**\n * {@link Viewer} plugin that performs view frustum culling to accelerate rendering performance.\n *\n * For each {@link Entity} that represents an object, ````ViewCullPlugin```` will automatically\n * set {@link Entity#culled}````false```` whenever it falls outside our field of view.\n *\n * When culled, an ````Entity```` is not processed by xeokit's renderer.\n *\n * Internally, ````ViewCullPlugin```` organizes {@link Entity}s in\n * a [bounding volume hierarchy](https://en.wikipedia.org/wiki/Bounding_volume_hierarchy), implemented as\n * a [kd-tree](https://en.wikipedia.org/wiki/K-d_tree).\n *\n * On each {@link Scene} \"tick\" event, ````ViewCullPlugin```` searches the kd-tree using a frustum generated from\n * the {@link Camera}, marking each ````Entity```` **culled** if it falls outside the frustum.\n *\n * Use ````ViewCullPlugin```` by simply adding it to your ````Viewer````:\n *\n * ````javascript\n * const viewer = new Viewer({\n *    canvasId: \"myCanvas\",\n *    transparent: true\n * });\n *\n * const viewCullPlugin = new ViewCullPlugin(viewer, {\n *    maxTreeDepth: 20\n * });\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const model = xktLoader.load({\n *      id: \"myModel\",\n *      src: \"./models/xkt/OTCConferenceCenter.xkt\"\n * });\n * ````\n */\nclass ViewCullPlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"ViewCull\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {Number} [cfg.maxTreeDepth=8] Maximum depth of the kd-tree.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"ViewCull\", viewer);\n\n        this._objectCullStates = getObjectCullStates(viewer.scene); // Combines updates from multiple culling systems for its Scene's Entities\n\n        this._maxTreeDepth = cfg.maxTreeDepth || MAX_KD_TREE_DEPTH;\n        this._modelInfos = {};\n        this._frustum = new Frustum$1();\n        this._kdRoot = null;\n\n        this._frustumDirty = false;\n        this._kdTreeDirty = false;\n\n        this._onViewMatrix = viewer.scene.camera.on(\"viewMatrix\", () => {\n            this._frustumDirty = true;\n        });\n\n        this._onProjMatrix = viewer.scene.camera.on(\"projMatMatrix\", () => {\n            this._frustumDirty = true;\n        });\n\n        this._onModelLoaded = viewer.scene.on(\"modelLoaded\", (modelId) => {\n            const model = this.viewer.scene.models[modelId];\n            if (model) {\n                this._addModel(model);\n            }\n        });\n\n        this._onSceneTick = viewer.scene.on(\"tick\", () => {\n            this._doCull();\n        });\n    }\n\n    /**\n     * Sets whether view culling is enabled.\n     *\n     * @param {Boolean} enabled Whether to enable view culling.\n     */\n    set enabled(enabled) {\n        this._enabled = enabled;\n    }\n\n    /**\n     * Gets whether view culling is enabled.\n     *\n     * @retutns {Boolean} Whether view culling is enabled.\n     */\n    get enabled() {\n        return this._enabled;\n    }\n\n    _addModel(model) {\n        const modelInfo = {\n            model: model,\n            onDestroyed: model.on(\"destroyed\", () => {\n                this._removeModel(model);\n            })\n        };\n        this._modelInfos[model.id] = modelInfo;\n        this._kdTreeDirty = true;\n    }\n\n    _removeModel(model) {\n        const modelInfo = this._modelInfos[model.id];\n        if (modelInfo) {\n            modelInfo.model.off(modelInfo.onDestroyed);\n            delete this._modelInfos[model.id];\n            this._kdTreeDirty = true;\n        }\n    }\n\n    _doCull() {\n        const cullDirty = (this._frustumDirty || this._kdTreeDirty);\n        if (this._frustumDirty) {\n            this._buildFrustum();\n        }\n        if (this._kdTreeDirty) {\n            this._buildKDTree();\n        }\n        if (cullDirty) {\n            const kdNode = this._kdRoot;\n            if (kdNode) {\n                this._visitKDNode(kdNode);\n            }\n        }\n    }\n\n    _buildFrustum() {\n        const camera = this.viewer.scene.camera;\n        setFrustum(this._frustum, camera.viewMatrix, camera.projMatrix);\n        this._frustumDirty = false;\n    }\n\n    _buildKDTree() {\n        const viewer = this.viewer;\n        const scene = viewer.scene;\n        const depth = 0;\n        if (this._kdRoot) ;\n        this._kdRoot = {\n            aabb: scene.getAABB(),\n            intersection: Frustum$1.INTERSECT\n        };\n        for (let objectIdx = 0, len = this._objectCullStates.numObjects; objectIdx < len; objectIdx++) {\n            const entity = this._objectCullStates.objects[objectIdx];\n            this._insertEntityIntoKDTree(this._kdRoot, entity, objectIdx, depth + 1);\n        }\n        this._kdTreeDirty = false;\n    }\n\n    _insertEntityIntoKDTree(kdNode, entity, objectIdx, depth) {\n\n        const entityAABB = entity.aabb;\n\n        if (depth >= this._maxTreeDepth) {\n            kdNode.objects = kdNode.objects || [];\n            kdNode.objects.push(objectIdx);\n            math.expandAABB3(kdNode.aabb, entityAABB);\n            return;\n        }\n\n        if (kdNode.left) {\n            if (math.containsAABB3(kdNode.left.aabb, entityAABB)) {\n                this._insertEntityIntoKDTree(kdNode.left, entity, objectIdx, depth + 1);\n                return;\n            }\n        }\n\n        if (kdNode.right) {\n            if (math.containsAABB3(kdNode.right.aabb, entityAABB)) {\n                this._insertEntityIntoKDTree(kdNode.right, entity, objectIdx, depth + 1);\n                return;\n            }\n        }\n\n        const nodeAABB = kdNode.aabb;\n\n        kdTreeDimLength[0] = nodeAABB[3] - nodeAABB[0];\n        kdTreeDimLength[1] = nodeAABB[4] - nodeAABB[1];\n        kdTreeDimLength[2] = nodeAABB[5] - nodeAABB[2];\n\n        let dim = 0;\n\n        if (kdTreeDimLength[1] > kdTreeDimLength[dim]) {\n            dim = 1;\n        }\n\n        if (kdTreeDimLength[2] > kdTreeDimLength[dim]) {\n            dim = 2;\n        }\n\n        if (!kdNode.left) {\n            const aabbLeft = nodeAABB.slice();\n            aabbLeft[dim + 3] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0);\n            kdNode.left = {\n                aabb: aabbLeft,\n                intersection: Frustum$1.INTERSECT\n            };\n            if (math.containsAABB3(aabbLeft, entityAABB)) {\n                this._insertEntityIntoKDTree(kdNode.left, entity, objectIdx, depth + 1);\n                return;\n            }\n        }\n\n        if (!kdNode.right) {\n            const aabbRight = nodeAABB.slice();\n            aabbRight[dim] = ((nodeAABB[dim] + nodeAABB[dim + 3]) / 2.0);\n            kdNode.right = {\n                aabb: aabbRight,\n                intersection: Frustum$1.INTERSECT\n            };\n            if (math.containsAABB3(aabbRight, entityAABB)) {\n                this._insertEntityIntoKDTree(kdNode.right, entity, objectIdx, depth + 1);\n                return;\n            }\n        }\n\n        kdNode.objects = kdNode.objects || [];\n        kdNode.objects.push(objectIdx);\n\n        math.expandAABB3(kdNode.aabb, entityAABB);\n    }\n\n    _visitKDNode(kdNode, intersects = Frustum$1.INTERSECT) {\n        if (intersects !== Frustum$1.INTERSECT && kdNode.intersects === intersects) {\n            return;\n        }\n        if (intersects === Frustum$1.INTERSECT) {\n            intersects = frustumIntersectsAABB3(this._frustum, kdNode.aabb);\n            kdNode.intersects = intersects;\n        }\n        const culled = (intersects === Frustum$1.OUTSIDE);\n        const objects = kdNode.objects;\n        if (objects && objects.length > 0) {\n            for (let i = 0, len = objects.length; i < len; i++) {\n                const objectIdx = objects[i];\n                this._objectCullStates.setObjectViewCulled(objectIdx, culled);\n            }\n        }\n        if (kdNode.left) {\n            this._visitKDNode(kdNode.left, intersects);\n        }\n        if (kdNode.right) {\n            this._visitKDNode(kdNode.right, intersects);\n        }\n    }\n\n    /**\n     * @private\n     */\n    send(name, value) {\n    }\n\n    /**\n     * Destroys this ViewCullPlugin.\n     */\n    destroy() {\n        super.destroy();\n        this._clear();\n        const scene = this.viewer.scene;\n        const camera = scene.camera;\n        scene.off(this._onModelLoaded);\n        scene.off(this._onSceneTick);\n        camera.off(this._onViewMatrix);\n        camera.off(this._onProjMatrix);\n    }\n\n    _clear() {\n        for (let modelId in this._modelInfos) {\n            const modelInfo = this._modelInfos[modelId];\n            modelInfo.model.off(modelInfo.onDestroyed);\n        }\n        this._modelInfos = {};\n        this._kdRoot = null;\n        this._kdTreeDirty = true;\n    }\n}\n\n/**\n * Default data access strategy for {@link XKTLoaderPlugin}.\n */\nclass XKTDefaultDataSource {\n\n    constructor(cfg = {}) {\n        this.cacheBuster = (cfg.cacheBuster !== false);\n    }\n\n    _cacheBusterURL(url) {\n        if (!this.cacheBuster) {\n            return url;\n        }\n        const timestamp = new Date().getTime();\n        if (url.indexOf('?') > -1) {\n            return url + '&_=' + timestamp;\n        } else {\n            return url + '?_=' + timestamp;\n        }\n    }\n\n    /**\n     * Gets manifest JSON.\n     *\n     * @param {String|Number} manifestSrc Identifies the manifest JSON asset.\n     * @param {Function} ok Fired on successful loading of the manifest JSON asset.\n     * @param {Function} error Fired on error while loading the manifest JSON asset.\n     */\n    getManifest(manifestSrc, ok, error) {\n        utils.loadJSON(this._cacheBusterURL(manifestSrc),\n            (json) => {\n                ok(json);\n            },\n            function (errMsg) {\n                error(errMsg);\n            });\n    }\n\n    /**\n     * Gets metamodel JSON.\n     *\n     * @param {String|Number} metaModelSrc Identifies the metamodel JSON asset.\n     * @param {Function} ok Fired on successful loading of the metamodel JSON asset.\n     * @param {Function} error Fired on error while loading the metamodel JSON asset.\n     */\n    getMetaModel(metaModelSrc, ok, error) {\n        utils.loadJSON(this._cacheBusterURL(metaModelSrc),\n            (json) => {\n                ok(json);\n            },\n            function (errMsg) {\n                error(errMsg);\n            });\n    }\n\n    /**\n     * Gets the contents of the given ````.xkt```` file in an arraybuffer.\n     *\n     * @param {String|Number} src Path or ID of an ````.xkt```` file.\n     * @param {Function} ok Callback fired on success, argument is the ````.xkt```` file in an arraybuffer.\n     * @param {Function} error Callback fired on error.\n     */\n    getXKT(src, ok, error) {\n        var defaultCallback = () => {\n        };\n        ok = ok || defaultCallback;\n        error = error || defaultCallback;\n        const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n        const dataUriRegexResult = src.match(dataUriRegex);\n        if (dataUriRegexResult) { // Safari can't handle data URIs through XMLHttpRequest\n            const isBase64 = !!dataUriRegexResult[2];\n            var data = dataUriRegexResult[3];\n            data = window.decodeURIComponent(data);\n            if (isBase64) {\n                data = window.atob(data);\n            }\n            try {\n                const buffer = new ArrayBuffer(data.length);\n                const view = new Uint8Array(buffer);\n                for (var i = 0; i < data.length; i++) {\n                    view[i] = data.charCodeAt(i);\n                }\n                ok(buffer);\n            } catch (errMsg) {\n                error(errMsg);\n            }\n        } else {\n            const request = new XMLHttpRequest();\n            request.open('GET', this._cacheBusterURL(src), true);\n            request.responseType = 'arraybuffer';\n            request.onreadystatechange = function () {\n                if (request.readyState === 4) {\n                    if (request.status === 200) {\n                        ok(request.response);\n                    } else {\n                        error('getXKT error : ' + request.response);\n                    }\n                }\n            };\n            request.send(null);\n        }\n    }\n}\n\n/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */\n!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?e(exports):\"function\"==typeof define&&define.amd?define([\"exports\"],e):e((t=\"undefined\"!=typeof globalThis?globalThis:t||self).pako={});}(undefined,(function(t){function e(t){let e=t.length;for(;--e>=0;)t[e]=0;}const a=256,i=286,n=30,s=15,r=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]),o=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),l=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]),h=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),d=new Array(576);e(d);const _=new Array(60);e(_);const f=new Array(512);e(f);const c=new Array(256);e(c);const u=new Array(29);e(u);const w=new Array(n);function m(t,e,a,i,n){this.static_tree=t,this.extra_bits=e,this.extra_base=a,this.elems=i,this.max_length=n,this.has_stree=t&&t.length;}let b,g,p;function k(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e;}e(w);const v=t=>t<256?f[t]:f[256+(t>>>7)],y=(t,e)=>{t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255;},x=(t,e,a)=>{t.bi_valid>16-a?(t.bi_buf|=e<<t.bi_valid&65535,y(t,t.bi_buf),t.bi_buf=e>>16-t.bi_valid,t.bi_valid+=a-16):(t.bi_buf|=e<<t.bi_valid&65535,t.bi_valid+=a);},z=(t,e,a)=>{x(t,a[2*e],a[2*e+1]);},A=(t,e)=>{let a=0;do{a|=1&t,t>>>=1,a<<=1;}while(--e>0);return a>>>1},E=(t,e,a)=>{const i=new Array(16);let n,r,o=0;for(n=1;n<=s;n++)o=o+a[n-1]<<1,i[n]=o;for(r=0;r<=e;r++){let e=t[2*r+1];0!==e&&(t[2*r]=A(i[e]++,e));}},R=t=>{let e;for(e=0;e<i;e++)t.dyn_ltree[2*e]=0;for(e=0;e<n;e++)t.dyn_dtree[2*e]=0;for(e=0;e<19;e++)t.bl_tree[2*e]=0;t.dyn_ltree[512]=1,t.opt_len=t.static_len=0,t.sym_next=t.matches=0;},Z=t=>{t.bi_valid>8?y(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0;},U=(t,e,a,i)=>{const n=2*e,s=2*a;return t[n]<t[s]||t[n]===t[s]&&i[e]<=i[a]},S=(t,e,a)=>{const i=t.heap[a];let n=a<<1;for(;n<=t.heap_len&&(n<t.heap_len&&U(e,t.heap[n+1],t.heap[n],t.depth)&&n++,!U(e,i,t.heap[n],t.depth));)t.heap[a]=t.heap[n],a=n,n<<=1;t.heap[a]=i;},D=(t,e,i)=>{let n,s,l,h,d=0;if(0!==t.sym_next)do{n=255&t.pending_buf[t.sym_buf+d++],n+=(255&t.pending_buf[t.sym_buf+d++])<<8,s=t.pending_buf[t.sym_buf+d++],0===n?z(t,s,e):(l=c[s],z(t,l+a+1,e),h=r[l],0!==h&&(s-=u[l],x(t,s,h)),n--,l=v(n),z(t,l,i),h=o[l],0!==h&&(n-=w[l],x(t,n,h)));}while(d<t.sym_next);z(t,256,e);},T=(t,e)=>{const a=e.dyn_tree,i=e.stat_desc.static_tree,n=e.stat_desc.has_stree,r=e.stat_desc.elems;let o,l,h,d=-1;for(t.heap_len=0,t.heap_max=573,o=0;o<r;o++)0!==a[2*o]?(t.heap[++t.heap_len]=d=o,t.depth[o]=0):a[2*o+1]=0;for(;t.heap_len<2;)h=t.heap[++t.heap_len]=d<2?++d:0,a[2*h]=1,t.depth[h]=0,t.opt_len--,n&&(t.static_len-=i[2*h+1]);for(e.max_code=d,o=t.heap_len>>1;o>=1;o--)S(t,a,o);h=r;do{o=t.heap[1],t.heap[1]=t.heap[t.heap_len--],S(t,a,1),l=t.heap[1],t.heap[--t.heap_max]=o,t.heap[--t.heap_max]=l,a[2*h]=a[2*o]+a[2*l],t.depth[h]=(t.depth[o]>=t.depth[l]?t.depth[o]:t.depth[l])+1,a[2*o+1]=a[2*l+1]=h,t.heap[1]=h++,S(t,a,1);}while(t.heap_len>=2);t.heap[--t.heap_max]=t.heap[1],((t,e)=>{const a=e.dyn_tree,i=e.max_code,n=e.stat_desc.static_tree,r=e.stat_desc.has_stree,o=e.stat_desc.extra_bits,l=e.stat_desc.extra_base,h=e.stat_desc.max_length;let d,_,f,c,u,w,m=0;for(c=0;c<=s;c++)t.bl_count[c]=0;for(a[2*t.heap[t.heap_max]+1]=0,d=t.heap_max+1;d<573;d++)_=t.heap[d],c=a[2*a[2*_+1]+1]+1,c>h&&(c=h,m++),a[2*_+1]=c,_>i||(t.bl_count[c]++,u=0,_>=l&&(u=o[_-l]),w=a[2*_],t.opt_len+=w*(c+u),r&&(t.static_len+=w*(n[2*_+1]+u)));if(0!==m){do{for(c=h-1;0===t.bl_count[c];)c--;t.bl_count[c]--,t.bl_count[c+1]+=2,t.bl_count[h]--,m-=2;}while(m>0);for(c=h;0!==c;c--)for(_=t.bl_count[c];0!==_;)f=t.heap[--d],f>i||(a[2*f+1]!==c&&(t.opt_len+=(c-a[2*f+1])*a[2*f],a[2*f+1]=c),_--);}})(t,e),E(a,d,t.bl_count);},O=(t,e,a)=>{let i,n,s=-1,r=e[1],o=0,l=7,h=4;for(0===r&&(l=138,h=3),e[2*(a+1)+1]=65535,i=0;i<=a;i++)n=r,r=e[2*(i+1)+1],++o<l&&n===r||(o<h?t.bl_tree[2*n]+=o:0!==n?(n!==s&&t.bl_tree[2*n]++,t.bl_tree[32]++):o<=10?t.bl_tree[34]++:t.bl_tree[36]++,o=0,s=n,0===r?(l=138,h=3):n===r?(l=6,h=3):(l=7,h=4));},I=(t,e,a)=>{let i,n,s=-1,r=e[1],o=0,l=7,h=4;for(0===r&&(l=138,h=3),i=0;i<=a;i++)if(n=r,r=e[2*(i+1)+1],!(++o<l&&n===r)){if(o<h)do{z(t,n,t.bl_tree);}while(0!=--o);else 0!==n?(n!==s&&(z(t,n,t.bl_tree),o--),z(t,16,t.bl_tree),x(t,o-3,2)):o<=10?(z(t,17,t.bl_tree),x(t,o-3,3)):(z(t,18,t.bl_tree),x(t,o-11,7));o=0,s=n,0===r?(l=138,h=3):n===r?(l=6,h=3):(l=7,h=4);}};let F=!1;const L=(t,e,a,i)=>{x(t,0+(i?1:0),3),Z(t),y(t,a),y(t,~a),a&&t.pending_buf.set(t.window.subarray(e,e+a),t.pending),t.pending+=a;};var N=(t,e,i,n)=>{let s,r,o=0;t.level>0?(2===t.strm.data_type&&(t.strm.data_type=(t=>{let e,i=4093624447;for(e=0;e<=31;e++,i>>>=1)if(1&i&&0!==t.dyn_ltree[2*e])return 0;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return 1;for(e=32;e<a;e++)if(0!==t.dyn_ltree[2*e])return 1;return 0})(t)),T(t,t.l_desc),T(t,t.d_desc),o=(t=>{let e;for(O(t,t.dyn_ltree,t.l_desc.max_code),O(t,t.dyn_dtree,t.d_desc.max_code),T(t,t.bl_desc),e=18;e>=3&&0===t.bl_tree[2*h[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e})(t),s=t.opt_len+3+7>>>3,r=t.static_len+3+7>>>3,r<=s&&(s=r)):s=r=i+5,i+4<=s&&-1!==e?L(t,e,i,n):4===t.strategy||r===s?(x(t,2+(n?1:0),3),D(t,d,_)):(x(t,4+(n?1:0),3),((t,e,a,i)=>{let n;for(x(t,e-257,5),x(t,a-1,5),x(t,i-4,4),n=0;n<i;n++)x(t,t.bl_tree[2*h[n]+1],3);I(t,t.dyn_ltree,e-1),I(t,t.dyn_dtree,a-1);})(t,t.l_desc.max_code+1,t.d_desc.max_code+1,o+1),D(t,t.dyn_ltree,t.dyn_dtree)),R(t),n&&Z(t);},B={_tr_init:t=>{F||((()=>{let t,e,a,h,k;const v=new Array(16);for(a=0,h=0;h<28;h++)for(u[h]=a,t=0;t<1<<r[h];t++)c[a++]=h;for(c[a-1]=h,k=0,h=0;h<16;h++)for(w[h]=k,t=0;t<1<<o[h];t++)f[k++]=h;for(k>>=7;h<n;h++)for(w[h]=k<<7,t=0;t<1<<o[h]-7;t++)f[256+k++]=h;for(e=0;e<=s;e++)v[e]=0;for(t=0;t<=143;)d[2*t+1]=8,t++,v[8]++;for(;t<=255;)d[2*t+1]=9,t++,v[9]++;for(;t<=279;)d[2*t+1]=7,t++,v[7]++;for(;t<=287;)d[2*t+1]=8,t++,v[8]++;for(E(d,287,v),t=0;t<n;t++)_[2*t+1]=5,_[2*t]=A(t,5);b=new m(d,r,257,i,s),g=new m(_,o,0,n,s),p=new m(new Array(0),l,0,19,7);})(),F=!0),t.l_desc=new k(t.dyn_ltree,b),t.d_desc=new k(t.dyn_dtree,g),t.bl_desc=new k(t.bl_tree,p),t.bi_buf=0,t.bi_valid=0,R(t);},_tr_stored_block:L,_tr_flush_block:N,_tr_tally:(t,e,i)=>(t.pending_buf[t.sym_buf+t.sym_next++]=e,t.pending_buf[t.sym_buf+t.sym_next++]=e>>8,t.pending_buf[t.sym_buf+t.sym_next++]=i,0===e?t.dyn_ltree[2*i]++:(t.matches++,e--,t.dyn_ltree[2*(c[i]+a+1)]++,t.dyn_dtree[2*v(e)]++),t.sym_next===t.sym_end),_tr_align:t=>{x(t,2,3),z(t,256,d),(t=>{16===t.bi_valid?(y(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):t.bi_valid>=8&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8);})(t);}};var C=(t,e,a,i)=>{let n=65535&t|0,s=t>>>16&65535|0,r=0;for(;0!==a;){r=a>2e3?2e3:a,a-=r;do{n=n+e[i++]|0,s=s+n|0;}while(--r);n%=65521,s%=65521;}return n|s<<16|0};const M=new Uint32Array((()=>{let t,e=[];for(var a=0;a<256;a++){t=a;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[a]=t;}return e})());var H=(t,e,a,i)=>{const n=M,s=i+a;t^=-1;for(let a=i;a<s;a++)t=t>>>8^n[255&(t^e[a])];return -1^t},j={2:\"need dictionary\",1:\"stream end\",0:\"\",\"-1\":\"file error\",\"-2\":\"stream error\",\"-3\":\"data error\",\"-4\":\"insufficient memory\",\"-5\":\"buffer error\",\"-6\":\"incompatible version\"},K={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};const{_tr_init:P,_tr_stored_block:Y,_tr_flush_block:G,_tr_tally:X,_tr_align:W}=B,{Z_NO_FLUSH:q,Z_PARTIAL_FLUSH:J,Z_FULL_FLUSH:Q,Z_FINISH:V,Z_BLOCK:$,Z_OK:tt,Z_STREAM_END:et,Z_STREAM_ERROR:at,Z_DATA_ERROR:it,Z_BUF_ERROR:nt,Z_DEFAULT_COMPRESSION:st,Z_FILTERED:rt,Z_HUFFMAN_ONLY:ot,Z_RLE:lt,Z_FIXED:ht,Z_DEFAULT_STRATEGY:dt,Z_UNKNOWN:_t,Z_DEFLATED:ft}=K,ct=258,ut=262,wt=42,mt=113,bt=666,gt=(t,e)=>(t.msg=j[e],e),pt=t=>2*t-(t>4?9:0),kt=t=>{let e=t.length;for(;--e>=0;)t[e]=0;},vt=t=>{let e,a,i,n=t.w_size;e=t.hash_size,i=e;do{a=t.head[--i],t.head[i]=a>=n?a-n:0;}while(--e);e=n,i=e;do{a=t.prev[--i],t.prev[i]=a>=n?a-n:0;}while(--e)};let yt=(t,e,a)=>(e<<t.hash_shift^a)&t.hash_mask;const xt=t=>{const e=t.state;let a=e.pending;a>t.avail_out&&(a=t.avail_out),0!==a&&(t.output.set(e.pending_buf.subarray(e.pending_out,e.pending_out+a),t.next_out),t.next_out+=a,e.pending_out+=a,t.total_out+=a,t.avail_out-=a,e.pending-=a,0===e.pending&&(e.pending_out=0));},zt=(t,e)=>{G(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,xt(t.strm);},At=(t,e)=>{t.pending_buf[t.pending++]=e;},Et=(t,e)=>{t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e;},Rt=(t,e,a,i)=>{let n=t.avail_in;return n>i&&(n=i),0===n?0:(t.avail_in-=n,e.set(t.input.subarray(t.next_in,t.next_in+n),a),1===t.state.wrap?t.adler=C(t.adler,e,n,a):2===t.state.wrap&&(t.adler=H(t.adler,e,n,a)),t.next_in+=n,t.total_in+=n,n)},Zt=(t,e)=>{let a,i,n=t.max_chain_length,s=t.strstart,r=t.prev_length,o=t.nice_match;const l=t.strstart>t.w_size-ut?t.strstart-(t.w_size-ut):0,h=t.window,d=t.w_mask,_=t.prev,f=t.strstart+ct;let c=h[s+r-1],u=h[s+r];t.prev_length>=t.good_match&&(n>>=2),o>t.lookahead&&(o=t.lookahead);do{if(a=e,h[a+r]===u&&h[a+r-1]===c&&h[a]===h[s]&&h[++a]===h[s+1]){s+=2,a++;do{}while(h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&s<f);if(i=ct-(f-s),s=f-ct,i>r){if(t.match_start=e,r=i,i>=o)break;c=h[s+r-1],u=h[s+r];}}}while((e=_[e&d])>l&&0!=--n);return r<=t.lookahead?r:t.lookahead},Ut=t=>{const e=t.w_size;let a,i,n;do{if(i=t.window_size-t.lookahead-t.strstart,t.strstart>=e+(e-ut)&&(t.window.set(t.window.subarray(e,e+e-i),0),t.match_start-=e,t.strstart-=e,t.block_start-=e,t.insert>t.strstart&&(t.insert=t.strstart),vt(t),i+=e),0===t.strm.avail_in)break;if(a=Rt(t.strm,t.window,t.strstart+t.lookahead,i),t.lookahead+=a,t.lookahead+t.insert>=3)for(n=t.strstart-t.insert,t.ins_h=t.window[n],t.ins_h=yt(t,t.ins_h,t.window[n+1]);t.insert&&(t.ins_h=yt(t,t.ins_h,t.window[n+3-1]),t.prev[n&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=n,n++,t.insert--,!(t.lookahead+t.insert<3)););}while(t.lookahead<ut&&0!==t.strm.avail_in)},St=(t,e)=>{let a,i,n,s=t.pending_buf_size-5>t.w_size?t.w_size:t.pending_buf_size-5,r=0,o=t.strm.avail_in;do{if(a=65535,n=t.bi_valid+42>>3,t.strm.avail_out<n)break;if(n=t.strm.avail_out-n,i=t.strstart-t.block_start,a>i+t.strm.avail_in&&(a=i+t.strm.avail_in),a>n&&(a=n),a<s&&(0===a&&e!==V||e===q||a!==i+t.strm.avail_in))break;r=e===V&&a===i+t.strm.avail_in?1:0,Y(t,0,0,r),t.pending_buf[t.pending-4]=a,t.pending_buf[t.pending-3]=a>>8,t.pending_buf[t.pending-2]=~a,t.pending_buf[t.pending-1]=~a>>8,xt(t.strm),i&&(i>a&&(i=a),t.strm.output.set(t.window.subarray(t.block_start,t.block_start+i),t.strm.next_out),t.strm.next_out+=i,t.strm.avail_out-=i,t.strm.total_out+=i,t.block_start+=i,a-=i),a&&(Rt(t.strm,t.strm.output,t.strm.next_out,a),t.strm.next_out+=a,t.strm.avail_out-=a,t.strm.total_out+=a);}while(0===r);return o-=t.strm.avail_in,o&&(o>=t.w_size?(t.matches=2,t.window.set(t.strm.input.subarray(t.strm.next_in-t.w_size,t.strm.next_in),0),t.strstart=t.w_size,t.insert=t.strstart):(t.window_size-t.strstart<=o&&(t.strstart-=t.w_size,t.window.set(t.window.subarray(t.w_size,t.w_size+t.strstart),0),t.matches<2&&t.matches++,t.insert>t.strstart&&(t.insert=t.strstart)),t.window.set(t.strm.input.subarray(t.strm.next_in-o,t.strm.next_in),t.strstart),t.strstart+=o,t.insert+=o>t.w_size-t.insert?t.w_size-t.insert:o),t.block_start=t.strstart),t.high_water<t.strstart&&(t.high_water=t.strstart),r?4:e!==q&&e!==V&&0===t.strm.avail_in&&t.strstart===t.block_start?2:(n=t.window_size-t.strstart,t.strm.avail_in>n&&t.block_start>=t.w_size&&(t.block_start-=t.w_size,t.strstart-=t.w_size,t.window.set(t.window.subarray(t.w_size,t.w_size+t.strstart),0),t.matches<2&&t.matches++,n+=t.w_size,t.insert>t.strstart&&(t.insert=t.strstart)),n>t.strm.avail_in&&(n=t.strm.avail_in),n&&(Rt(t.strm,t.window,t.strstart,n),t.strstart+=n,t.insert+=n>t.w_size-t.insert?t.w_size-t.insert:n),t.high_water<t.strstart&&(t.high_water=t.strstart),n=t.bi_valid+42>>3,n=t.pending_buf_size-n>65535?65535:t.pending_buf_size-n,s=n>t.w_size?t.w_size:n,i=t.strstart-t.block_start,(i>=s||(i||e===V)&&e!==q&&0===t.strm.avail_in&&i<=n)&&(a=i>n?n:i,r=e===V&&0===t.strm.avail_in&&a===i?1:0,Y(t,t.block_start,a,r),t.block_start+=a,xt(t.strm)),r?3:1)},Dt=(t,e)=>{let a,i;for(;;){if(t.lookahead<ut){if(Ut(t),t.lookahead<ut&&e===q)return 1;if(0===t.lookahead)break}if(a=0,t.lookahead>=3&&(t.ins_h=yt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==a&&t.strstart-a<=t.w_size-ut&&(t.match_length=Zt(t,a)),t.match_length>=3)if(i=X(t,t.strstart-t.match_start,t.match_length-3),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=3){t.match_length--;do{t.strstart++,t.ins_h=yt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart;}while(0!=--t.match_length);t.strstart++;}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=yt(t,t.ins_h,t.window[t.strstart+1]);else i=X(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(i&&(zt(t,!1),0===t.strm.avail_out))return 1}return t.insert=t.strstart<2?t.strstart:2,e===V?(zt(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(zt(t,!1),0===t.strm.avail_out)?1:2},Tt=(t,e)=>{let a,i,n;for(;;){if(t.lookahead<ut){if(Ut(t),t.lookahead<ut&&e===q)return 1;if(0===t.lookahead)break}if(a=0,t.lookahead>=3&&(t.ins_h=yt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=2,0!==a&&t.prev_length<t.max_lazy_match&&t.strstart-a<=t.w_size-ut&&(t.match_length=Zt(t,a),t.match_length<=5&&(t.strategy===rt||3===t.match_length&&t.strstart-t.match_start>4096)&&(t.match_length=2)),t.prev_length>=3&&t.match_length<=t.prev_length){n=t.strstart+t.lookahead-3,i=X(t,t.strstart-1-t.prev_match,t.prev_length-3),t.lookahead-=t.prev_length-1,t.prev_length-=2;do{++t.strstart<=n&&(t.ins_h=yt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart);}while(0!=--t.prev_length);if(t.match_available=0,t.match_length=2,t.strstart++,i&&(zt(t,!1),0===t.strm.avail_out))return 1}else if(t.match_available){if(i=X(t,0,t.window[t.strstart-1]),i&&zt(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return 1}else t.match_available=1,t.strstart++,t.lookahead--;}return t.match_available&&(i=X(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<2?t.strstart:2,e===V?(zt(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(zt(t,!1),0===t.strm.avail_out)?1:2};function Ot(t,e,a,i,n){this.good_length=t,this.max_lazy=e,this.nice_length=a,this.max_chain=i,this.func=n;}const It=[new Ot(0,0,0,0,St),new Ot(4,4,8,4,Dt),new Ot(4,5,16,8,Dt),new Ot(4,6,32,32,Dt),new Ot(4,4,16,16,Tt),new Ot(8,16,32,32,Tt),new Ot(8,16,128,128,Tt),new Ot(8,32,128,256,Tt),new Ot(32,128,258,1024,Tt),new Ot(32,258,258,4096,Tt)];function Ft(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=ft,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Uint16Array(1146),this.dyn_dtree=new Uint16Array(122),this.bl_tree=new Uint16Array(78),kt(this.dyn_ltree),kt(this.dyn_dtree),kt(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Uint16Array(16),this.heap=new Uint16Array(573),kt(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Uint16Array(573),kt(this.depth),this.sym_buf=0,this.lit_bufsize=0,this.sym_next=0,this.sym_end=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0;}const Lt=t=>{if(!t)return 1;const e=t.state;return !e||e.strm!==t||e.status!==wt&&57!==e.status&&69!==e.status&&73!==e.status&&91!==e.status&&103!==e.status&&e.status!==mt&&e.status!==bt?1:0},Nt=t=>{if(Lt(t))return gt(t,at);t.total_in=t.total_out=0,t.data_type=_t;const e=t.state;return e.pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=2===e.wrap?57:e.wrap?wt:mt,t.adler=2===e.wrap?0:1,e.last_flush=-2,P(e),tt},Bt=t=>{const e=Nt(t);var a;return e===tt&&((a=t.state).window_size=2*a.w_size,kt(a.head),a.max_lazy_match=It[a.level].max_lazy,a.good_match=It[a.level].good_length,a.nice_match=It[a.level].nice_length,a.max_chain_length=It[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=2,a.match_available=0,a.ins_h=0),e},Ct=(t,e,a,i,n,s)=>{if(!t)return at;let r=1;if(e===st&&(e=6),i<0?(r=0,i=-i):i>15&&(r=2,i-=16),n<1||n>9||a!==ft||i<8||i>15||e<0||e>9||s<0||s>ht||8===i&&1!==r)return gt(t,at);8===i&&(i=9);const o=new Ft;return t.state=o,o.strm=t,o.status=wt,o.wrap=r,o.gzhead=null,o.w_bits=i,o.w_size=1<<o.w_bits,o.w_mask=o.w_size-1,o.hash_bits=n+7,o.hash_size=1<<o.hash_bits,o.hash_mask=o.hash_size-1,o.hash_shift=~~((o.hash_bits+3-1)/3),o.window=new Uint8Array(2*o.w_size),o.head=new Uint16Array(o.hash_size),o.prev=new Uint16Array(o.w_size),o.lit_bufsize=1<<n+6,o.pending_buf_size=4*o.lit_bufsize,o.pending_buf=new Uint8Array(o.pending_buf_size),o.sym_buf=o.lit_bufsize,o.sym_end=3*(o.lit_bufsize-1),o.level=e,o.strategy=s,o.method=a,Bt(t)};var Mt={deflateInit:(t,e)=>Ct(t,e,ft,15,8,dt),deflateInit2:Ct,deflateReset:Bt,deflateResetKeep:Nt,deflateSetHeader:(t,e)=>Lt(t)||2!==t.state.wrap?at:(t.state.gzhead=e,tt),deflate:(t,e)=>{if(Lt(t)||e>$||e<0)return t?gt(t,at):at;const a=t.state;if(!t.output||0!==t.avail_in&&!t.input||a.status===bt&&e!==V)return gt(t,0===t.avail_out?nt:at);const i=a.last_flush;if(a.last_flush=e,0!==a.pending){if(xt(t),0===t.avail_out)return a.last_flush=-1,tt}else if(0===t.avail_in&&pt(e)<=pt(i)&&e!==V)return gt(t,nt);if(a.status===bt&&0!==t.avail_in)return gt(t,nt);if(a.status===wt&&0===a.wrap&&(a.status=mt),a.status===wt){let e=ft+(a.w_bits-8<<4)<<8,i=-1;if(i=a.strategy>=ot||a.level<2?0:a.level<6?1:6===a.level?2:3,e|=i<<6,0!==a.strstart&&(e|=32),e+=31-e%31,Et(a,e),0!==a.strstart&&(Et(a,t.adler>>>16),Et(a,65535&t.adler)),t.adler=1,a.status=mt,xt(t),0!==a.pending)return a.last_flush=-1,tt}if(57===a.status)if(t.adler=0,At(a,31),At(a,139),At(a,8),a.gzhead)At(a,(a.gzhead.text?1:0)+(a.gzhead.hcrc?2:0)+(a.gzhead.extra?4:0)+(a.gzhead.name?8:0)+(a.gzhead.comment?16:0)),At(a,255&a.gzhead.time),At(a,a.gzhead.time>>8&255),At(a,a.gzhead.time>>16&255),At(a,a.gzhead.time>>24&255),At(a,9===a.level?2:a.strategy>=ot||a.level<2?4:0),At(a,255&a.gzhead.os),a.gzhead.extra&&a.gzhead.extra.length&&(At(a,255&a.gzhead.extra.length),At(a,a.gzhead.extra.length>>8&255)),a.gzhead.hcrc&&(t.adler=H(t.adler,a.pending_buf,a.pending,0)),a.gzindex=0,a.status=69;else if(At(a,0),At(a,0),At(a,0),At(a,0),At(a,0),At(a,9===a.level?2:a.strategy>=ot||a.level<2?4:0),At(a,3),a.status=mt,xt(t),0!==a.pending)return a.last_flush=-1,tt;if(69===a.status){if(a.gzhead.extra){let e=a.pending,i=(65535&a.gzhead.extra.length)-a.gzindex;for(;a.pending+i>a.pending_buf_size;){let n=a.pending_buf_size-a.pending;if(a.pending_buf.set(a.gzhead.extra.subarray(a.gzindex,a.gzindex+n),a.pending),a.pending=a.pending_buf_size,a.gzhead.hcrc&&a.pending>e&&(t.adler=H(t.adler,a.pending_buf,a.pending-e,e)),a.gzindex+=n,xt(t),0!==a.pending)return a.last_flush=-1,tt;e=0,i-=n;}let n=new Uint8Array(a.gzhead.extra);a.pending_buf.set(n.subarray(a.gzindex,a.gzindex+i),a.pending),a.pending+=i,a.gzhead.hcrc&&a.pending>e&&(t.adler=H(t.adler,a.pending_buf,a.pending-e,e)),a.gzindex=0;}a.status=73;}if(73===a.status){if(a.gzhead.name){let e,i=a.pending;do{if(a.pending===a.pending_buf_size){if(a.gzhead.hcrc&&a.pending>i&&(t.adler=H(t.adler,a.pending_buf,a.pending-i,i)),xt(t),0!==a.pending)return a.last_flush=-1,tt;i=0;}e=a.gzindex<a.gzhead.name.length?255&a.gzhead.name.charCodeAt(a.gzindex++):0,At(a,e);}while(0!==e);a.gzhead.hcrc&&a.pending>i&&(t.adler=H(t.adler,a.pending_buf,a.pending-i,i)),a.gzindex=0;}a.status=91;}if(91===a.status){if(a.gzhead.comment){let e,i=a.pending;do{if(a.pending===a.pending_buf_size){if(a.gzhead.hcrc&&a.pending>i&&(t.adler=H(t.adler,a.pending_buf,a.pending-i,i)),xt(t),0!==a.pending)return a.last_flush=-1,tt;i=0;}e=a.gzindex<a.gzhead.comment.length?255&a.gzhead.comment.charCodeAt(a.gzindex++):0,At(a,e);}while(0!==e);a.gzhead.hcrc&&a.pending>i&&(t.adler=H(t.adler,a.pending_buf,a.pending-i,i));}a.status=103;}if(103===a.status){if(a.gzhead.hcrc){if(a.pending+2>a.pending_buf_size&&(xt(t),0!==a.pending))return a.last_flush=-1,tt;At(a,255&t.adler),At(a,t.adler>>8&255),t.adler=0;}if(a.status=mt,xt(t),0!==a.pending)return a.last_flush=-1,tt}if(0!==t.avail_in||0!==a.lookahead||e!==q&&a.status!==bt){let i=0===a.level?St(a,e):a.strategy===ot?((t,e)=>{let a;for(;;){if(0===t.lookahead&&(Ut(t),0===t.lookahead)){if(e===q)return 1;break}if(t.match_length=0,a=X(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,a&&(zt(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===V?(zt(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(zt(t,!1),0===t.strm.avail_out)?1:2})(a,e):a.strategy===lt?((t,e)=>{let a,i,n,s;const r=t.window;for(;;){if(t.lookahead<=ct){if(Ut(t),t.lookahead<=ct&&e===q)return 1;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=3&&t.strstart>0&&(n=t.strstart-1,i=r[n],i===r[++n]&&i===r[++n]&&i===r[++n])){s=t.strstart+ct;do{}while(i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&n<s);t.match_length=ct-(s-n),t.match_length>t.lookahead&&(t.match_length=t.lookahead);}if(t.match_length>=3?(a=X(t,1,t.match_length-3),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(a=X(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),a&&(zt(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===V?(zt(t,!0),0===t.strm.avail_out?3:4):t.sym_next&&(zt(t,!1),0===t.strm.avail_out)?1:2})(a,e):It[a.level].func(a,e);if(3!==i&&4!==i||(a.status=bt),1===i||3===i)return 0===t.avail_out&&(a.last_flush=-1),tt;if(2===i&&(e===J?W(a):e!==$&&(Y(a,0,0,!1),e===Q&&(kt(a.head),0===a.lookahead&&(a.strstart=0,a.block_start=0,a.insert=0))),xt(t),0===t.avail_out))return a.last_flush=-1,tt}return e!==V?tt:a.wrap<=0?et:(2===a.wrap?(At(a,255&t.adler),At(a,t.adler>>8&255),At(a,t.adler>>16&255),At(a,t.adler>>24&255),At(a,255&t.total_in),At(a,t.total_in>>8&255),At(a,t.total_in>>16&255),At(a,t.total_in>>24&255)):(Et(a,t.adler>>>16),Et(a,65535&t.adler)),xt(t),a.wrap>0&&(a.wrap=-a.wrap),0!==a.pending?tt:et)},deflateEnd:t=>{if(Lt(t))return at;const e=t.state.status;return t.state=null,e===mt?gt(t,it):tt},deflateSetDictionary:(t,e)=>{let a=e.length;if(Lt(t))return at;const i=t.state,n=i.wrap;if(2===n||1===n&&i.status!==wt||i.lookahead)return at;if(1===n&&(t.adler=C(t.adler,e,a,0)),i.wrap=0,a>=i.w_size){0===n&&(kt(i.head),i.strstart=0,i.block_start=0,i.insert=0);let t=new Uint8Array(i.w_size);t.set(e.subarray(a-i.w_size,a),0),e=t,a=i.w_size;}const s=t.avail_in,r=t.next_in,o=t.input;for(t.avail_in=a,t.next_in=0,t.input=e,Ut(i);i.lookahead>=3;){let t=i.strstart,e=i.lookahead-2;do{i.ins_h=yt(i,i.ins_h,i.window[t+3-1]),i.prev[t&i.w_mask]=i.head[i.ins_h],i.head[i.ins_h]=t,t++;}while(--e);i.strstart=t,i.lookahead=2,Ut(i);}return i.strstart+=i.lookahead,i.block_start=i.strstart,i.insert=i.lookahead,i.lookahead=0,i.match_length=i.prev_length=2,i.match_available=0,t.next_in=r,t.input=o,t.avail_in=s,i.wrap=n,tt},deflateInfo:\"pako deflate (from Nodeca project)\"};const Ht=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var jt=function(t){const e=Array.prototype.slice.call(arguments,1);for(;e.length;){const a=e.shift();if(a){if(\"object\"!=typeof a)throw new TypeError(a+\"must be non-object\");for(const e in a)Ht(a,e)&&(t[e]=a[e]);}}return t},Kt=t=>{let e=0;for(let a=0,i=t.length;a<i;a++)e+=t[a].length;const a=new Uint8Array(e);for(let e=0,i=0,n=t.length;e<n;e++){let n=t[e];a.set(n,i),i+=n.length;}return a};let Pt=!0;try{String.fromCharCode.apply(null,new Uint8Array(1));}catch(t){Pt=!1;}const Yt=new Uint8Array(256);for(let t=0;t<256;t++)Yt[t]=t>=252?6:t>=248?5:t>=240?4:t>=224?3:t>=192?2:1;Yt[254]=Yt[254]=1;var Gt=t=>{if(\"function\"==typeof TextEncoder&&TextEncoder.prototype.encode)return (new TextEncoder).encode(t);let e,a,i,n,s,r=t.length,o=0;for(n=0;n<r;n++)a=t.charCodeAt(n),55296==(64512&a)&&n+1<r&&(i=t.charCodeAt(n+1),56320==(64512&i)&&(a=65536+(a-55296<<10)+(i-56320),n++)),o+=a<128?1:a<2048?2:a<65536?3:4;for(e=new Uint8Array(o),s=0,n=0;s<o;n++)a=t.charCodeAt(n),55296==(64512&a)&&n+1<r&&(i=t.charCodeAt(n+1),56320==(64512&i)&&(a=65536+(a-55296<<10)+(i-56320),n++)),a<128?e[s++]=a:a<2048?(e[s++]=192|a>>>6,e[s++]=128|63&a):a<65536?(e[s++]=224|a>>>12,e[s++]=128|a>>>6&63,e[s++]=128|63&a):(e[s++]=240|a>>>18,e[s++]=128|a>>>12&63,e[s++]=128|a>>>6&63,e[s++]=128|63&a);return e},Xt=(t,e)=>{const a=e||t.length;if(\"function\"==typeof TextDecoder&&TextDecoder.prototype.decode)return (new TextDecoder).decode(t.subarray(0,e));let i,n;const s=new Array(2*a);for(n=0,i=0;i<a;){let e=t[i++];if(e<128){s[n++]=e;continue}let r=Yt[e];if(r>4)s[n++]=65533,i+=r-1;else {for(e&=2===r?31:3===r?15:7;r>1&&i<a;)e=e<<6|63&t[i++],r--;r>1?s[n++]=65533:e<65536?s[n++]=e:(e-=65536,s[n++]=55296|e>>10&1023,s[n++]=56320|1023&e);}}return ((t,e)=>{if(e<65534&&t.subarray&&Pt)return String.fromCharCode.apply(null,t.length===e?t:t.subarray(0,e));let a=\"\";for(let i=0;i<e;i++)a+=String.fromCharCode(t[i]);return a})(s,n)},Wt=(t,e)=>{(e=e||t.length)>t.length&&(e=t.length);let a=e-1;for(;a>=0&&128==(192&t[a]);)a--;return a<0||0===a?e:a+Yt[t[a]]>e?a:e};var qt=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg=\"\",this.state=null,this.data_type=2,this.adler=0;};const Jt=Object.prototype.toString,{Z_NO_FLUSH:Qt,Z_SYNC_FLUSH:Vt,Z_FULL_FLUSH:$t,Z_FINISH:te,Z_OK:ee,Z_STREAM_END:ae,Z_DEFAULT_COMPRESSION:ie,Z_DEFAULT_STRATEGY:ne,Z_DEFLATED:se}=K;function re(t){this.options=jt({level:ie,method:se,chunkSize:16384,windowBits:15,memLevel:8,strategy:ne},t||{});let e=this.options;e.raw&&e.windowBits>0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg=\"\",this.ended=!1,this.chunks=[],this.strm=new qt,this.strm.avail_out=0;let a=Mt.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(a!==ee)throw new Error(j[a]);if(e.header&&Mt.deflateSetHeader(this.strm,e.header),e.dictionary){let t;if(t=\"string\"==typeof e.dictionary?Gt(e.dictionary):\"[object ArrayBuffer]\"===Jt.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,a=Mt.deflateSetDictionary(this.strm,t),a!==ee)throw new Error(j[a]);this._dict_set=!0;}}function oe(t,e){const a=new re(e);if(a.push(t,!0),a.err)throw a.msg||j[a.err];return a.result}re.prototype.push=function(t,e){const a=this.strm,i=this.options.chunkSize;let n,s;if(this.ended)return !1;for(s=e===~~e?e:!0===e?te:Qt,\"string\"==typeof t?a.input=Gt(t):\"[object ArrayBuffer]\"===Jt.call(t)?a.input=new Uint8Array(t):a.input=t,a.next_in=0,a.avail_in=a.input.length;;)if(0===a.avail_out&&(a.output=new Uint8Array(i),a.next_out=0,a.avail_out=i),(s===Vt||s===$t)&&a.avail_out<=6)this.onData(a.output.subarray(0,a.next_out)),a.avail_out=0;else {if(n=Mt.deflate(a,s),n===ae)return a.next_out>0&&this.onData(a.output.subarray(0,a.next_out)),n=Mt.deflateEnd(this.strm),this.onEnd(n),this.ended=!0,n===ee;if(0!==a.avail_out){if(s>0&&a.next_out>0)this.onData(a.output.subarray(0,a.next_out)),a.avail_out=0;else if(0===a.avail_in)break}else this.onData(a.output);}return !0},re.prototype.onData=function(t){this.chunks.push(t);},re.prototype.onEnd=function(t){t===ee&&(this.result=Kt(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg;};var le={Deflate:re,deflate:oe,deflateRaw:function(t,e){return (e=e||{}).raw=!0,oe(t,e)},gzip:function(t,e){return (e=e||{}).gzip=!0,oe(t,e)},constants:K};const he=16209;var de=function(t,e){let a,i,n,s,r,o,l,h,d,_,f,c,u,w,m,b,g,p,k,v,y,x,z,A;const E=t.state;a=t.next_in,z=t.input,i=a+(t.avail_in-5),n=t.next_out,A=t.output,s=n-(e-t.avail_out),r=n+(t.avail_out-257),o=E.dmax,l=E.wsize,h=E.whave,d=E.wnext,_=E.window,f=E.hold,c=E.bits,u=E.lencode,w=E.distcode,m=(1<<E.lenbits)-1,b=(1<<E.distbits)-1;t:do{c<15&&(f+=z[a++]<<c,c+=8,f+=z[a++]<<c,c+=8),g=u[f&m];e:for(;;){if(p=g>>>24,f>>>=p,c-=p,p=g>>>16&255,0===p)A[n++]=65535&g;else {if(!(16&p)){if(0==(64&p)){g=u[(65535&g)+(f&(1<<p)-1)];continue e}if(32&p){E.mode=16191;break t}t.msg=\"invalid literal/length code\",E.mode=he;break t}k=65535&g,p&=15,p&&(c<p&&(f+=z[a++]<<c,c+=8),k+=f&(1<<p)-1,f>>>=p,c-=p),c<15&&(f+=z[a++]<<c,c+=8,f+=z[a++]<<c,c+=8),g=w[f&b];a:for(;;){if(p=g>>>24,f>>>=p,c-=p,p=g>>>16&255,!(16&p)){if(0==(64&p)){g=w[(65535&g)+(f&(1<<p)-1)];continue a}t.msg=\"invalid distance code\",E.mode=he;break t}if(v=65535&g,p&=15,c<p&&(f+=z[a++]<<c,c+=8,c<p&&(f+=z[a++]<<c,c+=8)),v+=f&(1<<p)-1,v>o){t.msg=\"invalid distance too far back\",E.mode=he;break t}if(f>>>=p,c-=p,p=n-s,v>p){if(p=v-p,p>h&&E.sane){t.msg=\"invalid distance too far back\",E.mode=he;break t}if(y=0,x=_,0===d){if(y+=l-p,p<k){k-=p;do{A[n++]=_[y++];}while(--p);y=n-v,x=A;}}else if(d<p){if(y+=l+d-p,p-=d,p<k){k-=p;do{A[n++]=_[y++];}while(--p);if(y=0,d<k){p=d,k-=p;do{A[n++]=_[y++];}while(--p);y=n-v,x=A;}}}else if(y+=d-p,p<k){k-=p;do{A[n++]=_[y++];}while(--p);y=n-v,x=A;}for(;k>2;)A[n++]=x[y++],A[n++]=x[y++],A[n++]=x[y++],k-=3;k&&(A[n++]=x[y++],k>1&&(A[n++]=x[y++]));}else {y=n-v;do{A[n++]=A[y++],A[n++]=A[y++],A[n++]=A[y++],k-=3;}while(k>2);k&&(A[n++]=A[y++],k>1&&(A[n++]=A[y++]));}break}}break}}while(a<i&&n<r);k=c>>3,a-=k,c-=k<<3,f&=(1<<c)-1,t.next_in=a,t.next_out=n,t.avail_in=a<i?i-a+5:5-(a-i),t.avail_out=n<r?r-n+257:257-(n-r),E.hold=f,E.bits=c;};const _e=15,fe=new Uint16Array([3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0]),ce=new Uint8Array([16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78]),ue=new Uint16Array([1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0]),we=new Uint8Array([16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64]);var me=(t,e,a,i,n,s,r,o)=>{const l=o.bits;let h,d,_,f,c,u,w=0,m=0,b=0,g=0,p=0,k=0,v=0,y=0,x=0,z=0,A=null;const E=new Uint16Array(16),R=new Uint16Array(16);let Z,U,S,D=null;for(w=0;w<=_e;w++)E[w]=0;for(m=0;m<i;m++)E[e[a+m]]++;for(p=l,g=_e;g>=1&&0===E[g];g--);if(p>g&&(p=g),0===g)return n[s++]=20971520,n[s++]=20971520,o.bits=1,0;for(b=1;b<g&&0===E[b];b++);for(p<b&&(p=b),y=1,w=1;w<=_e;w++)if(y<<=1,y-=E[w],y<0)return -1;if(y>0&&(0===t||1!==g))return -1;for(R[1]=0,w=1;w<_e;w++)R[w+1]=R[w]+E[w];for(m=0;m<i;m++)0!==e[a+m]&&(r[R[e[a+m]]++]=m);if(0===t?(A=D=r,u=20):1===t?(A=fe,D=ce,u=257):(A=ue,D=we,u=0),z=0,m=0,w=b,c=s,k=p,v=0,_=-1,x=1<<p,f=x-1,1===t&&x>852||2===t&&x>592)return 1;for(;;){Z=w-v,r[m]+1<u?(U=0,S=r[m]):r[m]>=u?(U=D[r[m]-u],S=A[r[m]-u]):(U=96,S=0),h=1<<w-v,d=1<<k,b=d;do{d-=h,n[c+(z>>v)+d]=Z<<24|U<<16|S|0;}while(0!==d);for(h=1<<w-1;z&h;)h>>=1;if(0!==h?(z&=h-1,z+=h):z=0,m++,0==--E[w]){if(w===g)break;w=e[a+r[m]];}if(w>p&&(z&f)!==_){for(0===v&&(v=p),c+=b,k=w-v,y=1<<k;k+v<g&&(y-=E[k+v],!(y<=0));)k++,y<<=1;if(x+=1<<k,1===t&&x>852||2===t&&x>592)return 1;_=z&f,n[_]=p<<24|k<<16|c-s|0;}}return 0!==z&&(n[c+z]=w-v<<24|64<<16|0),o.bits=p,0};const{Z_FINISH:be,Z_BLOCK:ge,Z_TREES:pe,Z_OK:ke,Z_STREAM_END:ve,Z_NEED_DICT:ye,Z_STREAM_ERROR:xe,Z_DATA_ERROR:ze,Z_MEM_ERROR:Ae,Z_BUF_ERROR:Ee,Z_DEFLATED:Re}=K,Ze=16180,Ue=16190,Se=16191,De=16192,Te=16194,Oe=16199,Ie=16200,Fe=16206,Le=16209,Ne=t=>(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24);function Be(){this.strm=null,this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0;}const Ce=t=>{if(!t)return 1;const e=t.state;return !e||e.strm!==t||e.mode<Ze||e.mode>16211?1:0},Me=t=>{if(Ce(t))return xe;const e=t.state;return t.total_in=t.total_out=e.total=0,t.msg=\"\",e.wrap&&(t.adler=1&e.wrap),e.mode=Ze,e.last=0,e.havedict=0,e.flags=-1,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new Int32Array(852),e.distcode=e.distdyn=new Int32Array(592),e.sane=1,e.back=-1,ke},He=t=>{if(Ce(t))return xe;const e=t.state;return e.wsize=0,e.whave=0,e.wnext=0,Me(t)},je=(t,e)=>{let a;if(Ce(t))return xe;const i=t.state;return e<0?(a=0,e=-e):(a=5+(e>>4),e<48&&(e&=15)),e&&(e<8||e>15)?xe:(null!==i.window&&i.wbits!==e&&(i.window=null),i.wrap=a,i.wbits=e,He(t))},Ke=(t,e)=>{if(!t)return xe;const a=new Be;t.state=a,a.strm=t,a.window=null,a.mode=Ze;const i=je(t,e);return i!==ke&&(t.state=null),i};let Pe,Ye,Ge=!0;const Xe=t=>{if(Ge){Pe=new Int32Array(512),Ye=new Int32Array(32);let e=0;for(;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(me(1,t.lens,0,288,Pe,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;me(2,t.lens,0,32,Ye,0,t.work,{bits:5}),Ge=!1;}t.lencode=Pe,t.lenbits=9,t.distcode=Ye,t.distbits=5;},We=(t,e,a,i)=>{let n;const s=t.state;return null===s.window&&(s.wsize=1<<s.wbits,s.wnext=0,s.whave=0,s.window=new Uint8Array(s.wsize)),i>=s.wsize?(s.window.set(e.subarray(a-s.wsize,a),0),s.wnext=0,s.whave=s.wsize):(n=s.wsize-s.wnext,n>i&&(n=i),s.window.set(e.subarray(a-i,a-i+n),s.wnext),(i-=n)?(s.window.set(e.subarray(a-i,a),0),s.wnext=i,s.whave=s.wsize):(s.wnext+=n,s.wnext===s.wsize&&(s.wnext=0),s.whave<s.wsize&&(s.whave+=n))),0};var qe={inflateReset:He,inflateReset2:je,inflateResetKeep:Me,inflateInit:t=>Ke(t,15),inflateInit2:Ke,inflate:(t,e)=>{let a,i,n,s,r,o,l,h,d,_,f,c,u,w,m,b,g,p,k,v,y,x,z=0;const A=new Uint8Array(4);let E,R;const Z=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(Ce(t)||!t.output||!t.input&&0!==t.avail_in)return xe;a=t.state,a.mode===Se&&(a.mode=De),r=t.next_out,n=t.output,l=t.avail_out,s=t.next_in,i=t.input,o=t.avail_in,h=a.hold,d=a.bits,_=o,f=l,x=ke;t:for(;;)switch(a.mode){case Ze:if(0===a.wrap){a.mode=De;break}for(;d<16;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}if(2&a.wrap&&35615===h){0===a.wbits&&(a.wbits=15),a.check=0,A[0]=255&h,A[1]=h>>>8&255,a.check=H(a.check,A,2,0),h=0,d=0,a.mode=16181;break}if(a.head&&(a.head.done=!1),!(1&a.wrap)||(((255&h)<<8)+(h>>8))%31){t.msg=\"incorrect header check\",a.mode=Le;break}if((15&h)!==Re){t.msg=\"unknown compression method\",a.mode=Le;break}if(h>>>=4,d-=4,y=8+(15&h),0===a.wbits&&(a.wbits=y),y>15||y>a.wbits){t.msg=\"invalid window size\",a.mode=Le;break}a.dmax=1<<a.wbits,a.flags=0,t.adler=a.check=1,a.mode=512&h?16189:Se,h=0,d=0;break;case 16181:for(;d<16;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}if(a.flags=h,(255&a.flags)!==Re){t.msg=\"unknown compression method\",a.mode=Le;break}if(57344&a.flags){t.msg=\"unknown header flags set\",a.mode=Le;break}a.head&&(a.head.text=h>>8&1),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,a.check=H(a.check,A,2,0)),h=0,d=0,a.mode=16182;case 16182:for(;d<32;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}a.head&&(a.head.time=h),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,A[2]=h>>>16&255,A[3]=h>>>24&255,a.check=H(a.check,A,4,0)),h=0,d=0,a.mode=16183;case 16183:for(;d<16;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}a.head&&(a.head.xflags=255&h,a.head.os=h>>8),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,a.check=H(a.check,A,2,0)),h=0,d=0,a.mode=16184;case 16184:if(1024&a.flags){for(;d<16;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}a.length=h,a.head&&(a.head.extra_len=h),512&a.flags&&4&a.wrap&&(A[0]=255&h,A[1]=h>>>8&255,a.check=H(a.check,A,2,0)),h=0,d=0;}else a.head&&(a.head.extra=null);a.mode=16185;case 16185:if(1024&a.flags&&(c=a.length,c>o&&(c=o),c&&(a.head&&(y=a.head.extra_len-a.length,a.head.extra||(a.head.extra=new Uint8Array(a.head.extra_len)),a.head.extra.set(i.subarray(s,s+c),y)),512&a.flags&&4&a.wrap&&(a.check=H(a.check,i,c,s)),o-=c,s+=c,a.length-=c),a.length))break t;a.length=0,a.mode=16186;case 16186:if(2048&a.flags){if(0===o)break t;c=0;do{y=i[s+c++],a.head&&y&&a.length<65536&&(a.head.name+=String.fromCharCode(y));}while(y&&c<o);if(512&a.flags&&4&a.wrap&&(a.check=H(a.check,i,c,s)),o-=c,s+=c,y)break t}else a.head&&(a.head.name=null);a.length=0,a.mode=16187;case 16187:if(4096&a.flags){if(0===o)break t;c=0;do{y=i[s+c++],a.head&&y&&a.length<65536&&(a.head.comment+=String.fromCharCode(y));}while(y&&c<o);if(512&a.flags&&4&a.wrap&&(a.check=H(a.check,i,c,s)),o-=c,s+=c,y)break t}else a.head&&(a.head.comment=null);a.mode=16188;case 16188:if(512&a.flags){for(;d<16;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}if(4&a.wrap&&h!==(65535&a.check)){t.msg=\"header crc mismatch\",a.mode=Le;break}h=0,d=0;}a.head&&(a.head.hcrc=a.flags>>9&1,a.head.done=!0),t.adler=a.check=0,a.mode=Se;break;case 16189:for(;d<32;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}t.adler=a.check=Ne(h),h=0,d=0,a.mode=Ue;case Ue:if(0===a.havedict)return t.next_out=r,t.avail_out=l,t.next_in=s,t.avail_in=o,a.hold=h,a.bits=d,ye;t.adler=a.check=1,a.mode=Se;case Se:if(e===ge||e===pe)break t;case De:if(a.last){h>>>=7&d,d-=7&d,a.mode=Fe;break}for(;d<3;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}switch(a.last=1&h,h>>>=1,d-=1,3&h){case 0:a.mode=16193;break;case 1:if(Xe(a),a.mode=Oe,e===pe){h>>>=2,d-=2;break t}break;case 2:a.mode=16196;break;case 3:t.msg=\"invalid block type\",a.mode=Le;}h>>>=2,d-=2;break;case 16193:for(h>>>=7&d,d-=7&d;d<32;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}if((65535&h)!=(h>>>16^65535)){t.msg=\"invalid stored block lengths\",a.mode=Le;break}if(a.length=65535&h,h=0,d=0,a.mode=Te,e===pe)break t;case Te:a.mode=16195;case 16195:if(c=a.length,c){if(c>o&&(c=o),c>l&&(c=l),0===c)break t;n.set(i.subarray(s,s+c),r),o-=c,s+=c,l-=c,r+=c,a.length-=c;break}a.mode=Se;break;case 16196:for(;d<14;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}if(a.nlen=257+(31&h),h>>>=5,d-=5,a.ndist=1+(31&h),h>>>=5,d-=5,a.ncode=4+(15&h),h>>>=4,d-=4,a.nlen>286||a.ndist>30){t.msg=\"too many length or distance symbols\",a.mode=Le;break}a.have=0,a.mode=16197;case 16197:for(;a.have<a.ncode;){for(;d<3;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}a.lens[Z[a.have++]]=7&h,h>>>=3,d-=3;}for(;a.have<19;)a.lens[Z[a.have++]]=0;if(a.lencode=a.lendyn,a.lenbits=7,E={bits:a.lenbits},x=me(0,a.lens,0,19,a.lencode,0,a.work,E),a.lenbits=E.bits,x){t.msg=\"invalid code lengths set\",a.mode=Le;break}a.have=0,a.mode=16198;case 16198:for(;a.have<a.nlen+a.ndist;){for(;z=a.lencode[h&(1<<a.lenbits)-1],m=z>>>24,b=z>>>16&255,g=65535&z,!(m<=d);){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}if(g<16)h>>>=m,d-=m,a.lens[a.have++]=g;else {if(16===g){for(R=m+2;d<R;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}if(h>>>=m,d-=m,0===a.have){t.msg=\"invalid bit length repeat\",a.mode=Le;break}y=a.lens[a.have-1],c=3+(3&h),h>>>=2,d-=2;}else if(17===g){for(R=m+3;d<R;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}h>>>=m,d-=m,y=0,c=3+(7&h),h>>>=3,d-=3;}else {for(R=m+7;d<R;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}h>>>=m,d-=m,y=0,c=11+(127&h),h>>>=7,d-=7;}if(a.have+c>a.nlen+a.ndist){t.msg=\"invalid bit length repeat\",a.mode=Le;break}for(;c--;)a.lens[a.have++]=y;}}if(a.mode===Le)break;if(0===a.lens[256]){t.msg=\"invalid code -- missing end-of-block\",a.mode=Le;break}if(a.lenbits=9,E={bits:a.lenbits},x=me(1,a.lens,0,a.nlen,a.lencode,0,a.work,E),a.lenbits=E.bits,x){t.msg=\"invalid literal/lengths set\",a.mode=Le;break}if(a.distbits=6,a.distcode=a.distdyn,E={bits:a.distbits},x=me(2,a.lens,a.nlen,a.ndist,a.distcode,0,a.work,E),a.distbits=E.bits,x){t.msg=\"invalid distances set\",a.mode=Le;break}if(a.mode=Oe,e===pe)break t;case Oe:a.mode=Ie;case Ie:if(o>=6&&l>=258){t.next_out=r,t.avail_out=l,t.next_in=s,t.avail_in=o,a.hold=h,a.bits=d,de(t,f),r=t.next_out,n=t.output,l=t.avail_out,s=t.next_in,i=t.input,o=t.avail_in,h=a.hold,d=a.bits,a.mode===Se&&(a.back=-1);break}for(a.back=0;z=a.lencode[h&(1<<a.lenbits)-1],m=z>>>24,b=z>>>16&255,g=65535&z,!(m<=d);){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}if(b&&0==(240&b)){for(p=m,k=b,v=g;z=a.lencode[v+((h&(1<<p+k)-1)>>p)],m=z>>>24,b=z>>>16&255,g=65535&z,!(p+m<=d);){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}h>>>=p,d-=p,a.back+=p;}if(h>>>=m,d-=m,a.back+=m,a.length=g,0===b){a.mode=16205;break}if(32&b){a.back=-1,a.mode=Se;break}if(64&b){t.msg=\"invalid literal/length code\",a.mode=Le;break}a.extra=15&b,a.mode=16201;case 16201:if(a.extra){for(R=a.extra;d<R;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}a.length+=h&(1<<a.extra)-1,h>>>=a.extra,d-=a.extra,a.back+=a.extra;}a.was=a.length,a.mode=16202;case 16202:for(;z=a.distcode[h&(1<<a.distbits)-1],m=z>>>24,b=z>>>16&255,g=65535&z,!(m<=d);){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}if(0==(240&b)){for(p=m,k=b,v=g;z=a.distcode[v+((h&(1<<p+k)-1)>>p)],m=z>>>24,b=z>>>16&255,g=65535&z,!(p+m<=d);){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}h>>>=p,d-=p,a.back+=p;}if(h>>>=m,d-=m,a.back+=m,64&b){t.msg=\"invalid distance code\",a.mode=Le;break}a.offset=g,a.extra=15&b,a.mode=16203;case 16203:if(a.extra){for(R=a.extra;d<R;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}a.offset+=h&(1<<a.extra)-1,h>>>=a.extra,d-=a.extra,a.back+=a.extra;}if(a.offset>a.dmax){t.msg=\"invalid distance too far back\",a.mode=Le;break}a.mode=16204;case 16204:if(0===l)break t;if(c=f-l,a.offset>c){if(c=a.offset-c,c>a.whave&&a.sane){t.msg=\"invalid distance too far back\",a.mode=Le;break}c>a.wnext?(c-=a.wnext,u=a.wsize-c):u=a.wnext-c,c>a.length&&(c=a.length),w=a.window;}else w=n,u=r-a.offset,c=a.length;c>l&&(c=l),l-=c,a.length-=c;do{n[r++]=w[u++];}while(--c);0===a.length&&(a.mode=Ie);break;case 16205:if(0===l)break t;n[r++]=a.length,l--,a.mode=Ie;break;case Fe:if(a.wrap){for(;d<32;){if(0===o)break t;o--,h|=i[s++]<<d,d+=8;}if(f-=l,t.total_out+=f,a.total+=f,4&a.wrap&&f&&(t.adler=a.check=a.flags?H(a.check,n,f,r-f):C(a.check,n,f,r-f)),f=l,4&a.wrap&&(a.flags?h:Ne(h))!==a.check){t.msg=\"incorrect data check\",a.mode=Le;break}h=0,d=0;}a.mode=16207;case 16207:if(a.wrap&&a.flags){for(;d<32;){if(0===o)break t;o--,h+=i[s++]<<d,d+=8;}if(4&a.wrap&&h!==(4294967295&a.total)){t.msg=\"incorrect length check\",a.mode=Le;break}h=0,d=0;}a.mode=16208;case 16208:x=ve;break t;case Le:x=ze;break t;case 16210:return Ae;default:return xe}return t.next_out=r,t.avail_out=l,t.next_in=s,t.avail_in=o,a.hold=h,a.bits=d,(a.wsize||f!==t.avail_out&&a.mode<Le&&(a.mode<Fe||e!==be))&&We(t,t.output,t.next_out,f-t.avail_out),_-=t.avail_in,f-=t.avail_out,t.total_in+=_,t.total_out+=f,a.total+=f,4&a.wrap&&f&&(t.adler=a.check=a.flags?H(a.check,n,f,t.next_out-f):C(a.check,n,f,t.next_out-f)),t.data_type=a.bits+(a.last?64:0)+(a.mode===Se?128:0)+(a.mode===Oe||a.mode===Te?256:0),(0===_&&0===f||e===be)&&x===ke&&(x=Ee),x},inflateEnd:t=>{if(Ce(t))return xe;let e=t.state;return e.window&&(e.window=null),t.state=null,ke},inflateGetHeader:(t,e)=>{if(Ce(t))return xe;const a=t.state;return 0==(2&a.wrap)?xe:(a.head=e,e.done=!1,ke)},inflateSetDictionary:(t,e)=>{const a=e.length;let i,n,s;return Ce(t)?xe:(i=t.state,0!==i.wrap&&i.mode!==Ue?xe:i.mode===Ue&&(n=1,n=C(n,e,a,0),n!==i.check)?ze:(s=We(t,e,a,a),s?(i.mode=16210,Ae):(i.havedict=1,ke)))},inflateInfo:\"pako inflate (from Nodeca project)\"};var Je=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name=\"\",this.comment=\"\",this.hcrc=0,this.done=!1;};const Qe=Object.prototype.toString,{Z_NO_FLUSH:Ve,Z_FINISH:$e,Z_OK:ta,Z_STREAM_END:ea,Z_NEED_DICT:aa,Z_STREAM_ERROR:ia,Z_DATA_ERROR:na,Z_MEM_ERROR:sa}=K;function ra(t){this.options=jt({chunkSize:65536,windowBits:15,to:\"\"},t||{});const e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(e.windowBits>=0&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg=\"\",this.ended=!1,this.chunks=[],this.strm=new qt,this.strm.avail_out=0;let a=qe.inflateInit2(this.strm,e.windowBits);if(a!==ta)throw new Error(j[a]);if(this.header=new Je,qe.inflateGetHeader(this.strm,this.header),e.dictionary&&(\"string\"==typeof e.dictionary?e.dictionary=Gt(e.dictionary):\"[object ArrayBuffer]\"===Qe.call(e.dictionary)&&(e.dictionary=new Uint8Array(e.dictionary)),e.raw&&(a=qe.inflateSetDictionary(this.strm,e.dictionary),a!==ta)))throw new Error(j[a])}function oa(t,e){const a=new ra(e);if(a.push(t),a.err)throw a.msg||j[a.err];return a.result}ra.prototype.push=function(t,e){const a=this.strm,i=this.options.chunkSize,n=this.options.dictionary;let s,r,o;if(this.ended)return !1;for(r=e===~~e?e:!0===e?$e:Ve,\"[object ArrayBuffer]\"===Qe.call(t)?a.input=new Uint8Array(t):a.input=t,a.next_in=0,a.avail_in=a.input.length;;){for(0===a.avail_out&&(a.output=new Uint8Array(i),a.next_out=0,a.avail_out=i),s=qe.inflate(a,r),s===aa&&n&&(s=qe.inflateSetDictionary(a,n),s===ta?s=qe.inflate(a,r):s===na&&(s=aa));a.avail_in>0&&s===ea&&a.state.wrap>0&&0!==t[a.next_in];)qe.inflateReset(a),s=qe.inflate(a,r);switch(s){case ia:case na:case aa:case sa:return this.onEnd(s),this.ended=!0,!1}if(o=a.avail_out,a.next_out&&(0===a.avail_out||s===ea))if(\"string\"===this.options.to){let t=Wt(a.output,a.next_out),e=a.next_out-t,n=Xt(a.output,t);a.next_out=e,a.avail_out=i-e,e&&a.output.set(a.output.subarray(t,t+e),0),this.onData(n);}else this.onData(a.output.length===a.next_out?a.output:a.output.subarray(0,a.next_out));if(s!==ta||0!==o){if(s===ea)return s=qe.inflateEnd(this.strm),this.onEnd(s),this.ended=!0,!0;if(0===a.avail_in)break}}return !0},ra.prototype.onData=function(t){this.chunks.push(t);},ra.prototype.onEnd=function(t){t===ta&&(\"string\"===this.options.to?this.result=this.chunks.join(\"\"):this.result=Kt(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg;};var la={Inflate:ra,inflate:oa,inflateRaw:function(t,e){return (e=e||{}).raw=!0,oa(t,e)},ungzip:oa,constants:K};const{Deflate:ha,deflate:da,deflateRaw:_a,gzip:fa}=le,{Inflate:ca,inflate:ua,inflateRaw:wa,ungzip:ma}=la;var ba=ha,ga=da,pa=_a,ka=fa,va=ca,ya=ua,xa=wa,za=ma,Aa=K,Ea={Deflate:ba,deflate:ga,deflateRaw:pa,gzip:ka,Inflate:va,inflate:ya,inflateRaw:xa,ungzip:za,constants:Aa};t.Deflate=ba,t.Inflate=va,t.constants=Aa,t.default=Ea,t.deflate=ga,t.deflateRaw=pa,t.gzip=ka,t.inflate=ya,t.inflateRaw=xa,t.ungzip=za,Object.defineProperty(t,\"__esModule\",{value:!0});}));\n\nvar p = /*#__PURE__*/Object.freeze({\n    __proto__: null\n});\n\n/*\n\n Parser for .XKT Format V1\n\n.XKT specifications: https://github.com/xeokit/xeokit-sdk/wiki/XKT-Format\n\n DEPRECATED\n\n */\n\nlet pako$a = window.pako || p;\nif (!pako$a.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako$a = pako$a.default;\n}\n\nconst decompressColor$b = (function () {\n    const color2 = new Float32Array(3);\n    return function (color) {\n        color2[0] = color[0] / 255.0;\n        color2[1] = color[1] / 255.0;\n        color2[2] = color[2] / 255.0;\n        return color2;\n    };\n})();\n\nfunction extract$a(elements) {\n    return {\n        positions: elements[0],\n        normals: elements[1],\n        indices: elements[2],\n        edgeIndices: elements[3],\n        meshPositions: elements[4],\n        meshIndices: elements[5],\n        meshEdgesIndices: elements[6],\n        meshColors: elements[7],\n        entityIDs: elements[8],\n        entityMeshes: elements[9],\n        entityIsObjects: elements[10],\n        positionsDecodeMatrix: elements[11]\n    };\n}\n\nfunction inflate$a(deflatedData) {\n    return {\n        positions: new Uint16Array(pako$a.inflate(deflatedData.positions).buffer),\n        normals: new Int8Array(pako$a.inflate(deflatedData.normals).buffer),\n        indices: new Uint32Array(pako$a.inflate(deflatedData.indices).buffer),\n        edgeIndices: new Uint32Array(pako$a.inflate(deflatedData.edgeIndices).buffer),\n        meshPositions: new Uint32Array(pako$a.inflate(deflatedData.meshPositions).buffer),\n        meshIndices: new Uint32Array(pako$a.inflate(deflatedData.meshIndices).buffer),\n        meshEdgesIndices: new Uint32Array(pako$a.inflate(deflatedData.meshEdgesIndices).buffer),\n        meshColors: new Uint8Array(pako$a.inflate(deflatedData.meshColors).buffer),\n        entityIDs: pako$a.inflate(deflatedData.entityIDs, {to: 'string'}),\n        entityMeshes: new Uint32Array(pako$a.inflate(deflatedData.entityMeshes).buffer),\n        entityIsObjects: new Uint8Array(pako$a.inflate(deflatedData.entityIsObjects).buffer),\n        positionsDecodeMatrix: new Float32Array(pako$a.inflate(deflatedData.positionsDecodeMatrix).buffer)\n    };\n}\n\nfunction load$b(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    manifestCtx.getNextId();\n\n    sceneModel.positionsCompression = \"precompressed\";\n    sceneModel.normalsCompression = \"precompressed\";\n\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n    const meshPositions = inflatedData.meshPositions;\n    const meshIndices = inflatedData.meshIndices;\n    const meshEdgesIndices = inflatedData.meshEdgesIndices;\n    const meshColors = inflatedData.meshColors;\n    const entityIDs = JSON.parse(inflatedData.entityIDs);\n    const entityMeshes = inflatedData.entityMeshes;\n    const entityIsObjects = inflatedData.entityIsObjects;\n    const numMeshes = meshPositions.length;\n    const numEntities = entityMeshes.length;\n\n    for (let i = 0; i < numEntities; i++) {\n\n        const xktEntityId = entityIDs [i];\n        const entityId = options.globalizeObjectIds ? math.globalizeObjectId(sceneModel.id, xktEntityId) : xktEntityId;\n        const metaObject = viewer.metaScene.metaObjects[entityId];\n        const entityDefaults = {};\n        const meshDefaults = {};\n\n        if (metaObject) {\n\n            if (options.excludeTypesMap && metaObject.type && options.excludeTypesMap[metaObject.type]) {\n                continue;\n            }\n\n            if (options.includeTypesMap && metaObject.type && (!options.includeTypesMap[metaObject.type])) {\n                continue;\n            }\n\n            const props = options.objectDefaults ? options.objectDefaults[metaObject.type] || options.objectDefaults[\"DEFAULT\"] : null;\n\n            if (props) {\n                if (props.visible === false) {\n                    entityDefaults.visible = false;\n                }\n                if (props.pickable === false) {\n                    entityDefaults.pickable = false;\n                }\n                if (props.colorize) {\n                    meshDefaults.color = props.colorize;\n                }\n                if (props.opacity !== undefined && props.opacity !== null) {\n                    meshDefaults.opacity = props.opacity;\n                }\n            }\n        } else {\n            if (options.excludeUnclassifiedObjects) {\n                continue;\n            }\n        }\n\n        const lastEntity = (i === numEntities - 1);\n        const meshIds = [];\n\n        for (let j = entityMeshes [i], jlen = lastEntity ? entityMeshes.length : entityMeshes [i + 1]; j < jlen; j++) {\n\n            const lastMesh = (j === (numMeshes - 1));\n            const meshId = entityId + \".mesh.\" + j;\n\n            const color = decompressColor$b(meshColors.subarray((j * 4), (j * 4) + 3));\n            const opacity = meshColors[(j * 4) + 3] / 255.0;\n\n            sceneModel.createMesh(utils.apply(meshDefaults, {\n                id: meshId,\n                primitive: \"triangles\",\n                positionsCompressed: positions.subarray(meshPositions [j], lastMesh ? positions.length : meshPositions [j + 1]),\n                normalsCompressed: normals.subarray(meshPositions [j], lastMesh ? positions.length : meshPositions [j + 1]),\n                indices: indices.subarray(meshIndices [j], lastMesh ? indices.length : meshIndices [j + 1]),\n                edgeIndices: edgeIndices.subarray(meshEdgesIndices [j], lastMesh ? edgeIndices.length : meshEdgesIndices [j + 1]),\n                positionsDecodeMatrix: inflatedData.positionsDecodeMatrix,\n                color: color,\n                opacity: opacity\n            }));\n\n            meshIds.push(meshId);\n        }\n\n        sceneModel.createEntity(utils.apply(entityDefaults, {\n            id: entityId,\n            isObject: (entityIsObjects [i] === 1),\n            meshIds: meshIds\n        }));\n    }\n}\n\n/** @private */\nconst ParserV1 = {\n    version: 1,\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract$a(elements);\n        const inflatedData = inflate$a(deflatedData);\n        load$b(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n\nParser for .XKT Format V2\n\nDEPRECATED\n\n.XKT specifications: https://github.com/xeokit/xeokit-sdk/wiki/XKT-Format\n\n */\n\nlet pako$9 = window.pako || p;\nif (!pako$9.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako$9 = pako$9.default;\n}\n\nfunction extract$9(elements) {\n    return {\n\n        positions: elements[0],\n        normals: elements[1],\n        indices: elements[2],\n        edgeIndices: elements[3],\n\n        meshPositions: elements[4],\n        meshIndices: elements[5],\n        meshEdgesIndices: elements[6],\n        meshColors: elements[7],\n\n        entityIDs: elements[8],\n        entityMeshes: elements[9],\n        entityIsObjects: elements[10],\n\n        positionsDecodeMatrix: elements[11],\n\n        entityMeshIds: elements[12],\n        entityMatrices: elements[13],\n        entityUsesInstancing: elements[14]\n    };\n}\n\nfunction inflate$9(deflatedData) {\n    return {\n        positions: new Uint16Array(pako$9.inflate(deflatedData.positions).buffer),\n        normals: new Int8Array(pako$9.inflate(deflatedData.normals).buffer),\n        indices: new Uint32Array(pako$9.inflate(deflatedData.indices).buffer),\n        edgeIndices: new Uint32Array(pako$9.inflate(deflatedData.edgeIndices).buffer),\n\n        meshPositions: new Uint32Array(pako$9.inflate(deflatedData.meshPositions).buffer),\n        meshIndices: new Uint32Array(pako$9.inflate(deflatedData.meshIndices).buffer),\n        meshEdgesIndices: new Uint32Array(pako$9.inflate(deflatedData.meshEdgesIndices).buffer),\n        meshColors: new Uint8Array(pako$9.inflate(deflatedData.meshColors).buffer),\n\n        entityIDs: pako$9.inflate(deflatedData.entityIDs, {to: 'string'}),\n        entityMeshes: new Uint32Array(pako$9.inflate(deflatedData.entityMeshes).buffer),\n        entityIsObjects: new Uint8Array(pako$9.inflate(deflatedData.entityIsObjects).buffer),\n\n        positionsDecodeMatrix: new Float32Array(pako$9.inflate(deflatedData.positionsDecodeMatrix).buffer),\n\n        entityMeshIds: new Uint32Array(pako$9.inflate(deflatedData.entityMeshIds).buffer),\n        entityMatrices: new Float32Array(pako$9.inflate(deflatedData.entityMatrices).buffer),\n        entityUsesInstancing: new Uint8Array(pako$9.inflate(deflatedData.entityUsesInstancing).buffer)\n    };\n}\n\nconst decompressColor$a = (function () {\n    const color2 = new Float32Array(3);\n    return function (color) {\n        color2[0] = color[0] / 255.0;\n        color2[1] = color[1] / 255.0;\n        color2[2] = color[2] / 255.0;\n        return color2;\n    };\n})();\n\nfunction load$a(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    sceneModel.positionsCompression = \"precompressed\";\n    sceneModel.normalsCompression = \"precompressed\";\n\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n    const meshPositions = inflatedData.meshPositions;\n    const meshIndices = inflatedData.meshIndices;\n    const meshEdgesIndices = inflatedData.meshEdgesIndices;\n    const meshColors = inflatedData.meshColors;\n    const entityIDs = JSON.parse(inflatedData.entityIDs);\n    const entityMeshes = inflatedData.entityMeshes;\n    const entityIsObjects = inflatedData.entityIsObjects;\n    const entityMeshIds = inflatedData.entityMeshIds;\n    const entityMatrices = inflatedData.entityMatrices;\n    const entityUsesInstancing = inflatedData.entityUsesInstancing;\n\n    const numMeshes = meshPositions.length;\n    const numEntities = entityMeshes.length;\n\n    const alreadyCreatedGeometries = {};\n\n    for (let i = 0; i < numEntities; i++) {\n\n        const xktEntityId = entityIDs [i];\n        const entityId = options.globalizeObjectIds ? math.globalizeObjectId(sceneModel.id, xktEntityId) : xktEntityId;\n        const metaObject = viewer.metaScene.metaObjects[entityId];\n        const entityDefaults = {};\n        const meshDefaults = {};\n        const entityMatrix = entityMatrices.subarray((i * 16), (i * 16) + 16);\n\n        if (metaObject) {\n            if (options.excludeTypesMap && metaObject.type && options.excludeTypesMap[metaObject.type]) {\n                continue;\n            }\n            if (options.includeTypesMap && metaObject.type && (!options.includeTypesMap[metaObject.type])) {\n                continue;\n            }\n            const props = options.objectDefaults ? options.objectDefaults[metaObject.type] || options.objectDefaults[\"DEFAULT\"] : null;\n            if (props) {\n                if (props.visible === false) {\n                    entityDefaults.visible = false;\n                }\n                if (props.pickable === false) {\n                    entityDefaults.pickable = false;\n                }\n                if (props.colorize) {\n                    meshDefaults.color = props.colorize;\n                }\n                if (props.opacity !== undefined && props.opacity !== null) {\n                    meshDefaults.opacity = props.opacity;\n                }\n            }\n        } else {\n            if (options.excludeUnclassifiedObjects) {\n                continue;\n            }\n        }\n\n        const lastEntity = (i === numEntities - 1);\n\n        const meshIds = [];\n\n        for (let j = entityMeshes [i], jlen = lastEntity ? entityMeshIds.length : entityMeshes [i + 1]; j < jlen; j++) {\n\n            const jj = entityMeshIds [j];\n\n            const lastMesh = (jj === (numMeshes - 1));\n            const meshId = manifestCtx.getNextId();\n\n            const color = decompressColor$a(meshColors.subarray((jj * 4), (jj * 4) + 3));\n            const opacity = meshColors[(jj * 4) + 3] / 255.0;\n\n            const tmpPositions = positions.subarray(meshPositions [jj], lastMesh ? positions.length : meshPositions [jj + 1]);\n            const tmpNormals = normals.subarray(meshPositions [jj], lastMesh ? positions.length : meshPositions [jj + 1]);\n            const tmpIndices = indices.subarray(meshIndices [jj], lastMesh ? indices.length : meshIndices [jj + 1]);\n            const tmpEdgeIndices = edgeIndices.subarray(meshEdgesIndices [jj], lastMesh ? edgeIndices.length : meshEdgesIndices [jj + 1]);\n\n            if (entityUsesInstancing [i] === 1) {\n\n                const geometryId = `${modelPartId}.geometry.${meshId}.${jj}`;\n\n                if (!(geometryId in alreadyCreatedGeometries)) {\n\n                    sceneModel.createGeometry({\n                        id: geometryId,\n                        positionsCompressed: tmpPositions,\n                        normalsCompressed: tmpNormals,\n                        indices: tmpIndices,\n                        edgeIndices: tmpEdgeIndices,\n                        primitive: \"triangles\",\n                        positionsDecodeMatrix: inflatedData.positionsDecodeMatrix,\n                    });\n\n                    alreadyCreatedGeometries [geometryId] = true;\n                }\n\n                sceneModel.createMesh(utils.apply(meshDefaults, {\n                    id: meshId,\n                    color: color,\n                    opacity: opacity,\n                    matrix: entityMatrix,\n                    geometryId,\n                }));\n\n                meshIds.push(meshId);\n\n            } else {\n\n                sceneModel.createMesh(utils.apply(meshDefaults, {\n                    id: meshId,\n                    primitive: \"triangles\",\n                    positionsCompressed: tmpPositions,\n                    normalsCompressed: tmpNormals,\n                    indices: tmpIndices,\n                    edgeIndices: tmpEdgeIndices,\n                    positionsDecodeMatrix: inflatedData.positionsDecodeMatrix,\n                    color: color,\n                    opacity: opacity\n                }));\n\n                meshIds.push(meshId);\n            }\n        }\n\n        if (meshIds.length) {\n\n            sceneModel.createEntity(utils.apply(entityDefaults, {\n                id: entityId,\n                isObject: (entityIsObjects [i] === 1),\n                meshIds: meshIds\n            }));\n        }\n    }\n}\n\n/** @private */\nconst ParserV2 = {\n    version: 2,\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract$9(elements);\n        const inflatedData = inflate$9(deflatedData);\n        load$a(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n\nParser for .XKT Format V3\n\n.XKT specifications: https://github.com/xeokit/xeokit-sdk/wiki/XKT-Format\n\n */\n\nlet pako$8 = window.pako || p;\nif (!pako$8.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako$8 = pako$8.default;\n}\n\nfunction extract$8(elements) {\n    return {\n        positions: elements[0],\n        normals: elements[1],\n        indices: elements[2],\n        edgeIndices: elements[3],\n        meshPositions: elements[4],\n        meshIndices: elements[5],\n        meshEdgesIndices: elements[6],\n        meshColors: elements[7],\n        entityIDs: elements[8],\n        entityMeshes: elements[9],\n        entityIsObjects: elements[10],\n        instancedPositionsDecodeMatrix: elements[11],\n        batchedPositionsDecodeMatrix: elements[12],\n        entityMeshIds: elements[13],\n        entityMatrices: elements[14],\n        entityUsesInstancing: elements[15]\n    };\n}\n\nfunction inflate$8(deflatedData) {\n    return {\n        positions: new Uint16Array(pako$8.inflate(deflatedData.positions).buffer),\n        normals: new Int8Array(pako$8.inflate(deflatedData.normals).buffer),\n        indices: new Uint32Array(pako$8.inflate(deflatedData.indices).buffer),\n        edgeIndices: new Uint32Array(pako$8.inflate(deflatedData.edgeIndices).buffer),\n        meshPositions: new Uint32Array(pako$8.inflate(deflatedData.meshPositions).buffer),\n        meshIndices: new Uint32Array(pako$8.inflate(deflatedData.meshIndices).buffer),\n        meshEdgesIndices: new Uint32Array(pako$8.inflate(deflatedData.meshEdgesIndices).buffer),\n        meshColors: new Uint8Array(pako$8.inflate(deflatedData.meshColors).buffer),\n        entityIDs: pako$8.inflate(deflatedData.entityIDs, {to: 'string'}),\n        entityMeshes: new Uint32Array(pako$8.inflate(deflatedData.entityMeshes).buffer),\n        entityIsObjects: new Uint8Array(pako$8.inflate(deflatedData.entityIsObjects).buffer),\n        instancedPositionsDecodeMatrix: new Float32Array(pako$8.inflate(deflatedData.instancedPositionsDecodeMatrix).buffer),\n        batchedPositionsDecodeMatrix: new Float32Array(pako$8.inflate(deflatedData.batchedPositionsDecodeMatrix).buffer),\n        entityMeshIds: new Uint32Array(pako$8.inflate(deflatedData.entityMeshIds).buffer),\n        entityMatrices: new Float32Array(pako$8.inflate(deflatedData.entityMatrices).buffer),\n        entityUsesInstancing: new Uint8Array(pako$8.inflate(deflatedData.entityUsesInstancing).buffer)\n    };\n}\n\nconst decompressColor$9 = (function () {\n    const color2 = new Float32Array(3);\n    return function (color) {\n        color2[0] = color[0] / 255.0;\n        color2[1] = color[1] / 255.0;\n        color2[2] = color[2] / 255.0;\n        return color2;\n    };\n})();\n\nfunction load$9(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    sceneModel.positionsCompression = \"precompressed\";\n    sceneModel.normalsCompression = \"precompressed\";\n\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n    const meshPositions = inflatedData.meshPositions;\n    const meshIndices = inflatedData.meshIndices;\n    const meshEdgesIndices = inflatedData.meshEdgesIndices;\n    const meshColors = inflatedData.meshColors;\n    const entityIDs = JSON.parse(inflatedData.entityIDs);\n    const entityMeshes = inflatedData.entityMeshes;\n    const entityIsObjects = inflatedData.entityIsObjects;\n    const entityMeshIds = inflatedData.entityMeshIds;\n    const entityMatrices = inflatedData.entityMatrices;\n    const entityUsesInstancing = inflatedData.entityUsesInstancing;\n\n    const numMeshes = meshPositions.length;\n    const numEntities = entityMeshes.length;\n\n    const _alreadyCreatedGeometries = {};\n\n    for (let i = 0; i < numEntities; i++) {\n\n        const xktEntityId = entityIDs [i];\n        const entityId = options.globalizeObjectIds ? math.globalizeObjectId(sceneModel.id, xktEntityId) : xktEntityId;\n        const metaObject = viewer.metaScene.metaObjects[entityId];\n        const entityDefaults = {};\n        const meshDefaults = {};\n        const entityMatrix = entityMatrices.subarray((i * 16), (i * 16) + 16);\n\n        if (metaObject) {\n\n            if (options.excludeTypesMap && metaObject.type && options.excludeTypesMap[metaObject.type]) {\n                continue;\n            }\n\n            if (options.includeTypesMap && metaObject.type && (!options.includeTypesMap[metaObject.type])) {\n                continue;\n            }\n\n            const props = options.objectDefaults ? options.objectDefaults[metaObject.type] || options.objectDefaults[\"DEFAULT\"] : null;\n\n            if (props) {\n                if (props.visible === false) {\n                    entityDefaults.visible = false;\n                }\n                if (props.pickable === false) {\n                    entityDefaults.pickable = false;\n                }\n                if (props.colorize) {\n                    meshDefaults.color = props.colorize;\n                }\n                if (props.opacity !== undefined && props.opacity !== null) {\n                    meshDefaults.opacity = props.opacity;\n                }\n            }\n        } else {\n            if (options.excludeUnclassifiedObjects) {\n                continue;\n            }\n        }\n\n        const lastEntity = (i === numEntities - 1);\n\n        const meshIds = [];\n\n        for (let j = entityMeshes [i], jlen = lastEntity ? entityMeshIds.length : entityMeshes [i + 1]; j < jlen; j++) {\n            var jj = entityMeshIds [j];\n\n            const lastMesh = (jj === (numMeshes - 1));\n            const meshId = `${modelPartId}.${entityId}.mesh.${jj}`;\n\n            const color = decompressColor$9(meshColors.subarray((jj * 4), (jj * 4) + 3));\n            const opacity = meshColors[(jj * 4) + 3] / 255.0;\n\n            var tmpPositions = positions.subarray(meshPositions [jj], lastMesh ? positions.length : meshPositions [jj + 1]);\n            var tmpNormals = normals.subarray(meshPositions [jj], lastMesh ? positions.length : meshPositions [jj + 1]);\n            var tmpIndices = indices.subarray(meshIndices [jj], lastMesh ? indices.length : meshIndices [jj + 1]);\n            var tmpEdgeIndices = edgeIndices.subarray(meshEdgesIndices [jj], lastMesh ? edgeIndices.length : meshEdgesIndices [jj + 1]);\n\n            if (entityUsesInstancing [i] === 1) {\n\n                const geometryId = `${modelPartId}.geometry.${meshId}.${jj}`;\n\n                if (!(geometryId in _alreadyCreatedGeometries)) {\n\n                    sceneModel.createGeometry({\n                        id: geometryId,\n                        positionsCompressed: tmpPositions,\n                        normalsCompressed: tmpNormals,\n                        indices: tmpIndices,\n                        edgeIndices: tmpEdgeIndices,\n                        primitive: \"triangles\",\n                        positionsDecodeMatrix: inflatedData.instancedPositionsDecodeMatrix\n                    });\n\n                    _alreadyCreatedGeometries [geometryId] = true;\n                }\n\n                sceneModel.createMesh(utils.apply(meshDefaults, {\n                    id: meshId,\n                    color: color,\n                    opacity: opacity,\n                    matrix: entityMatrix,\n                    geometryId,\n                }));\n\n                meshIds.push(meshId);\n\n            } else {\n\n                sceneModel.createMesh(utils.apply(meshDefaults, {\n                    id: meshId,\n                    primitive: \"triangles\",\n                    positionsCompressed: tmpPositions,\n                    normalsCompressed: tmpNormals,\n                    indices: tmpIndices,\n                    edgeIndices: tmpEdgeIndices,\n                    positionsDecodeMatrix: inflatedData.batchedPositionsDecodeMatrix,\n                    color: color,\n                    opacity: opacity\n                }));\n\n                meshIds.push(meshId);\n            }\n        }\n\n        if (meshIds.length) {\n            sceneModel.createEntity(utils.apply(entityDefaults, {\n                id: entityId,\n                isObject: (entityIsObjects [i] === 1),\n                meshIds: meshIds\n            }));\n        }\n    }\n}\n\n/** @private */\nconst ParserV3 = {\n    version: 3,\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract$8(elements);\n        const inflatedData = inflate$8(deflatedData);\n        load$9(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n\nParser for .XKT Format V4\n\n.XKT specifications: https://github.com/xeokit/xeokit-sdk/wiki/XKT-Format\n\n */\n\nlet pako$7 = window.pako || p;\nif (!pako$7.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako$7 = pako$7.default;\n}\n\nfunction extract$7(elements) {\n    return {\n        positions: elements[0],\n        normals: elements[1],\n        indices: elements[2],\n        edgeIndices: elements[3],\n        decodeMatrices: elements[4],\n        matrices: elements[5],\n        eachPrimitivePositionsAndNormalsPortion: elements[6],\n        eachPrimitiveIndicesPortion: elements[7],\n        eachPrimitiveEdgeIndicesPortion: elements[8],\n        eachPrimitiveDecodeMatricesPortion: elements[9],\n        eachPrimitiveColor: elements[10],\n        primitiveInstances: elements[11],\n        eachEntityId: elements[12],\n        eachEntityPrimitiveInstancesPortion: elements[13],\n        eachEntityMatricesPortion: elements[14],\n        eachEntityMatrix: elements[15]\n    };\n}\n\nfunction inflate$7(deflatedData) {\n    return {\n        positions: new Uint16Array(pako$7.inflate(deflatedData.positions).buffer),\n        normals: new Int8Array(pako$7.inflate(deflatedData.normals).buffer),\n        indices: new Uint32Array(pako$7.inflate(deflatedData.indices).buffer),\n        edgeIndices: new Uint32Array(pako$7.inflate(deflatedData.edgeIndices).buffer),\n        decodeMatrices: new Float32Array(pako$7.inflate(deflatedData.decodeMatrices).buffer),\n        matrices: new Float32Array(pako$7.inflate(deflatedData.matrices).buffer),\n        eachPrimitivePositionsAndNormalsPortion: new Uint32Array(pako$7.inflate(deflatedData.eachPrimitivePositionsAndNormalsPortion).buffer),\n        eachPrimitiveIndicesPortion: new Uint32Array(pako$7.inflate(deflatedData.eachPrimitiveIndicesPortion).buffer),\n        eachPrimitiveEdgeIndicesPortion: new Uint32Array(pako$7.inflate(deflatedData.eachPrimitiveEdgeIndicesPortion).buffer),\n        eachPrimitiveDecodeMatricesPortion: new Uint32Array(pako$7.inflate(deflatedData.eachPrimitiveDecodeMatricesPortion).buffer),\n        eachPrimitiveColor: new Uint8Array(pako$7.inflate(deflatedData.eachPrimitiveColor).buffer),\n        primitiveInstances: new Uint32Array(pako$7.inflate(deflatedData.primitiveInstances).buffer),\n        eachEntityId: pako$7.inflate(deflatedData.eachEntityId, {to: 'string'}),\n        eachEntityPrimitiveInstancesPortion: new Uint32Array(pako$7.inflate(deflatedData.eachEntityPrimitiveInstancesPortion).buffer),\n        eachEntityMatricesPortion: new Uint32Array(pako$7.inflate(deflatedData.eachEntityMatricesPortion).buffer)\n    };\n}\n\nconst decompressColor$8 = (function () {\n    const color2 = new Float32Array(3);\n    return function (color) {\n        color2[0] = color[0] / 255.0;\n        color2[1] = color[1] / 255.0;\n        color2[2] = color[2] / 255.0;\n        return color2;\n    };\n})();\n\nfunction load$8(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    sceneModel.positionsCompression = \"precompressed\";\n    sceneModel.normalsCompression = \"precompressed\";\n\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n    const decodeMatrices = inflatedData.decodeMatrices;\n    const matrices = inflatedData.matrices;\n\n    const eachPrimitivePositionsAndNormalsPortion = inflatedData.eachPrimitivePositionsAndNormalsPortion;\n    const eachPrimitiveIndicesPortion = inflatedData.eachPrimitiveIndicesPortion;\n    const eachPrimitiveEdgeIndicesPortion = inflatedData.eachPrimitiveEdgeIndicesPortion;\n    const eachPrimitiveDecodeMatricesPortion = inflatedData.eachPrimitiveDecodeMatricesPortion;\n    const eachPrimitiveColor = inflatedData.eachPrimitiveColor;\n\n    const primitiveInstances = inflatedData.primitiveInstances;\n\n    const eachEntityId = JSON.parse(inflatedData.eachEntityId);\n    const eachEntityPrimitiveInstancesPortion = inflatedData.eachEntityPrimitiveInstancesPortion;\n    const eachEntityMatricesPortion = inflatedData.eachEntityMatricesPortion;\n\n    const numPrimitives = eachPrimitivePositionsAndNormalsPortion.length;\n    const numPrimitiveInstances = primitiveInstances.length;\n    const primitiveInstanceCounts = new Uint8Array(numPrimitives); // For each mesh, how many times it is instanced\n    const orderedPrimitiveIndexes = new Uint32Array(numPrimitives); // For each mesh, its index sorted into runs that share the same decode matrix\n\n    const numEntities = eachEntityId.length;\n\n    // Get lookup that orders primitives into runs that share the same decode matrices;\n    // this is used to create meshes in batches that use the same decode matrix\n\n    for (let primitiveIndex = 0; primitiveIndex < numPrimitives; primitiveIndex++) {\n        orderedPrimitiveIndexes[primitiveIndex] = primitiveIndex;\n    }\n\n    orderedPrimitiveIndexes.sort((i1, i2) => {\n        if (eachPrimitiveDecodeMatricesPortion[i1] < eachPrimitiveDecodeMatricesPortion[i2]) {\n            return -1;\n        }\n        if (eachPrimitiveDecodeMatricesPortion[i1] > eachPrimitiveDecodeMatricesPortion[i2]) {\n            return 1;\n        }\n        return 0;\n    });\n\n    // Count instances of each primitive\n\n    for (let primitiveInstanceIndex = 0; primitiveInstanceIndex < numPrimitiveInstances; primitiveInstanceIndex++) {\n        const primitiveIndex = primitiveInstances[primitiveInstanceIndex];\n        primitiveInstanceCounts[primitiveIndex]++;\n    }\n\n    // Map batched primitives to the entities that will use them\n\n    const batchedPrimitiveEntityIndexes = {};\n\n    for (let entityIndex = 0; entityIndex < numEntities; entityIndex++) {\n\n        const lastEntityIndex = (numEntities - 1);\n        const atLastEntity = (entityIndex === lastEntityIndex);\n        const firstEntityPrimitiveInstanceIndex = eachEntityPrimitiveInstancesPortion [entityIndex];\n        const lastEntityPrimitiveInstanceIndex = atLastEntity ? eachEntityPrimitiveInstancesPortion[lastEntityIndex] : eachEntityPrimitiveInstancesPortion[entityIndex + 1];\n\n        for (let primitiveInstancesIndex = firstEntityPrimitiveInstanceIndex; primitiveInstancesIndex < lastEntityPrimitiveInstanceIndex; primitiveInstancesIndex++) {\n\n            const primitiveIndex = primitiveInstances[primitiveInstancesIndex];\n            const primitiveInstanceCount = primitiveInstanceCounts[primitiveIndex];\n            const isInstancedPrimitive = (primitiveInstanceCount > 1);\n\n            if (!isInstancedPrimitive) {\n                batchedPrimitiveEntityIndexes[primitiveIndex] = entityIndex;\n            }\n        }\n    }\n\n    // Create 1) geometries for instanced primitives, and 2) meshes for batched primitives.  We create all the\n    // batched meshes now, before we create entities, because we're creating the batched meshes in runs that share\n    // the same decode matrices. Each run of meshes with the same decode matrix will end up in the same\n    // BatchingLayer; the SceneModel#createMesh() method starts a new BatchingLayer each time the decode\n    // matrix has changed since the last invocation of that method, hence why we need to order batched meshes\n    // in runs like this.\n\n    for (let primitiveIndex = 0; primitiveIndex < numPrimitives; primitiveIndex++) {\n\n        const orderedPrimitiveIndex = orderedPrimitiveIndexes[primitiveIndex];\n\n        const atLastPrimitive = (orderedPrimitiveIndex === (numPrimitives - 1));\n\n        const primitiveInstanceCount = primitiveInstanceCounts[orderedPrimitiveIndex];\n        const isInstancedPrimitive = (primitiveInstanceCount > 1);\n\n        const color = decompressColor$8(eachPrimitiveColor.subarray((orderedPrimitiveIndex * 4), (orderedPrimitiveIndex * 4) + 3));\n        const opacity = eachPrimitiveColor[(orderedPrimitiveIndex * 4) + 3] / 255.0;\n\n        const primitivePositions = positions.subarray(eachPrimitivePositionsAndNormalsPortion [orderedPrimitiveIndex], atLastPrimitive ? positions.length : eachPrimitivePositionsAndNormalsPortion [orderedPrimitiveIndex + 1]);\n        const primitiveNormals = normals.subarray(eachPrimitivePositionsAndNormalsPortion [orderedPrimitiveIndex], atLastPrimitive ? normals.length : eachPrimitivePositionsAndNormalsPortion [orderedPrimitiveIndex + 1]);\n        const primitiveIndices = indices.subarray(eachPrimitiveIndicesPortion [orderedPrimitiveIndex], atLastPrimitive ? indices.length : eachPrimitiveIndicesPortion [orderedPrimitiveIndex + 1]);\n        const primitiveEdgeIndices = edgeIndices.subarray(eachPrimitiveEdgeIndicesPortion [orderedPrimitiveIndex], atLastPrimitive ? edgeIndices.length : eachPrimitiveEdgeIndicesPortion [orderedPrimitiveIndex + 1]);\n        const primitiveDecodeMatrix = decodeMatrices.subarray(eachPrimitiveDecodeMatricesPortion [orderedPrimitiveIndex], eachPrimitiveDecodeMatricesPortion [orderedPrimitiveIndex] + 16);\n\n        if (isInstancedPrimitive) {\n\n            // Primitive instanced by more than one entity, and has positions in Model-space\n\n           const geometryId = `${modelPartId}-geometry.${orderedPrimitiveIndex}`; // These IDs are local to the SceneModel\n\n            sceneModel.createGeometry({\n                id: geometryId,\n                primitive: \"triangles\",\n                positionsCompressed: primitivePositions,\n                normalsCompressed: primitiveNormals,\n                indices: primitiveIndices,\n                edgeIndices: primitiveEdgeIndices,\n                positionsDecodeMatrix: primitiveDecodeMatrix\n            });\n\n        } else {\n\n            // Primitive is used only by one entity, and has positions pre-transformed into World-space\n\n            const meshId = `${modelPartId}-${orderedPrimitiveIndex}`;\n\n            const entityIndex = batchedPrimitiveEntityIndexes[orderedPrimitiveIndex];\n            eachEntityId[entityIndex];\n\n            const meshDefaults = {}; // TODO: get from lookup from entity IDs\n\n            sceneModel.createMesh(utils.apply(meshDefaults, {\n                id: meshId,\n                primitive: \"triangles\",\n                positionsCompressed: primitivePositions,\n                normalsCompressed: primitiveNormals,\n                indices: primitiveIndices,\n                edgeIndices: primitiveEdgeIndices,\n                positionsDecodeMatrix: primitiveDecodeMatrix,\n                color: color,\n                opacity: opacity\n            }));\n        }\n    }\n\n    let countInstances = 0;\n\n    for (let entityIndex = 0; entityIndex < numEntities; entityIndex++) {\n\n        const lastEntityIndex = (numEntities - 1);\n        const atLastEntity = (entityIndex === lastEntityIndex);\n        const entityId = eachEntityId[entityIndex];\n        const firstEntityPrimitiveInstanceIndex = eachEntityPrimitiveInstancesPortion [entityIndex];\n        const lastEntityPrimitiveInstanceIndex = atLastEntity ? eachEntityPrimitiveInstancesPortion[lastEntityIndex] : eachEntityPrimitiveInstancesPortion[entityIndex + 1];\n\n        const meshIds = [];\n\n        for (let primitiveInstancesIndex = firstEntityPrimitiveInstanceIndex; primitiveInstancesIndex < lastEntityPrimitiveInstanceIndex; primitiveInstancesIndex++) {\n\n            const primitiveIndex = primitiveInstances[primitiveInstancesIndex];\n            const primitiveInstanceCount = primitiveInstanceCounts[primitiveIndex];\n            const isInstancedPrimitive = (primitiveInstanceCount > 1);\n\n            if (isInstancedPrimitive) {\n\n                const meshDefaults = {}; // TODO: get from lookup from entity IDs\n\n                const meshId = `${modelPartId}-instance.${countInstances++}`;\n                const geometryId = `${modelPartId}-geometry.${primitiveIndex}`; // These IDs are local to the SceneModel\n\n                const matricesIndex = (eachEntityMatricesPortion [entityIndex]) * 16;\n                const matrix = matrices.subarray(matricesIndex, matricesIndex + 16);\n\n                sceneModel.createMesh(utils.apply(meshDefaults, {\n                    id: meshId,\n                    geometryId: geometryId,\n                    matrix: matrix\n                }));\n\n                meshIds.push(meshId);\n\n            } else {\n                meshIds.push(primitiveIndex);\n            }\n        }\n\n        if (meshIds.length > 0) {\n\n            const entityDefaults = {}; // TODO: get from lookup from entity IDs\n\n            sceneModel.createEntity(utils.apply(entityDefaults, {\n                id: entityId,\n                isObject: true, ///////////////// TODO: If metaobject exists\n                meshIds: meshIds\n            }));\n        }\n    }\n}\n\n/** @private */\nconst ParserV4 = {\n    version: 4,\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract$7(elements);\n        const inflatedData = inflate$7(deflatedData);\n        load$8(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n\n Parser for .XKT Format V5\n\n.XKT specifications: https://github.com/xeokit/xeokit-sdk/wiki/XKT-Format\n\n */\n\nlet pako$6 = window.pako || p;\nif (!pako$6.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako$6 = pako$6.default;\n}\n\nfunction extract$6(elements) {\n    return {\n        positions: elements[0],\n        normals: elements[1],\n        indices: elements[2],\n        edgeIndices: elements[3],\n        matrices: elements[4],\n        eachPrimitivePositionsAndNormalsPortion: elements[5],\n        eachPrimitiveIndicesPortion: elements[6],\n        eachPrimitiveEdgeIndicesPortion: elements[7],\n        eachPrimitiveColor: elements[8],\n        primitiveInstances: elements[9],\n        eachEntityId: elements[10],\n        eachEntityPrimitiveInstancesPortion: elements[11],\n        eachEntityMatricesPortion: elements[12]\n    };\n}\n\nfunction inflate$6(deflatedData) {\n    return {\n        positions: new Float32Array(pako$6.inflate(deflatedData.positions).buffer),\n        normals: new Int8Array(pako$6.inflate(deflatedData.normals).buffer),\n        indices: new Uint32Array(pako$6.inflate(deflatedData.indices).buffer),\n        edgeIndices: new Uint32Array(pako$6.inflate(deflatedData.edgeIndices).buffer),\n        matrices: new Float32Array(pako$6.inflate(deflatedData.matrices).buffer),\n        eachPrimitivePositionsAndNormalsPortion: new Uint32Array(pako$6.inflate(deflatedData.eachPrimitivePositionsAndNormalsPortion).buffer),\n        eachPrimitiveIndicesPortion: new Uint32Array(pako$6.inflate(deflatedData.eachPrimitiveIndicesPortion).buffer),\n        eachPrimitiveEdgeIndicesPortion: new Uint32Array(pako$6.inflate(deflatedData.eachPrimitiveEdgeIndicesPortion).buffer),\n        eachPrimitiveColor: new Uint8Array(pako$6.inflate(deflatedData.eachPrimitiveColor).buffer),\n        primitiveInstances: new Uint32Array(pako$6.inflate(deflatedData.primitiveInstances).buffer),\n        eachEntityId: pako$6.inflate(deflatedData.eachEntityId, {to: 'string'}),\n        eachEntityPrimitiveInstancesPortion: new Uint32Array(pako$6.inflate(deflatedData.eachEntityPrimitiveInstancesPortion).buffer),\n        eachEntityMatricesPortion: new Uint32Array(pako$6.inflate(deflatedData.eachEntityMatricesPortion).buffer)\n    };\n}\n\nconst decompressColor$7 = (function () {\n    const color2 = new Float32Array(3);\n    return function (color) {\n        color2[0] = color[0] / 255.0;\n        color2[1] = color[1] / 255.0;\n        color2[2] = color[2] / 255.0;\n        return color2;\n    };\n})();\n\nfunction load$7(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    sceneModel.positionsCompression = \"disabled\"; // Positions in XKT V4 are floats, which we never quantize, for precision with big models\n    sceneModel.normalsCompression = \"precompressed\"; // Normals are oct-encoded though\n\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n    const matrices = inflatedData.matrices;\n\n    const eachPrimitivePositionsAndNormalsPortion = inflatedData.eachPrimitivePositionsAndNormalsPortion;\n    const eachPrimitiveIndicesPortion = inflatedData.eachPrimitiveIndicesPortion;\n    const eachPrimitiveEdgeIndicesPortion = inflatedData.eachPrimitiveEdgeIndicesPortion;\n    const eachPrimitiveColor = inflatedData.eachPrimitiveColor;\n\n    const primitiveInstances = inflatedData.primitiveInstances;\n\n    const eachEntityId = JSON.parse(inflatedData.eachEntityId);\n    const eachEntityPrimitiveInstancesPortion = inflatedData.eachEntityPrimitiveInstancesPortion;\n    const eachEntityMatricesPortion = inflatedData.eachEntityMatricesPortion;\n\n    const numPrimitives = eachPrimitivePositionsAndNormalsPortion.length;\n    const numPrimitiveInstances = primitiveInstances.length;\n    const primitiveInstanceCounts = new Uint8Array(numPrimitives); // For each mesh, how many times it is instanced\n\n    const numEntities = eachEntityId.length;\n\n    // Count instances of each primitive\n\n    for (let primitiveInstanceIndex = 0; primitiveInstanceIndex < numPrimitiveInstances; primitiveInstanceIndex++) {\n        const primitiveIndex = primitiveInstances[primitiveInstanceIndex];\n        primitiveInstanceCounts[primitiveIndex]++;\n    }\n\n    // Map batched primitives to the entities that will use them\n\n    const batchedPrimitiveEntityIndexes = {};\n\n    for (let entityIndex = 0; entityIndex < numEntities; entityIndex++) {\n\n        const lastEntityIndex = (numEntities - 1);\n        const atLastEntity = (entityIndex === lastEntityIndex);\n        const firstEntityPrimitiveInstanceIndex = eachEntityPrimitiveInstancesPortion [entityIndex];\n        const lastEntityPrimitiveInstanceIndex = atLastEntity ? eachEntityPrimitiveInstancesPortion[lastEntityIndex] : eachEntityPrimitiveInstancesPortion[entityIndex + 1];\n\n        for (let primitiveInstancesIndex = firstEntityPrimitiveInstanceIndex; primitiveInstancesIndex < lastEntityPrimitiveInstanceIndex; primitiveInstancesIndex++) {\n\n            const primitiveIndex = primitiveInstances[primitiveInstancesIndex];\n            const primitiveInstanceCount = primitiveInstanceCounts[primitiveIndex];\n            const isInstancedPrimitive = (primitiveInstanceCount > 1);\n\n            if (!isInstancedPrimitive) {\n                batchedPrimitiveEntityIndexes[primitiveIndex] = entityIndex;\n            }\n        }\n    }\n\n    // Create geometries for instanced primitives and meshes for batched primitives.\n\n    for (let primitiveIndex = 0; primitiveIndex < numPrimitives; primitiveIndex++) {\n\n        const atLastPrimitive = (primitiveIndex === (numPrimitives - 1));\n\n        const primitiveInstanceCount = primitiveInstanceCounts[primitiveIndex];\n        const isInstancedPrimitive = (primitiveInstanceCount > 1);\n\n        const color = decompressColor$7(eachPrimitiveColor.subarray((primitiveIndex * 4), (primitiveIndex * 4) + 3));\n        const opacity = eachPrimitiveColor[(primitiveIndex * 4) + 3] / 255.0;\n\n        const primitivePositions = positions.subarray(eachPrimitivePositionsAndNormalsPortion [primitiveIndex], atLastPrimitive ? positions.length : eachPrimitivePositionsAndNormalsPortion [primitiveIndex + 1]);\n        const primitiveNormals = normals.subarray(eachPrimitivePositionsAndNormalsPortion [primitiveIndex], atLastPrimitive ? normals.length : eachPrimitivePositionsAndNormalsPortion [primitiveIndex + 1]);\n        const primitiveIndices = indices.subarray(eachPrimitiveIndicesPortion [primitiveIndex], atLastPrimitive ? indices.length : eachPrimitiveIndicesPortion [primitiveIndex + 1]);\n        const primitiveEdgeIndices = edgeIndices.subarray(eachPrimitiveEdgeIndicesPortion [primitiveIndex], atLastPrimitive ? edgeIndices.length : eachPrimitiveEdgeIndicesPortion [primitiveIndex + 1]);\n\n        if (isInstancedPrimitive) {\n\n            // Primitive instanced by more than one entity, and has positions in Model-space\n\n            const geometryId = `${modelPartId}-geometry.${primitiveIndex}`; // These IDs are local to the SceneModel\n\n            sceneModel.createGeometry({\n                id: geometryId,\n                primitive: \"triangles\",\n                positionsCompressed: primitivePositions,\n                normalsCompressed: primitiveNormals,\n                indices: primitiveIndices,\n                edgeIndices: primitiveEdgeIndices\n            });\n\n        } else {\n\n            // Primitive is used only by one entity, and has positions pre-transformed into World-space\n\n            const meshId = primitiveIndex; // These IDs are local to the SceneModel\n\n            const entityIndex = batchedPrimitiveEntityIndexes[primitiveIndex];\n            eachEntityId[entityIndex];\n\n            const meshDefaults = {}; // TODO: get from lookup from entity IDs\n\n            sceneModel.createMesh(utils.apply(meshDefaults, {\n                id: meshId,\n                primitive: \"triangles\",\n                positionsCompressed: primitivePositions,\n                normalsCompressed: primitiveNormals,\n                indices: primitiveIndices,\n                edgeIndices: primitiveEdgeIndices,\n                color: color,\n                opacity: opacity\n            }));\n        }\n    }\n\n    let countInstances = 0;\n\n    for (let entityIndex = 0; entityIndex < numEntities; entityIndex++) {\n\n        const lastEntityIndex = (numEntities - 1);\n        const atLastEntity = (entityIndex === lastEntityIndex);\n        const entityId = eachEntityId[entityIndex];\n        const firstEntityPrimitiveInstanceIndex = eachEntityPrimitiveInstancesPortion [entityIndex];\n        const lastEntityPrimitiveInstanceIndex = atLastEntity ? eachEntityPrimitiveInstancesPortion[lastEntityIndex] : eachEntityPrimitiveInstancesPortion[entityIndex + 1];\n\n        const meshIds = [];\n\n        for (let primitiveInstancesIndex = firstEntityPrimitiveInstanceIndex; primitiveInstancesIndex < lastEntityPrimitiveInstanceIndex; primitiveInstancesIndex++) {\n\n            const primitiveIndex = primitiveInstances[primitiveInstancesIndex];\n            const primitiveInstanceCount = primitiveInstanceCounts[primitiveIndex];\n            const isInstancedPrimitive = (primitiveInstanceCount > 1);\n\n            if (isInstancedPrimitive) {\n\n                const meshDefaults = {}; // TODO: get from lookup from entity IDs\n\n                const meshId = \"instance.\" + countInstances++;\n                const geometryId = \"geometry\" + primitiveIndex;\n                const matricesIndex = (eachEntityMatricesPortion [entityIndex]) * 16;\n                const matrix = matrices.subarray(matricesIndex, matricesIndex + 16);\n\n                sceneModel.createMesh(utils.apply(meshDefaults, {\n                    id: meshId,\n                    geometryId: geometryId,\n                    matrix: matrix\n                }));\n\n                meshIds.push(meshId);\n\n            } else {\n                meshIds.push(primitiveIndex);\n            }\n        }\n\n        if (meshIds.length > 0) {\n\n            const entityDefaults = {}; // TODO: get from lookup from entity IDs\n\n            sceneModel.createEntity(utils.apply(entityDefaults, {\n                id: entityId,\n                isObject: true, ///////////////// TODO: If metaobject exists\n                meshIds: meshIds\n            }));\n        }\n    }\n}\n\n/** @private */\nconst ParserV5 = {\n    version: 5,\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract$6(elements);\n        const inflatedData = inflate$6(deflatedData);\n        load$7(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n\n Parser for .XKT Format V6\n\n */\n\nlet pako$5 = window.pako || p;\nif (!pako$5.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako$5 = pako$5.default;\n}\n\nfunction extract$5(elements) {\n\n    return {\n        positions: elements[0],\n        normals: elements[1],\n        indices: elements[2],\n        edgeIndices: elements[3],\n        matrices: elements[4],\n        reusedPrimitivesDecodeMatrix: elements[5],\n        eachPrimitivePositionsAndNormalsPortion: elements[6],\n        eachPrimitiveIndicesPortion: elements[7],\n        eachPrimitiveEdgeIndicesPortion: elements[8],\n        eachPrimitiveColorAndOpacity: elements[9],\n        primitiveInstances: elements[10],\n        eachEntityId: elements[11],\n        eachEntityPrimitiveInstancesPortion: elements[12],\n        eachEntityMatricesPortion: elements[13],\n        eachTileAABB: elements[14],\n        eachTileEntitiesPortion: elements[15]\n    };\n}\n\nfunction inflate$5(deflatedData) {\n\n    function inflate(array, options) {\n        return (array.length === 0) ? [] : pako$5.inflate(array, options).buffer;\n    }\n\n    return {\n        positions: new Uint16Array(inflate(deflatedData.positions)),\n        normals: new Int8Array(inflate(deflatedData.normals)),\n        indices: new Uint32Array(inflate(deflatedData.indices)),\n        edgeIndices: new Uint32Array(inflate(deflatedData.edgeIndices)),\n        matrices: new Float32Array(inflate(deflatedData.matrices)),\n        reusedPrimitivesDecodeMatrix: new Float32Array(inflate(deflatedData.reusedPrimitivesDecodeMatrix)),\n        eachPrimitivePositionsAndNormalsPortion: new Uint32Array(inflate(deflatedData.eachPrimitivePositionsAndNormalsPortion)),\n        eachPrimitiveIndicesPortion: new Uint32Array(inflate(deflatedData.eachPrimitiveIndicesPortion)),\n        eachPrimitiveEdgeIndicesPortion: new Uint32Array(inflate(deflatedData.eachPrimitiveEdgeIndicesPortion)),\n        eachPrimitiveColorAndOpacity: new Uint8Array(inflate(deflatedData.eachPrimitiveColorAndOpacity)),\n        primitiveInstances: new Uint32Array(inflate(deflatedData.primitiveInstances)),\n        eachEntityId: pako$5.inflate(deflatedData.eachEntityId, {to: 'string'}),\n        eachEntityPrimitiveInstancesPortion: new Uint32Array(inflate(deflatedData.eachEntityPrimitiveInstancesPortion)),\n        eachEntityMatricesPortion: new Uint32Array(inflate(deflatedData.eachEntityMatricesPortion)),\n        eachTileAABB: new Float64Array(inflate(deflatedData.eachTileAABB)),\n        eachTileEntitiesPortion: new Uint32Array(inflate(deflatedData.eachTileEntitiesPortion))\n    };\n}\n\nconst decompressColor$6 = (function () {\n    const floatColor = new Float32Array(3);\n    return function (intColor) {\n        floatColor[0] = intColor[0] / 255.0;\n        floatColor[1] = intColor[1] / 255.0;\n        floatColor[2] = intColor[2] / 255.0;\n        return floatColor;\n    };\n})();\n\nfunction load$6(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n\n    const matrices = inflatedData.matrices;\n\n    const reusedPrimitivesDecodeMatrix = inflatedData.reusedPrimitivesDecodeMatrix;\n\n    const eachPrimitivePositionsAndNormalsPortion = inflatedData.eachPrimitivePositionsAndNormalsPortion;\n    const eachPrimitiveIndicesPortion = inflatedData.eachPrimitiveIndicesPortion;\n    const eachPrimitiveEdgeIndicesPortion = inflatedData.eachPrimitiveEdgeIndicesPortion;\n    const eachPrimitiveColorAndOpacity = inflatedData.eachPrimitiveColorAndOpacity;\n\n    const primitiveInstances = inflatedData.primitiveInstances;\n\n    const eachEntityId = JSON.parse(inflatedData.eachEntityId);\n    const eachEntityPrimitiveInstancesPortion = inflatedData.eachEntityPrimitiveInstancesPortion;\n    const eachEntityMatricesPortion = inflatedData.eachEntityMatricesPortion;\n\n    const eachTileAABB = inflatedData.eachTileAABB;\n    const eachTileEntitiesPortion = inflatedData.eachTileEntitiesPortion;\n\n    const numPrimitives = eachPrimitivePositionsAndNormalsPortion.length;\n    const numPrimitiveInstances = primitiveInstances.length;\n    const numEntities = eachEntityId.length;\n    const numTiles = eachTileEntitiesPortion.length;\n\n    // Count instances of each primitive\n\n    const primitiveReuseCounts = new Uint32Array(numPrimitives);\n\n    for (let primitiveInstanceIndex = 0; primitiveInstanceIndex < numPrimitiveInstances; primitiveInstanceIndex++) {\n        const primitiveIndex = primitiveInstances[primitiveInstanceIndex];\n        if (primitiveReuseCounts[primitiveIndex] !== undefined) {\n            primitiveReuseCounts[primitiveIndex]++;\n        } else {\n            primitiveReuseCounts[primitiveIndex] = 1;\n        }\n    }\n\n    // Iterate over tiles\n\n    const tileCenter = math.vec3();\n    const rtcAABB = math.AABB3();\n\n    for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {\n\n        const lastTileIndex = (numTiles - 1);\n\n        const atLastTile = (tileIndex === lastTileIndex);\n\n        const firstTileEntityIndex = eachTileEntitiesPortion [tileIndex];\n        const lastTileEntityIndex = atLastTile ? numEntities : eachTileEntitiesPortion[tileIndex + 1];\n\n        const tileAABBIndex = tileIndex * 6;\n        const tileAABB = eachTileAABB.subarray(tileAABBIndex, tileAABBIndex + 6);\n\n        math.getAABB3Center(tileAABB, tileCenter);\n\n        rtcAABB[0] = tileAABB[0] - tileCenter[0];\n        rtcAABB[1] = tileAABB[1] - tileCenter[1];\n        rtcAABB[2] = tileAABB[2] - tileCenter[2];\n        rtcAABB[3] = tileAABB[3] - tileCenter[0];\n        rtcAABB[4] = tileAABB[4] - tileCenter[1];\n        rtcAABB[5] = tileAABB[5] - tileCenter[2];\n\n        const tileDecodeMatrix = geometryCompressionUtils.createPositionsDecodeMatrix(rtcAABB);\n\n        const geometryCreated = {};\n\n        // Iterate over each tile's entities\n\n        for (let tileEntityIndex = firstTileEntityIndex; tileEntityIndex < lastTileEntityIndex; tileEntityIndex++) {\n\n            const xktEntityId = eachEntityId[tileEntityIndex];\n            const entityId = options.globalizeObjectIds ? math.globalizeObjectId(sceneModel.id, xktEntityId) : xktEntityId;\n\n            const entityMatrixIndex = eachEntityMatricesPortion[tileEntityIndex];\n            const entityMatrix = matrices.slice(entityMatrixIndex, entityMatrixIndex + 16);\n\n            const lastTileEntityIndex = (numEntities - 1);\n            const atLastTileEntity = (tileEntityIndex === lastTileEntityIndex);\n            const firstPrimitiveInstanceIndex = eachEntityPrimitiveInstancesPortion [tileEntityIndex];\n            const lastPrimitiveInstanceIndex = atLastTileEntity ? primitiveInstances.length : eachEntityPrimitiveInstancesPortion[tileEntityIndex + 1];\n\n            const meshIds = [];\n\n            const metaObject = viewer.metaScene.metaObjects[entityId];\n            const entityDefaults = {};\n            const meshDefaults = {};\n\n            if (metaObject) {\n\n                // Mask loading of object types\n\n                if (options.excludeTypesMap && metaObject.type && options.excludeTypesMap[metaObject.type]) {\n                    continue;\n                }\n\n                if (options.includeTypesMap && metaObject.type && (!options.includeTypesMap[metaObject.type])) {\n                    continue;\n                }\n\n                // Mask loading of object ids\n\n                if (options.includeIdsMap && metaObject.id && (!options.includeIdsMap[metaObject.id])) {\n                    continue;\n                }\n\n                // Get initial property values for object types\n\n                const props = options.objectDefaults ? options.objectDefaults[metaObject.type] || options.objectDefaults[\"DEFAULT\"] : null;\n\n                if (props) {\n                    if (props.visible === false) {\n                        entityDefaults.visible = false;\n                    }\n                    if (props.pickable === false) {\n                        entityDefaults.pickable = false;\n                    }\n                    if (props.colorize) {\n                        meshDefaults.color = props.colorize;\n                    }\n                    if (props.opacity !== undefined && props.opacity !== null) {\n                        meshDefaults.opacity = props.opacity;\n                    }\n                }\n\n            } else {\n                if (options.excludeUnclassifiedObjects) {\n                    continue;\n                }\n            }\n\n            // Iterate each entity's primitive instances\n\n            for (let primitiveInstancesIndex = firstPrimitiveInstanceIndex; primitiveInstancesIndex < lastPrimitiveInstanceIndex; primitiveInstancesIndex++) {\n\n                const primitiveIndex = primitiveInstances[primitiveInstancesIndex];\n                const primitiveReuseCount = primitiveReuseCounts[primitiveIndex];\n                const isReusedPrimitive = (primitiveReuseCount > 1);\n\n                const atLastPrimitive = (primitiveIndex === (numPrimitives - 1));\n\n                const primitivePositions = positions.subarray(eachPrimitivePositionsAndNormalsPortion [primitiveIndex], atLastPrimitive ? positions.length : eachPrimitivePositionsAndNormalsPortion [primitiveIndex + 1]);\n                const primitiveNormals = normals.subarray(eachPrimitivePositionsAndNormalsPortion [primitiveIndex], atLastPrimitive ? normals.length : eachPrimitivePositionsAndNormalsPortion [primitiveIndex + 1]);\n                const primitiveIndices = indices.subarray(eachPrimitiveIndicesPortion [primitiveIndex], atLastPrimitive ? indices.length : eachPrimitiveIndicesPortion [primitiveIndex + 1]);\n                const primitiveEdgeIndices = edgeIndices.subarray(eachPrimitiveEdgeIndicesPortion [primitiveIndex], atLastPrimitive ? edgeIndices.length : eachPrimitiveEdgeIndicesPortion [primitiveIndex + 1]);\n\n                const color = decompressColor$6(eachPrimitiveColorAndOpacity.subarray((primitiveIndex * 4), (primitiveIndex * 4) + 3));\n                const opacity = eachPrimitiveColorAndOpacity[(primitiveIndex * 4) + 3] / 255.0;\n\n                const meshId = manifestCtx.getNextId();\n\n                if (isReusedPrimitive) {\n\n                    // Create mesh for multi-use primitive - create (or reuse) geometry, create mesh using that geometry\n\n                    const geometryId = `${modelPartId}-geometry.${tileIndex}.${primitiveIndex}`; // These IDs are local to the SceneModel\n\n                    if (!geometryCreated[geometryId]) {\n\n                        sceneModel.createGeometry({\n                            id: geometryId,\n                            primitive: \"triangles\",\n                            positionsCompressed: primitivePositions,\n                         //   normalsCompressed: primitiveNormals,\n                            indices: primitiveIndices,\n                            edgeIndices: primitiveEdgeIndices,\n                            positionsDecodeMatrix: reusedPrimitivesDecodeMatrix\n                        });\n\n                        geometryCreated[geometryId] = true;\n                    }\n\n                    sceneModel.createMesh(utils.apply(meshDefaults, {\n                        id: meshId,\n                        geometryId: geometryId,\n                        origin: tileCenter,\n                        matrix: entityMatrix,\n                        color: color,\n                        opacity: opacity\n                    }));\n\n                    meshIds.push(meshId);\n\n                } else {\n\n                    sceneModel.createMesh(utils.apply(meshDefaults, {\n                        id: meshId,\n                        origin: tileCenter,\n                        primitive: \"triangles\",\n                        positionsCompressed: primitivePositions,\n                        normalsCompressed: primitiveNormals,\n                        indices: primitiveIndices,\n                        edgeIndices: primitiveEdgeIndices,\n                        positionsDecodeMatrix: tileDecodeMatrix,\n                        color: color,\n                        opacity: opacity\n                    }));\n\n                    meshIds.push(meshId);\n                }\n            }\n\n            if (meshIds.length > 0) {\n\n                sceneModel.createEntity(utils.apply(entityDefaults, {\n                    id: entityId,\n                    isObject: true,\n                    meshIds: meshIds\n                }));\n            }\n        }\n    }\n}\n\n/** @private */\nconst ParserV6 = {\n    version: 6,\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract$5(elements);\n        const inflatedData = inflate$5(deflatedData);\n        load$6(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n\n Parser for .XKT Format V7\n\n */\n\nlet pako$4 = window.pako || p;\nif (!pako$4.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako$4 = pako$4.default;\n}\n\nfunction extract$4(elements) {\n\n    return {\n\n        // Vertex attributes\n\n        positions: elements[0],\n        normals: elements[1],\n        colors: elements[2],\n\n        // Indices\n\n        indices: elements[3],\n        edgeIndices: elements[4],\n\n        // Transform matrices\n\n        matrices: elements[5],\n\n        reusedGeometriesDecodeMatrix: elements[6],\n\n        // Geometries\n\n        eachGeometryPrimitiveType: elements[7],\n        eachGeometryPositionsPortion: elements[8],\n        eachGeometryNormalsPortion: elements[9],\n        eachGeometryColorsPortion: elements[10],\n        eachGeometryIndicesPortion: elements[11],\n        eachGeometryEdgeIndicesPortion: elements[12],\n\n        // Meshes are grouped in runs that are shared by the same entities\n\n        eachMeshGeometriesPortion: elements[13],\n        eachMeshMatricesPortion: elements[14],\n        eachMeshMaterial: elements[15],\n\n        // Entity elements in the following arrays are grouped in runs that are shared by the same tiles\n\n        eachEntityId: elements[16],\n        eachEntityMeshesPortion: elements[17],\n\n        eachTileAABB: elements[18],\n        eachTileEntitiesPortion: elements[19]\n    };\n}\n\nfunction inflate$4(deflatedData) {\n\n    function inflate(array, options) {\n        return (array.length === 0) ? [] : pako$4.inflate(array, options).buffer;\n    }\n\n    return {\n        positions: new Uint16Array(inflate(deflatedData.positions)),\n        normals: new Int8Array(inflate(deflatedData.normals)),\n        colors: new Uint8Array(inflate(deflatedData.colors)),\n\n        indices: new Uint32Array(inflate(deflatedData.indices)),\n        edgeIndices: new Uint32Array(inflate(deflatedData.edgeIndices)),\n\n        matrices: new Float32Array(inflate(deflatedData.matrices)),\n\n        reusedGeometriesDecodeMatrix: new Float32Array(inflate(deflatedData.reusedGeometriesDecodeMatrix)),\n\n        eachGeometryPrimitiveType: new Uint8Array(inflate(deflatedData.eachGeometryPrimitiveType)),\n        eachGeometryPositionsPortion: new Uint32Array(inflate(deflatedData.eachGeometryPositionsPortion)),\n        eachGeometryNormalsPortion: new Uint32Array(inflate(deflatedData.eachGeometryNormalsPortion)),\n        eachGeometryColorsPortion: new Uint32Array(inflate(deflatedData.eachGeometryColorsPortion)),\n        eachGeometryIndicesPortion: new Uint32Array(inflate(deflatedData.eachGeometryIndicesPortion)),\n        eachGeometryEdgeIndicesPortion: new Uint32Array(inflate(deflatedData.eachGeometryEdgeIndicesPortion)),\n\n        eachMeshGeometriesPortion: new Uint32Array(inflate(deflatedData.eachMeshGeometriesPortion)),\n        eachMeshMatricesPortion: new Uint32Array(inflate(deflatedData.eachMeshMatricesPortion)),\n        eachMeshMaterial: new Uint8Array(inflate(deflatedData.eachMeshMaterial)),\n\n        eachEntityId: pako$4.inflate(deflatedData.eachEntityId, {to: 'string'}),\n        eachEntityMeshesPortion: new Uint32Array(inflate(deflatedData.eachEntityMeshesPortion)),\n\n        eachTileAABB: new Float64Array(inflate(deflatedData.eachTileAABB)),\n        eachTileEntitiesPortion: new Uint32Array(inflate(deflatedData.eachTileEntitiesPortion)),\n    };\n}\n\nconst decompressColor$5 = (function () {\n    const floatColor = new Float32Array(3);\n    return function (intColor) {\n        floatColor[0] = intColor[0] / 255.0;\n        floatColor[1] = intColor[1] / 255.0;\n        floatColor[2] = intColor[2] / 255.0;\n        return floatColor;\n    };\n})();\n\nfunction convertColorsRGBToRGBA$1(colorsRGB) {\n    const colorsRGBA = [];\n    for (let i = 0, len = colorsRGB.length; i < len; i+=3) {\n        colorsRGBA.push(colorsRGB[i]);\n        colorsRGBA.push(colorsRGB[i+1]);\n        colorsRGBA.push(colorsRGB[i+2]);\n        colorsRGBA.push(1.0);\n    }\n    return colorsRGBA;\n}\n\nfunction load$5(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const colors = inflatedData.colors;\n\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n\n    const matrices = inflatedData.matrices;\n\n    const reusedGeometriesDecodeMatrix = inflatedData.reusedGeometriesDecodeMatrix;\n\n    const eachGeometryPrimitiveType = inflatedData.eachGeometryPrimitiveType;\n    const eachGeometryPositionsPortion = inflatedData.eachGeometryPositionsPortion;\n    const eachGeometryNormalsPortion = inflatedData.eachGeometryNormalsPortion;\n    const eachGeometryColorsPortion = inflatedData.eachGeometryColorsPortion;\n    const eachGeometryIndicesPortion = inflatedData.eachGeometryIndicesPortion;\n    const eachGeometryEdgeIndicesPortion = inflatedData.eachGeometryEdgeIndicesPortion;\n\n    const eachMeshGeometriesPortion = inflatedData.eachMeshGeometriesPortion;\n    const eachMeshMatricesPortion = inflatedData.eachMeshMatricesPortion;\n    const eachMeshMaterial = inflatedData.eachMeshMaterial;\n\n    const eachEntityId = JSON.parse(inflatedData.eachEntityId);\n    const eachEntityMeshesPortion = inflatedData.eachEntityMeshesPortion;\n\n    const eachTileAABB = inflatedData.eachTileAABB;\n    const eachTileEntitiesPortion = inflatedData.eachTileEntitiesPortion;\n\n    const numGeometries = eachGeometryPositionsPortion.length;\n    const numMeshes = eachMeshGeometriesPortion.length;\n    const numEntities = eachEntityId.length;\n    const numTiles = eachTileEntitiesPortion.length;\n\n    // Count instances of each geometry\n\n    const geometryReuseCounts = new Uint32Array(numGeometries);\n\n    for (let meshIndex = 0; meshIndex < numMeshes; meshIndex++) {\n        const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n        if (geometryReuseCounts[geometryIndex] !== undefined) {\n            geometryReuseCounts[geometryIndex]++;\n        } else {\n            geometryReuseCounts[geometryIndex] = 1;\n        }\n    }\n\n    // Iterate over tiles\n\n    const tileCenter = math.vec3();\n    const rtcAABB = math.AABB3();\n\n    for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {\n\n        const lastTileIndex = (numTiles - 1);\n\n        const atLastTile = (tileIndex === lastTileIndex);\n\n        const firstTileEntityIndex = eachTileEntitiesPortion [tileIndex];\n        const lastTileEntityIndex = atLastTile ? numEntities : eachTileEntitiesPortion[tileIndex + 1];\n\n        const tileAABBIndex = tileIndex * 6;\n        const tileAABB = eachTileAABB.subarray(tileAABBIndex, tileAABBIndex + 6);\n\n        math.getAABB3Center(tileAABB, tileCenter);\n\n        rtcAABB[0] = tileAABB[0] - tileCenter[0];\n        rtcAABB[1] = tileAABB[1] - tileCenter[1];\n        rtcAABB[2] = tileAABB[2] - tileCenter[2];\n        rtcAABB[3] = tileAABB[3] - tileCenter[0];\n        rtcAABB[4] = tileAABB[4] - tileCenter[1];\n        rtcAABB[5] = tileAABB[5] - tileCenter[2];\n\n        const tileDecodeMatrix = geometryCompressionUtils.createPositionsDecodeMatrix(rtcAABB);\n\n        const geometryCreated = {};\n\n        // Iterate over each tile's entities\n\n        for (let tileEntityIndex = firstTileEntityIndex; tileEntityIndex < lastTileEntityIndex; tileEntityIndex++) {\n\n            const xktEntityId = eachEntityId[tileEntityIndex];\n            const entityId = options.globalizeObjectIds ? math.globalizeObjectId(sceneModel.id, xktEntityId) : xktEntityId;\n\n            const lastTileEntityIndex = (numEntities - 1);\n            const atLastTileEntity = (tileEntityIndex === lastTileEntityIndex);\n            const firstMeshIndex = eachEntityMeshesPortion [tileEntityIndex];\n            const lastMeshIndex = atLastTileEntity ? eachMeshGeometriesPortion.length : eachEntityMeshesPortion[tileEntityIndex + 1];\n\n            const meshIds = [];\n\n            const metaObject = viewer.metaScene.metaObjects[entityId];\n            const entityDefaults = {};\n            const meshDefaults = {};\n\n            if (metaObject) {\n\n                // Mask loading of object types\n\n                if (options.excludeTypesMap && metaObject.type && options.excludeTypesMap[metaObject.type]) {\n                    continue;\n                }\n\n                if (options.includeTypesMap && metaObject.type && (!options.includeTypesMap[metaObject.type])) {\n                    continue;\n                }\n\n                // Mask loading of object ids\n\n                if (options.includeIdsMap && metaObject.id && (!options.includeIdsMap[metaObject.id])) {\n                    continue;\n                }\n\n                // Get initial property values for object types\n\n                const props = options.objectDefaults ? options.objectDefaults[metaObject.type] || options.objectDefaults[\"DEFAULT\"] : null;\n\n                if (props) {\n                    if (props.visible === false) {\n                        entityDefaults.visible = false;\n                    }\n                    if (props.pickable === false) {\n                        entityDefaults.pickable = false;\n                    }\n                    if (props.colorize) {\n                        meshDefaults.color = props.colorize;\n                    }\n                    if (props.opacity !== undefined && props.opacity !== null) {\n                        meshDefaults.opacity = props.opacity;\n                    }\n                    if (props.metallic !== undefined && props.metallic !== null) {\n                        meshDefaults.metallic = props.metallic;\n                    }\n                    if (props.roughness !== undefined && props.roughness !== null) {\n                        meshDefaults.roughness = props.roughness;\n                    }\n                }\n\n            } else {\n                if (options.excludeUnclassifiedObjects) {\n                    continue;\n                }\n            }\n\n            // Iterate each entity's meshes\n\n            for (let meshIndex = firstMeshIndex; meshIndex < lastMeshIndex; meshIndex++) {\n\n                const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n                const geometryReuseCount = geometryReuseCounts[geometryIndex];\n                const isReusedGeometry = (geometryReuseCount > 1);\n\n                const atLastGeometry = (geometryIndex === (numGeometries - 1));\n\n                const meshColor = decompressColor$5(eachMeshMaterial.subarray((meshIndex * 6), (meshIndex * 6) + 3));\n                const meshOpacity = eachMeshMaterial[(meshIndex * 6) + 3] / 255.0;\n                const meshMetallic = eachMeshMaterial[(meshIndex * 6) + 4] / 255.0;\n                const meshRoughness = eachMeshMaterial[(meshIndex * 6) + 5] / 255.0;\n\n                const meshId = manifestCtx.getNextId();\n\n                if (isReusedGeometry) {\n\n                    // Create mesh for multi-use geometry - create (or reuse) geometry, create mesh using that geometry\n\n                    const meshMatrixIndex = eachMeshMatricesPortion[meshIndex];\n                    const meshMatrix = matrices.slice(meshMatrixIndex, meshMatrixIndex + 16);\n\n                    const geometryId = `${modelPartId}-geometry.${tileIndex}.${geometryIndex}`; // These IDs are local to the SceneModel\n\n                    if (!geometryCreated[geometryId]) {\n\n                        const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n\n                        let primitiveName;\n                        let geometryPositions;\n                        let geometryNormals;\n                        let geometryColors;\n                        let geometryIndices;\n                        let geometryEdgeIndices;\n\n                        switch (primitiveType) {\n                            case 0:\n                                primitiveName = \"solid\";\n                                geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                break;\n                            case 1:\n                                primitiveName = \"surface\";\n                                geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                break;\n                            case 2:\n                                primitiveName = \"points\";\n                                geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryColors = convertColorsRGBToRGBA$1(colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]));\n                                break;\n                            case 3:\n                                primitiveName = \"lines\";\n                                geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                break;\n                            default:\n                                continue;\n                        }\n\n                        sceneModel.createGeometry({\n                            id: geometryId,\n                            primitive: primitiveName,\n                            positionsCompressed: geometryPositions,\n                            normalsCompressed: geometryNormals,\n                            colors: geometryColors,\n                            indices: geometryIndices,\n                            edgeIndices: geometryEdgeIndices,\n                            positionsDecodeMatrix: reusedGeometriesDecodeMatrix\n                        });\n\n                        geometryCreated[geometryId] = true;\n                    }\n\n                    sceneModel.createMesh(utils.apply(meshDefaults, {\n                        id: meshId,\n                        geometryId: geometryId,\n                        origin: tileCenter,\n                        matrix: meshMatrix,\n                        color: meshColor,\n                        metallic: meshMetallic,\n                        roughness: meshRoughness,\n                        opacity: meshOpacity\n                    }));\n\n                    meshIds.push(meshId);\n\n                } else {\n\n                    const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n\n                    let primitiveName;\n                    let geometryPositions;\n                    let geometryNormals;\n                    let geometryColors;\n                    let geometryIndices;\n                    let geometryEdgeIndices;\n\n                    switch (primitiveType) {\n                        case 0:\n                            primitiveName = \"solid\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            break;\n                        case 1:\n                            primitiveName = \"surface\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            break;\n                        case 2:\n                            primitiveName = \"points\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryColors = convertColorsRGBToRGBA$1(colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]));\n                            break;\n                        case 3:\n                            primitiveName = \"lines\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            break;\n                        default:\n                            continue;\n                    }\n\n                    sceneModel.createMesh(utils.apply(meshDefaults, {\n                        id: meshId,\n                        origin: tileCenter,\n                        primitive: primitiveName,\n                        positionsCompressed: geometryPositions,\n                        normalsCompressed: geometryNormals,\n                        colors: geometryColors,\n                        indices: geometryIndices,\n                        edgeIndices: geometryEdgeIndices,\n                        positionsDecodeMatrix: tileDecodeMatrix,\n                        color: meshColor,\n                        metallic: meshMetallic,\n                        roughness: meshRoughness,\n                        opacity: meshOpacity\n                    }));\n\n                    meshIds.push(meshId);\n                }\n            }\n\n            if (meshIds.length > 0) {\n\n                sceneModel.createEntity(utils.apply(entityDefaults, {\n                    id: entityId,\n                    isObject: true,\n                    meshIds: meshIds\n                }));\n            }\n        }\n    }\n}\n\n/** @private */\nconst ParserV7 = {\n    version: 7,\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract$4(elements);\n        const inflatedData = inflate$4(deflatedData);\n        load$5(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n\n Parser for .XKT Format V8\n\n */\n\nlet pako$3 = window.pako || p;\nif (!pako$3.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako$3 = pako$3.default;\n}\n\nconst tempVec4a$4 = math.vec4();\nconst tempVec4b$4 = math.vec4();\n\nfunction extract$3(elements) {\n\n    return {\n\n        // Vertex attributes\n\n        types: elements[0],\n        eachMetaObjectId: elements[1],\n        eachMetaObjectType: elements[2],\n        eachMetaObjectName: elements[3],\n        eachMetaObjectParent: elements[4],\n\n        positions: elements[5],\n        normals: elements[6],\n        colors: elements[7],\n        indices: elements[8],\n        edgeIndices: elements[9],\n\n        // Transform matrices\n\n        matrices: elements[10],\n        reusedGeometriesDecodeMatrix: elements[11],\n\n        // Geometries\n\n        eachGeometryPrimitiveType: elements[12],\n        eachGeometryPositionsPortion: elements[13],\n        eachGeometryNormalsPortion: elements[14],\n        eachGeometryColorsPortion: elements[15],\n        eachGeometryIndicesPortion: elements[16],\n        eachGeometryEdgeIndicesPortion: elements[17],\n\n        // Meshes are grouped in runs that are shared by the same entities\n\n        eachMeshGeometriesPortion: elements[18],\n        eachMeshMatricesPortion: elements[19],\n        eachMeshMaterial: elements[20],\n\n        // Entity elements in the following arrays are grouped in runs that are shared by the same tiles\n\n        eachEntityMetaObject: elements[21],\n        eachEntityMeshesPortion: elements[22],\n\n        eachTileAABB: elements[23],\n        eachTileEntitiesPortion: elements[24]\n    };\n}\n\nfunction inflate$3(deflatedData) {\n\n    function inflate(array, options) {\n        return (array.length === 0) ? [] : pako$3.inflate(array, options).buffer;\n    }\n\n    return {\n\n        types: pako$3.inflate(deflatedData.types, {to: 'string'}),\n        eachMetaObjectId: pako$3.inflate(deflatedData.eachMetaObjectId, {to: 'string'}),\n        eachMetaObjectType: new Uint32Array(inflate(deflatedData.eachMetaObjectType)),\n        eachMetaObjectName: pako$3.inflate(deflatedData.eachMetaObjectName, {to: 'string'}),\n        eachMetaObjectParent: new Uint32Array(inflate(deflatedData.eachMetaObjectParent)),\n\n        positions: new Uint16Array(inflate(deflatedData.positions)),\n        normals: new Int8Array(inflate(deflatedData.normals)),\n        colors: new Uint8Array(inflate(deflatedData.colors)),\n        indices: new Uint32Array(inflate(deflatedData.indices)),\n        edgeIndices: new Uint32Array(inflate(deflatedData.edgeIndices)),\n\n        matrices: new Float32Array(inflate(deflatedData.matrices)),\n        reusedGeometriesDecodeMatrix: new Float32Array(inflate(deflatedData.reusedGeometriesDecodeMatrix)),\n\n        eachGeometryPrimitiveType: new Uint8Array(inflate(deflatedData.eachGeometryPrimitiveType)),\n        eachGeometryPositionsPortion: new Uint32Array(inflate(deflatedData.eachGeometryPositionsPortion)),\n        eachGeometryNormalsPortion: new Uint32Array(inflate(deflatedData.eachGeometryNormalsPortion)),\n        eachGeometryColorsPortion: new Uint32Array(inflate(deflatedData.eachGeometryColorsPortion)),\n        eachGeometryIndicesPortion: new Uint32Array(inflate(deflatedData.eachGeometryIndicesPortion)),\n        eachGeometryEdgeIndicesPortion: new Uint32Array(inflate(deflatedData.eachGeometryEdgeIndicesPortion)),\n\n        eachMeshGeometriesPortion: new Uint32Array(inflate(deflatedData.eachMeshGeometriesPortion)),\n        eachMeshMatricesPortion: new Uint32Array(inflate(deflatedData.eachMeshMatricesPortion)),\n        eachMeshMaterial: new Uint8Array(inflate(deflatedData.eachMeshMaterial)),\n\n        eachEntityMetaObject: new Uint32Array(inflate(deflatedData.eachEntityMetaObject)),\n        eachEntityMeshesPortion: new Uint32Array(inflate(deflatedData.eachEntityMeshesPortion)),\n\n        eachTileAABB: new Float64Array(inflate(deflatedData.eachTileAABB)),\n        eachTileEntitiesPortion: new Uint32Array(inflate(deflatedData.eachTileEntitiesPortion)),\n    };\n}\n\nconst decompressColor$4 = (function () {\n    const floatColor = new Float32Array(3);\n    return function (intColor) {\n        floatColor[0] = intColor[0] / 255.0;\n        floatColor[1] = intColor[1] / 255.0;\n        floatColor[2] = intColor[2] / 255.0;\n        return floatColor;\n    };\n})();\n\nfunction convertColorsRGBToRGBA(colorsRGB) {\n    const colorsRGBA = [];\n    for (let i = 0, len = colorsRGB.length; i < len; i += 3) {\n        colorsRGBA.push(colorsRGB[i]);\n        colorsRGBA.push(colorsRGB[i + 1]);\n        colorsRGBA.push(colorsRGB[i + 2]);\n        colorsRGBA.push(1.0);\n    }\n    return colorsRGBA;\n}\n\nfunction load$4(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    const types = JSON.parse(inflatedData.types);\n    const eachMetaObjectId = JSON.parse(inflatedData.eachMetaObjectId);\n    const eachMetaObjectType = inflatedData.eachMetaObjectType;\n    const eachMetaObjectName = JSON.parse(inflatedData.eachMetaObjectName);\n    const eachMetaObjectParent = inflatedData.eachMetaObjectParent;\n\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const colors = inflatedData.colors;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n\n    const matrices = inflatedData.matrices;\n    const reusedGeometriesDecodeMatrix = inflatedData.reusedGeometriesDecodeMatrix;\n\n    const eachGeometryPrimitiveType = inflatedData.eachGeometryPrimitiveType;\n    const eachGeometryPositionsPortion = inflatedData.eachGeometryPositionsPortion;\n    const eachGeometryNormalsPortion = inflatedData.eachGeometryNormalsPortion;\n    const eachGeometryColorsPortion = inflatedData.eachGeometryColorsPortion;\n    const eachGeometryIndicesPortion = inflatedData.eachGeometryIndicesPortion;\n    const eachGeometryEdgeIndicesPortion = inflatedData.eachGeometryEdgeIndicesPortion;\n\n    const eachMeshGeometriesPortion = inflatedData.eachMeshGeometriesPortion;\n    const eachMeshMatricesPortion = inflatedData.eachMeshMatricesPortion;\n    const eachMeshMaterial = inflatedData.eachMeshMaterial;\n\n    const eachEntityMetaObject = inflatedData.eachEntityMetaObject;\n    const eachEntityMeshesPortion = inflatedData.eachEntityMeshesPortion;\n\n    const eachTileAABB = inflatedData.eachTileAABB;\n    const eachTileEntitiesPortion = inflatedData.eachTileEntitiesPortion;\n\n    const numMetaObjects = eachMetaObjectId.length;\n    const numGeometries = eachGeometryPositionsPortion.length;\n    const numMeshes = eachMeshGeometriesPortion.length;\n    const numEntities = eachEntityMetaObject.length;\n    const numTiles = eachTileEntitiesPortion.length;\n\n    if (metaModel) {\n        const metaModelData = {\n            metaObjects: []\n        };\n        for (let metaObjectIndex = 0; metaObjectIndex < numMetaObjects; metaObjectIndex++) {\n            const metaObjectId = eachMetaObjectId[metaObjectIndex];\n            const typeIndex = eachMetaObjectType[metaObjectIndex];\n            const metaObjectType = types[typeIndex] || \"default\";\n            const metaObjectName = eachMetaObjectName[metaObjectIndex];\n            const metaObjectParentIndex = eachMetaObjectParent[metaObjectIndex];\n            const metaObjectParentId = (metaObjectParentIndex !== metaObjectIndex) ? eachMetaObjectId[metaObjectParentIndex] : null;\n            metaModelData.metaObjects.push({\n                id: metaObjectId,\n                type: metaObjectType,\n                name: metaObjectName,\n                parent: metaObjectParentId\n            });\n        }\n        metaModel.loadData(metaModelData, {\n            includeTypes: options.includeTypes,\n            excludeTypes: options.excludeTypes,\n            globalizeObjectIds: options.globalizeObjectIds\n        });\n    }\n\n    // Count instances of each geometry\n\n    const geometryReuseCounts = new Uint32Array(numGeometries);\n\n    for (let meshIndex = 0; meshIndex < numMeshes; meshIndex++) {\n        const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n        if (geometryReuseCounts[geometryIndex] !== undefined) {\n            geometryReuseCounts[geometryIndex]++;\n        } else {\n            geometryReuseCounts[geometryIndex] = 1;\n        }\n    }\n\n    // Iterate over tiles\n\n    const tileCenter = math.vec3();\n    const rtcAABB = math.AABB3();\n\n    const geometryArraysCache = {};\n\n    for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {\n\n        const lastTileIndex = (numTiles - 1);\n\n        const atLastTile = (tileIndex === lastTileIndex);\n\n        const firstTileEntityIndex = eachTileEntitiesPortion [tileIndex];\n        const lastTileEntityIndex = atLastTile ? numEntities : eachTileEntitiesPortion[tileIndex + 1];\n\n        const tileAABBIndex = tileIndex * 6;\n        const tileAABB = eachTileAABB.subarray(tileAABBIndex, tileAABBIndex + 6);\n\n        math.getAABB3Center(tileAABB, tileCenter);\n\n        rtcAABB[0] = tileAABB[0] - tileCenter[0];\n        rtcAABB[1] = tileAABB[1] - tileCenter[1];\n        rtcAABB[2] = tileAABB[2] - tileCenter[2];\n        rtcAABB[3] = tileAABB[3] - tileCenter[0];\n        rtcAABB[4] = tileAABB[4] - tileCenter[1];\n        rtcAABB[5] = tileAABB[5] - tileCenter[2];\n\n        const tileDecodeMatrix = geometryCompressionUtils.createPositionsDecodeMatrix(rtcAABB);\n\n        const geometryCreatedInTile = {};\n\n        // Iterate over each tile's entities\n\n        for (let tileEntityIndex = firstTileEntityIndex; tileEntityIndex < lastTileEntityIndex; tileEntityIndex++) {\n\n            const xktMetaObjectIndex = eachEntityMetaObject[tileEntityIndex];\n            const xktMetaObjectId = eachMetaObjectId[xktMetaObjectIndex];\n            const xktEntityId = xktMetaObjectId;\n\n            const entityId = options.globalizeObjectIds ? math.globalizeObjectId(sceneModel.id, xktEntityId) : xktEntityId;\n\n            const lastTileEntityIndex = (numEntities - 1);\n            const atLastTileEntity = (tileEntityIndex === lastTileEntityIndex);\n            const firstMeshIndex = eachEntityMeshesPortion [tileEntityIndex];\n            const lastMeshIndex = atLastTileEntity ? eachMeshGeometriesPortion.length : eachEntityMeshesPortion[tileEntityIndex + 1];\n\n            const meshIds = [];\n\n            const metaObject = viewer.metaScene.metaObjects[entityId];\n            const entityDefaults = {};\n            const meshDefaults = {};\n\n            if (metaObject) {\n\n                // Mask loading of object types\n\n                if (options.excludeTypesMap && metaObject.type && options.excludeTypesMap[metaObject.type]) {\n                    continue;\n                }\n\n                if (options.includeTypesMap && metaObject.type && (!options.includeTypesMap[metaObject.type])) {\n                    continue;\n                }\n\n                // Mask loading of object ids\n\n                if (options.includeIdsMap && metaObject.id && (!options.includeIdsMap[metaObject.id])) {\n                    continue;\n                }\n\n                // Get initial property values for object types\n\n                const props = options.objectDefaults ? options.objectDefaults[metaObject.type] || options.objectDefaults[\"DEFAULT\"] : null;\n\n                if (props) {\n                    if (props.visible === false) {\n                        entityDefaults.visible = false;\n                    }\n                    if (props.pickable === false) {\n                        entityDefaults.pickable = false;\n                    }\n                    if (props.colorize) {\n                        meshDefaults.color = props.colorize;\n                    }\n                    if (props.opacity !== undefined && props.opacity !== null) {\n                        meshDefaults.opacity = props.opacity;\n                    }\n                    if (props.metallic !== undefined && props.metallic !== null) {\n                        meshDefaults.metallic = props.metallic;\n                    }\n                    if (props.roughness !== undefined && props.roughness !== null) {\n                        meshDefaults.roughness = props.roughness;\n                    }\n                }\n\n            } else {\n                if (options.excludeUnclassifiedObjects) {\n                    continue;\n                }\n            }\n\n            // Iterate each entity's meshes\n\n            for (let meshIndex = firstMeshIndex; meshIndex < lastMeshIndex; meshIndex++) {\n\n                const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n                const geometryReuseCount = geometryReuseCounts[geometryIndex];\n                const isReusedGeometry = (geometryReuseCount > 1);\n\n                const atLastGeometry = (geometryIndex === (numGeometries - 1));\n\n                const meshColor = decompressColor$4(eachMeshMaterial.subarray((meshIndex * 6), (meshIndex * 6) + 3));\n                const meshOpacity = eachMeshMaterial[(meshIndex * 6) + 3] / 255.0;\n                const meshMetallic = eachMeshMaterial[(meshIndex * 6) + 4] / 255.0;\n                const meshRoughness = eachMeshMaterial[(meshIndex * 6) + 5] / 255.0;\n\n                const meshId = manifestCtx.getNextId();\n\n                if (isReusedGeometry) {\n\n                    // Create mesh for multi-use geometry - create (or reuse) geometry, create mesh using that geometry\n\n                    const meshMatrixIndex = eachMeshMatricesPortion[meshIndex];\n                    const meshMatrix = matrices.slice(meshMatrixIndex, meshMatrixIndex + 16);\n\n                     const geometryId = `${modelPartId}-geometry.${tileIndex}.${geometryIndex}`; // These IDs are local to the SceneModel\n\n                    let geometryArrays = geometryArraysCache[geometryId];\n\n                    if (!geometryArrays) {\n\n                        geometryArrays = {\n                            batchThisMesh: (!options.reuseGeometries)\n                        };\n\n                        const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n\n                        let geometryValid = false;\n\n                        switch (primitiveType) {\n                            case 0:\n                                geometryArrays.primitiveName = \"solid\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 1:\n                                geometryArrays.primitiveName = \"surface\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 2:\n                                geometryArrays.primitiveName = \"points\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryColors = convertColorsRGBToRGBA(colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]));\n                                geometryValid = (geometryArrays.geometryPositions.length > 0);\n                                break;\n                            case 3:\n                                geometryArrays.primitiveName = \"lines\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            default:\n                                continue;\n                        }\n\n                        if (!geometryValid) {\n                            geometryArrays = null;\n                        }\n\n                        if (geometryArrays) {\n                            if (geometryArrays.geometryPositions.length > 1000) ;\n                            if (geometryArrays.batchThisMesh) {\n                                geometryArrays.decompressedPositions = new Float32Array(geometryArrays.geometryPositions.length);\n                                const geometryPositions = geometryArrays.geometryPositions;\n                                const decompressedPositions = geometryArrays.decompressedPositions;\n                                for (let i = 0, len = geometryPositions.length; i < len; i += 3) {\n                                    decompressedPositions[i + 0] = geometryPositions[i + 0] * reusedGeometriesDecodeMatrix[0] + reusedGeometriesDecodeMatrix[12];\n                                    decompressedPositions[i + 1] = geometryPositions[i + 1] * reusedGeometriesDecodeMatrix[5] + reusedGeometriesDecodeMatrix[13];\n                                    decompressedPositions[i + 2] = geometryPositions[i + 2] * reusedGeometriesDecodeMatrix[10] + reusedGeometriesDecodeMatrix[14];\n                                }\n                                geometryArrays.geometryPositions = null;\n                                geometryArraysCache[geometryId] = geometryArrays;\n                            }\n                        }\n                    }\n\n                    if (geometryArrays) {\n\n                        if (geometryArrays.batchThisMesh) {\n\n                            const decompressedPositions = geometryArrays.decompressedPositions;\n                            const positions = new Uint16Array(decompressedPositions.length);\n                            for (let i = 0, len = decompressedPositions.length; i < len; i += 3) {\n                                tempVec4a$4[0] = decompressedPositions[i + 0];\n                                tempVec4a$4[1] = decompressedPositions[i + 1];\n                                tempVec4a$4[2] = decompressedPositions[i + 2];\n                                tempVec4a$4[3] = 1;\n                                math.transformVec4(meshMatrix, tempVec4a$4, tempVec4b$4);\n                                geometryCompressionUtils.compressPosition(tempVec4b$4, rtcAABB, tempVec4a$4);\n                                positions[i + 0] = tempVec4a$4[0];\n                                positions[i + 1] = tempVec4a$4[1];\n                                positions[i + 2] = tempVec4a$4[2];\n                            }\n\n                            sceneModel.createMesh(utils.apply(meshDefaults, {\n                                id: meshId,\n                                origin: tileCenter,\n                                primitive: geometryArrays.primitiveName,\n                                positionsCompressed: positions,\n                                normalsCompressed: geometryArrays.geometryNormals,\n                                colorsCompressed: geometryArrays.geometryColors,\n                                indices: geometryArrays.geometryIndices,\n                                edgeIndices: geometryArrays.geometryEdgeIndices,\n                                positionsDecodeMatrix: tileDecodeMatrix,\n                                color: meshColor,\n                                metallic: meshMetallic,\n                                roughness: meshRoughness,\n                                opacity: meshOpacity\n                            }));\n\n                            meshIds.push(meshId);\n\n                        } else {\n\n                            if (!geometryCreatedInTile[geometryId]) {\n\n                                sceneModel.createGeometry({\n                                    id: geometryId,\n                                    primitive: geometryArrays.primitiveName,\n                                    positionsCompressed: geometryArrays.geometryPositions,\n                                    normalsCompressed: geometryArrays.geometryNormals,\n                                    colorsCompressed: geometryArrays.geometryColors,\n                                    indices: geometryArrays.geometryIndices,\n                                    edgeIndices: geometryArrays.geometryEdgeIndices,\n                                    positionsDecodeMatrix: reusedGeometriesDecodeMatrix\n                                });\n\n                                geometryCreatedInTile[geometryId] = true;\n                            }\n\n                            sceneModel.createMesh(utils.apply(meshDefaults, {\n                                id: meshId,\n                                geometryId: geometryId,\n                                origin: tileCenter,\n                                matrix: meshMatrix,\n                                color: meshColor,\n                                metallic: meshMetallic,\n                                roughness: meshRoughness,\n                                opacity: meshOpacity\n                            }));\n\n                            meshIds.push(meshId);\n                        }\n                    }\n\n                } else {\n\n                    const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n\n                    let primitiveName;\n                    let geometryPositions;\n                    let geometryNormals;\n                    let geometryColors;\n                    let geometryIndices;\n                    let geometryEdgeIndices;\n                    let geometryValid = false;\n\n                    switch (primitiveType) {\n                        case 0:\n                            primitiveName = \"solid\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 1:\n                            primitiveName = \"surface\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 2:\n                            primitiveName = \"points\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryColors = convertColorsRGBToRGBA(colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]));\n                            geometryValid = (geometryPositions.length > 0);\n                            break;\n                        case 3:\n                            primitiveName = \"lines\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        default:\n                            continue;\n                    }\n\n                    if (geometryValid) {\n\n                        sceneModel.createMesh(utils.apply(meshDefaults, {\n                            id: meshId,\n                            origin: tileCenter,\n                            primitive: primitiveName,\n                            positionsCompressed: geometryPositions,\n                            normalsCompressed: geometryNormals,\n                            colorsCompressed: geometryColors,\n                            indices: geometryIndices,\n                            edgeIndices: geometryEdgeIndices,\n                            positionsDecodeMatrix: tileDecodeMatrix,\n                            color: meshColor,\n                            metallic: meshMetallic,\n                            roughness: meshRoughness,\n                            opacity: meshOpacity\n                        }));\n\n                        meshIds.push(meshId);\n                    }\n                }\n            }\n\n            if (meshIds.length > 0) {\n\n                sceneModel.createEntity(utils.apply(entityDefaults, {\n                    id: entityId,\n                    isObject: true,\n                    meshIds: meshIds\n                }));\n            }\n        }\n    }\n}\n\n/** @private */\nconst ParserV8 = {\n    version: 8,\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract$3(elements);\n        const inflatedData = inflate$3(deflatedData);\n        load$4(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n\n Parser for .XKT Format V9\n\n */\n\nlet pako$2 = window.pako || p;\nif (!pako$2.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako$2 = pako$2.default;\n}\n\nconst tempVec4a$3 = math.vec4();\nconst tempVec4b$3 = math.vec4();\n\nfunction extract$2(elements) {\n\n    return {\n\n        // Metadata\n\n        metadata: elements[0],\n\n        positions: elements[1],\n        normals: elements[2],\n        colors: elements[3],\n        indices: elements[4],\n        edgeIndices: elements[5],\n\n        // Transform matrices\n\n        matrices: elements[6],\n        reusedGeometriesDecodeMatrix: elements[7],\n\n        // Geometries\n\n        eachGeometryPrimitiveType: elements[8],\n        eachGeometryPositionsPortion: elements[9],\n        eachGeometryNormalsPortion: elements[10],\n        eachGeometryColorsPortion: elements[11],\n        eachGeometryIndicesPortion: elements[12],\n        eachGeometryEdgeIndicesPortion: elements[13],\n\n        // Meshes are grouped in runs that are shared by the same entities\n\n        eachMeshGeometriesPortion: elements[14],\n        eachMeshMatricesPortion: elements[15],\n        eachMeshMaterial: elements[16],\n\n        // Entity elements in the following arrays are grouped in runs that are shared by the same tiles\n\n        eachEntityId: elements[17],\n        eachEntityMeshesPortion: elements[18],\n\n        eachTileAABB: elements[19],\n        eachTileEntitiesPortion: elements[20]\n    };\n}\n\nfunction inflate$2(deflatedData) {\n\n    function inflate(array, options) {\n        return (array.length === 0) ? [] : pako$2.inflate(array, options).buffer;\n    }\n\n    return {\n\n        metadata: JSON.parse(pako$2.inflate(deflatedData.metadata, {to: 'string'})),\n\n        positions: new Uint16Array(inflate(deflatedData.positions)),\n        normals: new Int8Array(inflate(deflatedData.normals)),\n        colors: new Uint8Array(inflate(deflatedData.colors)),\n        indices: new Uint32Array(inflate(deflatedData.indices)),\n        edgeIndices: new Uint32Array(inflate(deflatedData.edgeIndices)),\n\n        matrices: new Float32Array(inflate(deflatedData.matrices)),\n        reusedGeometriesDecodeMatrix: new Float32Array(inflate(deflatedData.reusedGeometriesDecodeMatrix)),\n\n        eachGeometryPrimitiveType: new Uint8Array(inflate(deflatedData.eachGeometryPrimitiveType)),\n        eachGeometryPositionsPortion: new Uint32Array(inflate(deflatedData.eachGeometryPositionsPortion)),\n        eachGeometryNormalsPortion: new Uint32Array(inflate(deflatedData.eachGeometryNormalsPortion)),\n        eachGeometryColorsPortion: new Uint32Array(inflate(deflatedData.eachGeometryColorsPortion)),\n        eachGeometryIndicesPortion: new Uint32Array(inflate(deflatedData.eachGeometryIndicesPortion)),\n        eachGeometryEdgeIndicesPortion: new Uint32Array(inflate(deflatedData.eachGeometryEdgeIndicesPortion)),\n\n        eachMeshGeometriesPortion: new Uint32Array(inflate(deflatedData.eachMeshGeometriesPortion)),\n        eachMeshMatricesPortion: new Uint32Array(inflate(deflatedData.eachMeshMatricesPortion)),\n        eachMeshMaterial: new Uint8Array(inflate(deflatedData.eachMeshMaterial)),\n\n        eachEntityId: JSON.parse(pako$2.inflate(deflatedData.eachEntityId, {to: 'string'})),\n        eachEntityMeshesPortion: new Uint32Array(inflate(deflatedData.eachEntityMeshesPortion)),\n\n        eachTileAABB: new Float64Array(inflate(deflatedData.eachTileAABB)),\n        eachTileEntitiesPortion: new Uint32Array(inflate(deflatedData.eachTileEntitiesPortion)),\n    };\n}\n\nconst decompressColor$3 = (function () {\n    const floatColor = new Float32Array(3);\n    return function (intColor) {\n        floatColor[0] = intColor[0] / 255.0;\n        floatColor[1] = intColor[1] / 255.0;\n        floatColor[2] = intColor[2] / 255.0;\n        return floatColor;\n    };\n})();\n\nfunction load$3(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    const metadata = inflatedData.metadata;\n\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const colors = inflatedData.colors;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n\n    const matrices = inflatedData.matrices;\n    const reusedGeometriesDecodeMatrix = inflatedData.reusedGeometriesDecodeMatrix;\n\n    const eachGeometryPrimitiveType = inflatedData.eachGeometryPrimitiveType;\n    const eachGeometryPositionsPortion = inflatedData.eachGeometryPositionsPortion;\n    const eachGeometryNormalsPortion = inflatedData.eachGeometryNormalsPortion;\n    const eachGeometryColorsPortion = inflatedData.eachGeometryColorsPortion;\n    const eachGeometryIndicesPortion = inflatedData.eachGeometryIndicesPortion;\n    const eachGeometryEdgeIndicesPortion = inflatedData.eachGeometryEdgeIndicesPortion;\n\n    const eachMeshGeometriesPortion = inflatedData.eachMeshGeometriesPortion;\n    const eachMeshMatricesPortion = inflatedData.eachMeshMatricesPortion;\n    const eachMeshMaterial = inflatedData.eachMeshMaterial;\n\n    const eachEntityId = inflatedData.eachEntityId;\n    const eachEntityMeshesPortion = inflatedData.eachEntityMeshesPortion;\n\n    const eachTileAABB = inflatedData.eachTileAABB;\n    const eachTileEntitiesPortion = inflatedData.eachTileEntitiesPortion;\n\n    const numGeometries = eachGeometryPositionsPortion.length;\n    const numMeshes = eachMeshGeometriesPortion.length;\n    const numEntities = eachEntityMeshesPortion.length;\n    const numTiles = eachTileEntitiesPortion.length;\n\n    if (metaModel) {\n        metaModel.loadData(metadata, {\n            includeTypes: options.includeTypes,\n            excludeTypes: options.excludeTypes,\n            globalizeObjectIds: options.globalizeObjectIds\n        }); // Can be empty\n    }\n\n    // Count instances of each geometry\n\n    const geometryReuseCounts = new Uint32Array(numGeometries);\n\n    for (let meshIndex = 0; meshIndex < numMeshes; meshIndex++) {\n        const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n        if (geometryReuseCounts[geometryIndex] !== undefined) {\n            geometryReuseCounts[geometryIndex]++;\n        } else {\n            geometryReuseCounts[geometryIndex] = 1;\n        }\n    }\n\n    // Iterate over tiles\n\n    const tileCenter = math.vec3();\n    const rtcAABB = math.AABB3();\n\n    const geometryArraysCache = {};\n\n    for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {\n\n        const lastTileIndex = (numTiles - 1);\n\n        const atLastTile = (tileIndex === lastTileIndex);\n\n        const firstTileEntityIndex = eachTileEntitiesPortion [tileIndex];\n        const lastTileEntityIndex = atLastTile ? (numEntities - 1) : (eachTileEntitiesPortion[tileIndex + 1] - 1);\n\n        const tileAABBIndex = tileIndex * 6;\n        const tileAABB = eachTileAABB.subarray(tileAABBIndex, tileAABBIndex + 6);\n\n        math.getAABB3Center(tileAABB, tileCenter);\n\n        rtcAABB[0] = tileAABB[0] - tileCenter[0];\n        rtcAABB[1] = tileAABB[1] - tileCenter[1];\n        rtcAABB[2] = tileAABB[2] - tileCenter[2];\n        rtcAABB[3] = tileAABB[3] - tileCenter[0];\n        rtcAABB[4] = tileAABB[4] - tileCenter[1];\n        rtcAABB[5] = tileAABB[5] - tileCenter[2];\n\n        const tileDecodeMatrix = geometryCompressionUtils.createPositionsDecodeMatrix(rtcAABB);\n\n        const geometryCreatedInTile = {};\n\n        // Iterate over each tile's entities\n\n        for (let tileEntityIndex = firstTileEntityIndex; tileEntityIndex <= lastTileEntityIndex; tileEntityIndex++) {\n\n            const xktEntityId = eachEntityId[tileEntityIndex];\n\n            const entityId = options.globalizeObjectIds ? math.globalizeObjectId(sceneModel.id, xktEntityId) : xktEntityId;\n\n            const finalTileEntityIndex = (numEntities - 1);\n            const atLastTileEntity = (tileEntityIndex === finalTileEntityIndex);\n            const firstMeshIndex = eachEntityMeshesPortion [tileEntityIndex];\n            const lastMeshIndex = atLastTileEntity ? (eachMeshGeometriesPortion.length - 1) : (eachEntityMeshesPortion[tileEntityIndex + 1] - 1);\n\n            const meshIds = [];\n\n            const metaObject = viewer.metaScene.metaObjects[entityId];\n            const entityDefaults = {};\n            const meshDefaults = {};\n\n            if (metaObject) {\n\n                // Mask loading of object types\n\n                if (options.excludeTypesMap && metaObject.type && options.excludeTypesMap[metaObject.type]) {\n                    continue;\n                }\n\n                if (options.includeTypesMap && metaObject.type && (!options.includeTypesMap[metaObject.type])) {\n                    continue;\n                }\n\n                // Mask loading of object ids\n\n                if (options.includeIdsMap && metaObject.id && (!options.includeIdsMap[metaObject.id])) {\n                    continue;\n                }\n\n                // Get initial property values for object types\n\n                const props = options.objectDefaults ? options.objectDefaults[metaObject.type] || options.objectDefaults[\"DEFAULT\"] : null;\n\n                if (props) {\n                    if (props.visible === false) {\n                        entityDefaults.visible = false;\n                    }\n                    if (props.pickable === false) {\n                        entityDefaults.pickable = false;\n                    }\n                    if (props.colorize) {\n                        meshDefaults.color = props.colorize;\n                    }\n                    if (props.opacity !== undefined && props.opacity !== null) {\n                        meshDefaults.opacity = props.opacity;\n                    }\n                    if (props.metallic !== undefined && props.metallic !== null) {\n                        meshDefaults.metallic = props.metallic;\n                    }\n                    if (props.roughness !== undefined && props.roughness !== null) {\n                        meshDefaults.roughness = props.roughness;\n                    }\n                }\n\n            } else {\n                if (options.excludeUnclassifiedObjects) {\n                    continue;\n                }\n            }\n\n            // Iterate each entity's meshes\n\n            for (let meshIndex = firstMeshIndex; meshIndex <= lastMeshIndex; meshIndex++) {\n\n                const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n                const geometryReuseCount = geometryReuseCounts[geometryIndex];\n                const isReusedGeometry = (geometryReuseCount > 1);\n\n                const atLastGeometry = (geometryIndex === (numGeometries - 1));\n\n                const meshColor = decompressColor$3(eachMeshMaterial.subarray((meshIndex * 6), (meshIndex * 6) + 3));\n                const meshOpacity = eachMeshMaterial[(meshIndex * 6) + 3] / 255.0;\n                const meshMetallic = eachMeshMaterial[(meshIndex * 6) + 4] / 255.0;\n                const meshRoughness = eachMeshMaterial[(meshIndex * 6) + 5] / 255.0;\n\n                const meshId = manifestCtx.getNextId();\n\n                if (isReusedGeometry) {\n\n                    // Create mesh for multi-use geometry - create (or reuse) geometry, create mesh using that geometry\n\n                    const meshMatrixIndex = eachMeshMatricesPortion[meshIndex];\n                    const meshMatrix = matrices.slice(meshMatrixIndex, meshMatrixIndex + 16);\n\n                    const geometryId = `${modelPartId}-geometry.${tileIndex}.${geometryIndex}`; // These IDs are local to the SceneModel\n\n                    let geometryArrays = geometryArraysCache[geometryId];\n\n                    if (!geometryArrays) {\n                        geometryArrays = {\n                            batchThisMesh: (!options.reuseGeometries)\n                        };\n                        const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n                        let geometryValid = false;\n                        switch (primitiveType) {\n                            case 0:\n                                geometryArrays.primitiveName = \"solid\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 1:\n                                geometryArrays.primitiveName = \"surface\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 2:\n                                geometryArrays.primitiveName = \"points\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryColors = colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0);\n                                break;\n                            case 3:\n                                geometryArrays.primitiveName = \"lines\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            default:\n                                continue;\n                        }\n\n                        if (!geometryValid) {\n                            geometryArrays = null;\n                        }\n\n                        if (geometryArrays) {\n                            if (geometryArrays.geometryPositions.length > 1000) ;\n                            if (geometryArrays.batchThisMesh) {\n                                geometryArrays.decompressedPositions = new Float32Array(geometryArrays.geometryPositions.length);\n                                geometryArrays.transformedAndRecompressedPositions = new Uint16Array(geometryArrays.geometryPositions.length);\n                                const geometryPositions = geometryArrays.geometryPositions;\n                                const decompressedPositions = geometryArrays.decompressedPositions;\n                                for (let i = 0, len = geometryPositions.length; i < len; i += 3) {\n                                    decompressedPositions[i + 0] = geometryPositions[i + 0] * reusedGeometriesDecodeMatrix[0] + reusedGeometriesDecodeMatrix[12];\n                                    decompressedPositions[i + 1] = geometryPositions[i + 1] * reusedGeometriesDecodeMatrix[5] + reusedGeometriesDecodeMatrix[13];\n                                    decompressedPositions[i + 2] = geometryPositions[i + 2] * reusedGeometriesDecodeMatrix[10] + reusedGeometriesDecodeMatrix[14];\n                                }\n                                geometryArrays.geometryPositions = null;\n                                geometryArraysCache[geometryId] = geometryArrays;\n                            }\n                        }\n                    }\n\n                    if (geometryArrays) {\n\n                        if (geometryArrays.batchThisMesh) {\n\n                            const decompressedPositions = geometryArrays.decompressedPositions;\n                            const transformedAndRecompressedPositions = geometryArrays.transformedAndRecompressedPositions;\n\n                            for (let i = 0, len = decompressedPositions.length; i < len; i += 3) {\n                                tempVec4a$3[0] = decompressedPositions[i + 0];\n                                tempVec4a$3[1] = decompressedPositions[i + 1];\n                                tempVec4a$3[2] = decompressedPositions[i + 2];\n                                tempVec4a$3[3] = 1;\n                                math.transformVec4(meshMatrix, tempVec4a$3, tempVec4b$3);\n                                geometryCompressionUtils.compressPosition(tempVec4b$3, rtcAABB, tempVec4a$3);\n                                transformedAndRecompressedPositions[i + 0] = tempVec4a$3[0];\n                                transformedAndRecompressedPositions[i + 1] = tempVec4a$3[1];\n                                transformedAndRecompressedPositions[i + 2] = tempVec4a$3[2];\n                            }\n\n                            sceneModel.createMesh(utils.apply(meshDefaults, {\n                                id: meshId,\n                                origin: tileCenter,\n                                primitive: geometryArrays.primitiveName,\n                                positionsCompressed: transformedAndRecompressedPositions,\n                                normalsCompressed: geometryArrays.geometryNormals,\n                                colorsCompressed: geometryArrays.geometryColors,\n                                indices: geometryArrays.geometryIndices,\n                                edgeIndices: geometryArrays.geometryEdgeIndices,\n                                positionsDecodeMatrix: tileDecodeMatrix,\n                                color: meshColor,\n                                metallic: meshMetallic,\n                                roughness: meshRoughness,\n                                opacity: meshOpacity\n                            }));\n\n                            meshIds.push(meshId);\n\n                        } else {\n\n                            if (!geometryCreatedInTile[geometryId]) {\n\n                                sceneModel.createGeometry({\n                                    id: geometryId,\n                                    primitive: geometryArrays.primitiveName,\n                                    positionsCompressed: geometryArrays.geometryPositions,\n                                    normalsCompressed: geometryArrays.geometryNormals,\n                                    colorsCompressed: geometryArrays.geometryColors,\n                                    indices: geometryArrays.geometryIndices,\n                                    edgeIndices: geometryArrays.geometryEdgeIndices,\n                                    positionsDecodeMatrix: reusedGeometriesDecodeMatrix\n                                });\n\n                                geometryCreatedInTile[geometryId] = true;\n                            }\n\n                            sceneModel.createMesh(utils.apply(meshDefaults, {\n                                id: meshId,\n                                geometryId: geometryId,\n                                origin: tileCenter,\n                                matrix: meshMatrix,\n                                color: meshColor,\n                                metallic: meshMetallic,\n                                roughness: meshRoughness,\n                                opacity: meshOpacity\n                            }));\n\n                            meshIds.push(meshId);\n                        }\n                    }\n\n                } else {\n\n                    const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n\n                    let primitiveName;\n                    let geometryPositions;\n                    let geometryNormals;\n                    let geometryColors;\n                    let geometryIndices;\n                    let geometryEdgeIndices;\n                    let geometryValid = false;\n\n                    switch (primitiveType) {\n                        case 0:\n                            primitiveName = \"solid\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 1:\n                            primitiveName = \"surface\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 2:\n                            primitiveName = \"points\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryColors = colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0);\n                            break;\n                        case 3:\n                            primitiveName = \"lines\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        default:\n                            continue;\n                    }\n\n                    if (geometryValid) {\n\n                        sceneModel.createMesh(utils.apply(meshDefaults, {\n                            id: meshId,\n                            origin: tileCenter,\n                            primitive: primitiveName,\n                            positionsCompressed: geometryPositions,\n                            normalsCompressed: geometryNormals,\n                            colorsCompressed: geometryColors,\n                            indices: geometryIndices,\n                            edgeIndices: geometryEdgeIndices,\n                            positionsDecodeMatrix: tileDecodeMatrix,\n                            color: meshColor,\n                            metallic: meshMetallic,\n                            roughness: meshRoughness,\n                            opacity: meshOpacity\n                        }));\n\n                        meshIds.push(meshId);\n                    }\n                }\n            }\n\n            if (meshIds.length > 0) {\n\n                sceneModel.createEntity(utils.apply(entityDefaults, {\n                    id: entityId,\n                    isObject: true,\n                    meshIds: meshIds\n                }));\n            }\n        }\n    }\n}\n\n/** @private */\nconst ParserV9 = {\n    version: 9,\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract$2(elements);\n        const inflatedData = inflate$2(deflatedData);\n        load$3(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n Parser for .XKT Format V10\n*/\n\nlet pako$1 = window.pako || p;\nif (!pako$1.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako$1 = pako$1.default;\n}\n\nconst tempVec4a$2 = math.vec4();\nconst tempVec4b$2 = math.vec4();\n\nconst NUM_TEXTURE_ATTRIBUTES$2 = 9;\n\nfunction extract$1(elements) {\n\n    let i = 0;\n\n    return {\n        metadata: elements[i++],\n        textureData: elements[i++],\n        eachTextureDataPortion: elements[i++],\n        eachTextureAttributes: elements[i++],\n        positions: elements[i++],\n        normals: elements[i++],\n        colors: elements[i++],\n        uvs: elements[i++],\n        indices: elements[i++],\n        edgeIndices: elements[i++],\n        eachTextureSetTextures: elements[i++],\n        matrices: elements[i++],\n        reusedGeometriesDecodeMatrix: elements[i++],\n        eachGeometryPrimitiveType: elements[i++],\n        eachGeometryPositionsPortion: elements[i++],\n        eachGeometryNormalsPortion: elements[i++],\n        eachGeometryColorsPortion: elements[i++],\n        eachGeometryUVsPortion: elements[i++],\n        eachGeometryIndicesPortion: elements[i++],\n        eachGeometryEdgeIndicesPortion: elements[i++],\n        eachMeshGeometriesPortion: elements[i++],\n        eachMeshMatricesPortion: elements[i++],\n        eachMeshTextureSet: elements[i++],\n        eachMeshMaterialAttributes: elements[i++],\n        eachEntityId: elements[i++],\n        eachEntityMeshesPortion: elements[i++],\n        eachTileAABB: elements[i++],\n        eachTileEntitiesPortion: elements[i++]\n    };\n}\n\nfunction inflate$1(deflatedData) {\n\n    function inflate(array, options) {\n        return (array.length === 0) ? [] : pako$1.inflate(array, options).buffer;\n    }\n\n    return {\n        metadata: JSON.parse(pako$1.inflate(deflatedData.metadata, {to: 'string'})),\n        textureData: new Uint8Array(inflate(deflatedData.textureData)),  // <<----------------------------- ??? ZIPPing to blame?\n        eachTextureDataPortion: new Uint32Array(inflate(deflatedData.eachTextureDataPortion)),\n        eachTextureAttributes: new Uint16Array(inflate(deflatedData.eachTextureAttributes)),\n        positions: new Uint16Array(inflate(deflatedData.positions)),\n        normals: new Int8Array(inflate(deflatedData.normals)),\n        colors: new Uint8Array(inflate(deflatedData.colors)),\n        uvs: new Float32Array(inflate(deflatedData.uvs)),\n        indices: new Uint32Array(inflate(deflatedData.indices)),\n        edgeIndices: new Uint32Array(inflate(deflatedData.edgeIndices)),\n        eachTextureSetTextures: new Int32Array(inflate(deflatedData.eachTextureSetTextures)),\n        matrices: new Float32Array(inflate(deflatedData.matrices)),\n        reusedGeometriesDecodeMatrix: new Float32Array(inflate(deflatedData.reusedGeometriesDecodeMatrix)),\n        eachGeometryPrimitiveType: new Uint8Array(inflate(deflatedData.eachGeometryPrimitiveType)),\n        eachGeometryPositionsPortion: new Uint32Array(inflate(deflatedData.eachGeometryPositionsPortion)),\n        eachGeometryNormalsPortion: new Uint32Array(inflate(deflatedData.eachGeometryNormalsPortion)),\n        eachGeometryColorsPortion: new Uint32Array(inflate(deflatedData.eachGeometryColorsPortion)),\n        eachGeometryUVsPortion: new Uint32Array(inflate(deflatedData.eachGeometryUVsPortion)),\n        eachGeometryIndicesPortion: new Uint32Array(inflate(deflatedData.eachGeometryIndicesPortion)),\n        eachGeometryEdgeIndicesPortion: new Uint32Array(inflate(deflatedData.eachGeometryEdgeIndicesPortion)),\n        eachMeshGeometriesPortion: new Uint32Array(inflate(deflatedData.eachMeshGeometriesPortion)),\n        eachMeshMatricesPortion: new Uint32Array(inflate(deflatedData.eachMeshMatricesPortion)),\n        eachMeshTextureSet: new Int32Array(inflate(deflatedData.eachMeshTextureSet)), // Can be -1\n        eachMeshMaterialAttributes: new Uint8Array(inflate(deflatedData.eachMeshMaterialAttributes)),\n        eachEntityId: JSON.parse(pako$1.inflate(deflatedData.eachEntityId, {to: 'string'})),\n        eachEntityMeshesPortion: new Uint32Array(inflate(deflatedData.eachEntityMeshesPortion)),\n        eachTileAABB: new Float64Array(inflate(deflatedData.eachTileAABB)),\n        eachTileEntitiesPortion: new Uint32Array(inflate(deflatedData.eachTileEntitiesPortion)),\n    };\n}\n\nconst decompressColor$2 = (function () {\n    const floatColor = new Float32Array(3);\n    return function (intColor) {\n        floatColor[0] = intColor[0] / 255.0;\n        floatColor[1] = intColor[1] / 255.0;\n        floatColor[2] = intColor[2] / 255.0;\n        return floatColor;\n    };\n})();\n\n((function () {\n    const canvas = document.createElement('canvas');\n    const context = canvas.getContext('2d');\n    return function (imagedata) {\n        canvas.width = imagedata.width;\n        canvas.height = imagedata.height;\n        context.putImageData(imagedata, 0, 0);\n        return canvas.toDataURL();\n    };\n}))();\n\nfunction load$2(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    const metadata = inflatedData.metadata;\n    const textureData = inflatedData.textureData;\n    const eachTextureDataPortion = inflatedData.eachTextureDataPortion;\n    const eachTextureAttributes = inflatedData.eachTextureAttributes;\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const colors = inflatedData.colors;\n    const uvs = inflatedData.uvs;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n    const eachTextureSetTextures = inflatedData.eachTextureSetTextures;\n    const matrices = inflatedData.matrices;\n    const reusedGeometriesDecodeMatrix = inflatedData.reusedGeometriesDecodeMatrix;\n    const eachGeometryPrimitiveType = inflatedData.eachGeometryPrimitiveType;\n    const eachGeometryPositionsPortion = inflatedData.eachGeometryPositionsPortion;\n    const eachGeometryNormalsPortion = inflatedData.eachGeometryNormalsPortion;\n    const eachGeometryColorsPortion = inflatedData.eachGeometryColorsPortion;\n    const eachGeometryUVsPortion = inflatedData.eachGeometryUVsPortion;\n    const eachGeometryIndicesPortion = inflatedData.eachGeometryIndicesPortion;\n    const eachGeometryEdgeIndicesPortion = inflatedData.eachGeometryEdgeIndicesPortion;\n    const eachMeshGeometriesPortion = inflatedData.eachMeshGeometriesPortion;\n    const eachMeshMatricesPortion = inflatedData.eachMeshMatricesPortion;\n    const eachMeshTextureSet = inflatedData.eachMeshTextureSet;\n    const eachMeshMaterialAttributes = inflatedData.eachMeshMaterialAttributes;\n    const eachEntityId = inflatedData.eachEntityId;\n    const eachEntityMeshesPortion = inflatedData.eachEntityMeshesPortion;\n    const eachTileAABB = inflatedData.eachTileAABB;\n    const eachTileEntitiesPortion = inflatedData.eachTileEntitiesPortion;\n\n    const numTextures = eachTextureDataPortion.length;\n    const numTextureSets = eachTextureSetTextures.length / 5;\n    const numGeometries = eachGeometryPositionsPortion.length;\n    const numMeshes = eachMeshGeometriesPortion.length;\n    const numEntities = eachEntityMeshesPortion.length;\n    const numTiles = eachTileEntitiesPortion.length;\n\n    if (metaModel) {\n        metaModel.loadData(metadata, {\n            includeTypes: options.includeTypes,\n            excludeTypes: options.excludeTypes,\n            globalizeObjectIds: options.globalizeObjectIds\n        }); // Can be empty\n    }\n\n    // Create textures\n\n    for (let textureIndex = 0; textureIndex < numTextures; textureIndex++) {\n        const atLastTexture = (textureIndex === (numTextures - 1));\n        const textureDataPortionStart = eachTextureDataPortion[textureIndex];\n        const textureDataPortionEnd = atLastTexture ? textureData.length : (eachTextureDataPortion[textureIndex + 1]);\n\n        const textureDataPortionSize = textureDataPortionEnd - textureDataPortionStart;\n        const textureDataPortionExists = (textureDataPortionSize > 0);\n\n        const textureAttrBaseIdx = (textureIndex * NUM_TEXTURE_ATTRIBUTES$2);\n\n        const compressed = (eachTextureAttributes[textureAttrBaseIdx + 0] === 1);\n        const mediaType = eachTextureAttributes[textureAttrBaseIdx + 1];\n        eachTextureAttributes[textureAttrBaseIdx + 2];\n        eachTextureAttributes[textureAttrBaseIdx + 3];\n        const minFilter = eachTextureAttributes[textureAttrBaseIdx + 4];\n        const magFilter = eachTextureAttributes[textureAttrBaseIdx + 5]; // LinearFilter | NearestFilter\n        const wrapS = eachTextureAttributes[textureAttrBaseIdx + 6]; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n        const wrapT = eachTextureAttributes[textureAttrBaseIdx + 7]; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n        const wrapR = eachTextureAttributes[textureAttrBaseIdx + 8]; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n\n        if (textureDataPortionExists) {\n\n            const imageDataSubarray = new Uint8Array(textureData.subarray(textureDataPortionStart, textureDataPortionEnd));\n            const arrayBuffer = imageDataSubarray.buffer;\n            const textureId = `${modelPartId}-texture-${textureIndex}`;\n\n            if (compressed) {\n\n                sceneModel.createTexture({\n                    id: textureId,\n                    buffers: [arrayBuffer],\n                    minFilter,\n                    magFilter,\n                    wrapS,\n                    wrapT,\n                    wrapR\n                });\n\n            } else {\n\n                const mimeType = mediaType === JPEGMediaType ? \"image/jpeg\" : (mediaType === PNGMediaType ? \"image/png\" : \"image/gif\");\n                const blob = new Blob([arrayBuffer], {type: mimeType});\n                const urlCreator = window.URL || window.webkitURL;\n                const imageUrl = urlCreator.createObjectURL(blob);\n                const img = document.createElement('img');\n                img.src = imageUrl;\n\n                sceneModel.createTexture({\n                    id: textureId,\n                    image: img,\n                    //mediaType,\n                    minFilter,\n                    magFilter,\n                    wrapS,\n                    wrapT,\n                    wrapR\n                });\n            }\n        }\n    }\n\n    // Create texture sets\n\n    for (let textureSetIndex = 0; textureSetIndex < numTextureSets; textureSetIndex++) {\n        const eachTextureSetTexturesIndex = textureSetIndex * 5;\n        const textureSetId = `${modelPartId}-textureSet-${textureSetIndex}`;\n        const colorTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 0];\n        const metallicRoughnessTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 1];\n        const normalsTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 2];\n        const emissiveTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 3];\n        const occlusionTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 4];\n        sceneModel.createTextureSet({\n            id: textureSetId,\n            colorTextureId: colorTextureIndex >= 0 ? `${modelPartId}-texture-${colorTextureIndex}` : null,\n            normalsTextureId: normalsTextureIndex >= 0 ? `${modelPartId}-texture-${normalsTextureIndex}` : null,\n            metallicRoughnessTextureId: metallicRoughnessTextureIndex >= 0 ? `${modelPartId}-texture-${metallicRoughnessTextureIndex}` : null,\n            emissiveTextureId: emissiveTextureIndex >= 0 ? `${modelPartId}-texture-${emissiveTextureIndex}` : null,\n            occlusionTextureId: occlusionTextureIndex >= 0 ? `${modelPartId}-texture-${occlusionTextureIndex}` : null\n        });\n    }\n\n    // Count instances of each geometry\n\n    const geometryReuseCounts = new Uint32Array(numGeometries);\n\n    for (let meshIndex = 0; meshIndex < numMeshes; meshIndex++) {\n        const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n        if (geometryReuseCounts[geometryIndex] !== undefined) {\n            geometryReuseCounts[geometryIndex]++;\n        } else {\n            geometryReuseCounts[geometryIndex] = 1;\n        }\n    }\n\n    // Iterate over tiles\n\n    const tileCenter = math.vec3();\n    const rtcAABB = math.AABB3();\n\n    const geometryArraysCache = {};\n\n    for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {\n\n        const lastTileIndex = (numTiles - 1);\n\n        const atLastTile = (tileIndex === lastTileIndex);\n\n        const firstTileEntityIndex = eachTileEntitiesPortion [tileIndex];\n        const lastTileEntityIndex = atLastTile ? (numEntities - 1) : (eachTileEntitiesPortion[tileIndex + 1] - 1);\n\n        const tileAABBIndex = tileIndex * 6;\n        const tileAABB = eachTileAABB.subarray(tileAABBIndex, tileAABBIndex + 6);\n\n        math.getAABB3Center(tileAABB, tileCenter);\n\n        rtcAABB[0] = tileAABB[0] - tileCenter[0];\n        rtcAABB[1] = tileAABB[1] - tileCenter[1];\n        rtcAABB[2] = tileAABB[2] - tileCenter[2];\n        rtcAABB[3] = tileAABB[3] - tileCenter[0];\n        rtcAABB[4] = tileAABB[4] - tileCenter[1];\n        rtcAABB[5] = tileAABB[5] - tileCenter[2];\n\n        const tileDecodeMatrix = geometryCompressionUtils.createPositionsDecodeMatrix(rtcAABB);\n\n        const geometryCreatedInTile = {};\n\n        // Iterate over each tile's entities\n\n        for (let tileEntityIndex = firstTileEntityIndex; tileEntityIndex <= lastTileEntityIndex; tileEntityIndex++) {\n\n            const xktEntityId = eachEntityId[tileEntityIndex];\n\n            const entityId = options.globalizeObjectIds ? math.globalizeObjectId(sceneModel.id, xktEntityId) : xktEntityId;\n\n            const finalTileEntityIndex = (numEntities - 1);\n            const atLastTileEntity = (tileEntityIndex === finalTileEntityIndex);\n            const firstMeshIndex = eachEntityMeshesPortion [tileEntityIndex];\n            const lastMeshIndex = atLastTileEntity ? (eachMeshGeometriesPortion.length - 1) : (eachEntityMeshesPortion[tileEntityIndex + 1] - 1);\n\n            const meshIds = [];\n\n            const metaObject = viewer.metaScene.metaObjects[entityId];\n            const entityDefaults = {};\n            const meshDefaults = {};\n\n            if (metaObject) {\n\n                // Mask loading of object types\n\n                if (options.excludeTypesMap && metaObject.type && options.excludeTypesMap[metaObject.type]) {\n                    continue;\n                }\n\n                if (options.includeTypesMap && metaObject.type && (!options.includeTypesMap[metaObject.type])) {\n                    continue;\n                }\n\n                // Mask loading of object ids\n\n                if (options.includeIdsMap && metaObject.id && (!options.includeIdsMap[metaObject.id])) {\n                    continue;\n                }\n\n                // Get initial property values for object types\n\n                const props = options.objectDefaults ? options.objectDefaults[metaObject.type] || options.objectDefaults[\"DEFAULT\"] : null;\n\n                if (props) {\n                    if (props.visible === false) {\n                        entityDefaults.visible = false;\n                    }\n                    if (props.pickable === false) {\n                        entityDefaults.pickable = false;\n                    }\n                    if (props.colorize) {\n                        meshDefaults.color = props.colorize;\n                    }\n                    if (props.opacity !== undefined && props.opacity !== null) {\n                        meshDefaults.opacity = props.opacity;\n                    }\n                    if (props.metallic !== undefined && props.metallic !== null) {\n                        meshDefaults.metallic = props.metallic;\n                    }\n                    if (props.roughness !== undefined && props.roughness !== null) {\n                        meshDefaults.roughness = props.roughness;\n                    }\n                }\n\n            } else {\n                if (options.excludeUnclassifiedObjects) {\n                    continue;\n                }\n            }\n\n            // Iterate each entity's meshes\n\n            for (let meshIndex = firstMeshIndex; meshIndex <= lastMeshIndex; meshIndex++) {\n\n                const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n                const geometryReuseCount = geometryReuseCounts[geometryIndex];\n                const isReusedGeometry = (geometryReuseCount > 1);\n\n                const atLastGeometry = (geometryIndex === (numGeometries - 1));\n\n                const textureSetIndex = eachMeshTextureSet[meshIndex];\n\n                const textureSetId = (textureSetIndex >= 0) ? `${modelPartId}-textureSet-${textureSetIndex}` : null;\n\n                const meshColor = decompressColor$2(eachMeshMaterialAttributes.subarray((meshIndex * 6), (meshIndex * 6) + 3));\n                const meshOpacity = eachMeshMaterialAttributes[(meshIndex * 6) + 3] / 255.0;\n                const meshMetallic = eachMeshMaterialAttributes[(meshIndex * 6) + 4] / 255.0;\n                const meshRoughness = eachMeshMaterialAttributes[(meshIndex * 6) + 5] / 255.0;\n\n                const meshId = manifestCtx.getNextId();\n\n                if (isReusedGeometry) {\n\n                    // Create mesh for multi-use geometry - create (or reuse) geometry, create mesh using that geometry\n\n                    const meshMatrixIndex = eachMeshMatricesPortion[meshIndex];\n                    const meshMatrix = matrices.slice(meshMatrixIndex, meshMatrixIndex + 16);\n\n                    const geometryId = `${modelPartId}-geometry.${tileIndex}.${geometryIndex}`; // These IDs are local to the SceneModel\n\n                    let geometryArrays = geometryArraysCache[geometryId];\n\n                    if (!geometryArrays) {\n                        geometryArrays = {\n                            batchThisMesh: (!options.reuseGeometries)\n                        };\n                        const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n                        let geometryValid = false;\n                        switch (primitiveType) {\n                            case 0:\n                                geometryArrays.primitiveName = \"solid\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 1:\n                                geometryArrays.primitiveName = \"surface\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 2:\n                                geometryArrays.primitiveName = \"points\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryColors = colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0);\n                                break;\n                            case 3:\n                                geometryArrays.primitiveName = \"lines\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 4:\n                                geometryArrays.primitiveName = \"lines\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = lineStripToLines$2(\n                                    geometryArrays.geometryPositions,\n                                    indices.subarray(eachGeometryIndicesPortion [geometryIndex],\n                                        atLastGeometry\n                                            ? indices.length\n                                            : eachGeometryIndicesPortion [geometryIndex + 1]));\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            default:\n                                continue;\n                        }\n\n                        if (!geometryValid) {\n                            geometryArrays = null;\n                        }\n\n                        if (geometryArrays) {\n                            if (geometryArrays.geometryPositions.length > 1000) ;\n                            if (geometryArrays.batchThisMesh) {\n                                geometryArrays.decompressedPositions = new Float32Array(geometryArrays.geometryPositions.length);\n                                geometryArrays.transformedAndRecompressedPositions = new Uint16Array(geometryArrays.geometryPositions.length);\n                                const geometryPositions = geometryArrays.geometryPositions;\n                                const decompressedPositions = geometryArrays.decompressedPositions;\n                                for (let i = 0, len = geometryPositions.length; i < len; i += 3) {\n                                    decompressedPositions[i + 0] = geometryPositions[i + 0] * reusedGeometriesDecodeMatrix[0] + reusedGeometriesDecodeMatrix[12];\n                                    decompressedPositions[i + 1] = geometryPositions[i + 1] * reusedGeometriesDecodeMatrix[5] + reusedGeometriesDecodeMatrix[13];\n                                    decompressedPositions[i + 2] = geometryPositions[i + 2] * reusedGeometriesDecodeMatrix[10] + reusedGeometriesDecodeMatrix[14];\n                                }\n                                geometryArrays.geometryPositions = null;\n                                geometryArraysCache[geometryId] = geometryArrays;\n                            }\n                        }\n                    }\n\n                    if (geometryArrays) {\n\n                        if (geometryArrays.batchThisMesh) {\n\n                            const decompressedPositions = geometryArrays.decompressedPositions;\n                            const transformedAndRecompressedPositions = geometryArrays.transformedAndRecompressedPositions;\n\n                            for (let i = 0, len = decompressedPositions.length; i < len; i += 3) {\n                                tempVec4a$2[0] = decompressedPositions[i + 0];\n                                tempVec4a$2[1] = decompressedPositions[i + 1];\n                                tempVec4a$2[2] = decompressedPositions[i + 2];\n                                tempVec4a$2[3] = 1;\n                                math.transformVec4(meshMatrix, tempVec4a$2, tempVec4b$2);\n                                geometryCompressionUtils.compressPosition(tempVec4b$2, rtcAABB, tempVec4a$2);\n                                transformedAndRecompressedPositions[i + 0] = tempVec4a$2[0];\n                                transformedAndRecompressedPositions[i + 1] = tempVec4a$2[1];\n                                transformedAndRecompressedPositions[i + 2] = tempVec4a$2[2];\n                            }\n\n                            sceneModel.createMesh(utils.apply(meshDefaults, {\n                                id: meshId,\n                                textureSetId,\n                                origin: tileCenter,\n                                primitive: geometryArrays.primitiveName,\n                                positionsCompressed: transformedAndRecompressedPositions,\n                                normalsCompressed: geometryArrays.geometryNormals,\n                                uv: geometryArrays.geometryUVs,\n                                colorsCompressed: geometryArrays.geometryColors,\n                                indices: geometryArrays.geometryIndices,\n                                edgeIndices: geometryArrays.geometryEdgeIndices,\n                                positionsDecodeMatrix: tileDecodeMatrix,\n                                color: meshColor,\n                                metallic: meshMetallic,\n                                roughness: meshRoughness,\n                                opacity: meshOpacity\n                            }));\n\n                            meshIds.push(meshId);\n\n                        } else {\n\n                            if (!geometryCreatedInTile[geometryId]) {\n\n                                sceneModel.createGeometry({\n                                    id: geometryId,\n                                    primitive: geometryArrays.primitiveName,\n                                    positionsCompressed: geometryArrays.geometryPositions,\n                                    normalsCompressed: geometryArrays.geometryNormals,\n                                    uv: geometryArrays.geometryUVs,\n                                    colorsCompressed: geometryArrays.geometryColors,\n                                    indices: geometryArrays.geometryIndices,\n                                    edgeIndices: geometryArrays.geometryEdgeIndices,\n                                    positionsDecodeMatrix: reusedGeometriesDecodeMatrix\n                                });\n\n                                geometryCreatedInTile[geometryId] = true;\n                            }\n\n                            sceneModel.createMesh(utils.apply(meshDefaults, {\n                                id: meshId,\n                                geometryId,\n                                textureSetId,\n                                matrix: meshMatrix,\n                                color: meshColor,\n                                metallic: meshMetallic,\n                                roughness: meshRoughness,\n                                opacity: meshOpacity,\n                                origin: tileCenter\n                            }));\n\n                            meshIds.push(meshId);\n                        }\n                    }\n\n                } else { // Do not reuse geometry\n\n                    const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n\n                    let primitiveName;\n                    let geometryPositions;\n                    let geometryNormals;\n                    let geometryUVs;\n                    let geometryColors;\n                    let geometryIndices;\n                    let geometryEdgeIndices;\n                    let geometryValid = false;\n\n                    switch (primitiveType) {\n                        case 0:\n                            primitiveName = \"solid\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 1:\n                            primitiveName = \"surface\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 2:\n                            primitiveName = \"points\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryColors = colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0);\n                            break;\n                        case 3:\n                            primitiveName = \"lines\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 4:\n                            primitiveName = \"lines\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryIndices = lineStripToLines$2(\n                                geometryPositions,\n                                indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry\n                                    ? indices.length\n                                    : eachGeometryIndicesPortion [geometryIndex + 1]));\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        default:\n                            continue;\n                    }\n\n                    if (geometryValid) {\n\n                        sceneModel.createMesh(utils.apply(meshDefaults, {\n                            id: meshId,\n                            textureSetId,\n                            origin: tileCenter,\n                            primitive: primitiveName,\n                            positionsCompressed: geometryPositions,\n                            normalsCompressed: geometryNormals,\n                            uv: geometryUVs && geometryUVs.length > 0 ? geometryUVs : null,\n                            colorsCompressed: geometryColors,\n                            indices: geometryIndices,\n                            edgeIndices: geometryEdgeIndices,\n                            positionsDecodeMatrix: tileDecodeMatrix,\n                            color: meshColor,\n                            metallic: meshMetallic,\n                            roughness: meshRoughness,\n                            opacity: meshOpacity\n                        }));\n\n                        meshIds.push(meshId);\n                    }\n                }\n            }\n\n            if (meshIds.length > 0) {\n\n                sceneModel.createEntity(utils.apply(entityDefaults, {\n                    id: entityId,\n                    isObject: true,\n                    meshIds: meshIds\n                }));\n            }\n        }\n    }\n}\n\nfunction lineStripToLines$2(positions, indices) {\n    const linesIndices = [];\n    if (indices.length > 1) {\n        for (let i = 0, len = indices.length - 1; i < len; i++) {\n            linesIndices.push(indices[i]);\n            linesIndices.push(indices[i + 1]);\n        }\n    } else if (positions.length > 1) {\n        for (let i = 0, len = (positions.length / 3) - 1; i < len; i++) {\n            linesIndices.push(i);\n            linesIndices.push(i + 1);\n        }\n    }\n    return linesIndices;\n}\n\n/** @private */\nconst ParserV10 = {\n    version: 10,\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract$1(elements);\n        const inflatedData = inflate$1(deflatedData);\n        load$2(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n Parser for .XKT Format V11\n*/\n\nconst tempVec4a$1 = math.vec4();\nconst tempVec4b$1 = math.vec4();\n\nconst NUM_TEXTURE_ATTRIBUTES$1 = 9;\n\nfunction decodeData$1(arrayBuffer) {\n    const requiresSwapFromLittleEndian = (function() {\n        const buffer = new ArrayBuffer(2);\n        new Uint16Array(buffer)[0] = 1;\n        return new Uint8Array(buffer)[0] !== 1;\n    })();\n\n    const nextArray = (function() {\n        let i = 0;\n        const dataView = new DataView(arrayBuffer);\n        return function(type) {\n            const idx = 1 + 2 * i++; // `1' for the version nr\n            const byteOffset = dataView.getUint32(idx       * 4, true);\n            const byteLength = dataView.getUint32((idx + 1) * 4, true);\n\n            const BPE = type.BYTES_PER_ELEMENT;\n            if (requiresSwapFromLittleEndian && (BPE > 1)) {\n                const subarray = new Uint8Array(arrayBuffer, byteOffset, byteLength);\n                const swaps = BPE / 2;\n                const cnt = subarray.length / BPE;\n                for (let b = 0; b < cnt; b++) {\n                    const offset = b * BPE;\n                    for (let j = 0; j < swaps; j++) {\n                        const i1 = offset + j;\n                        const i2 = offset - j + BPE - 1;\n                        const tmp = subarray[i1];\n                        subarray[i1] = subarray[i2];\n                        subarray[i2] = tmp;\n                    }\n                }\n            }\n\n            return new type(arrayBuffer, byteOffset, byteLength / BPE);\n        };\n    })();\n\n    const nextObject = (function() {\n        const decoder = new TextDecoder();\n        return () => JSON.parse(decoder.decode(nextArray(Uint8Array)));\n    })();\n\n    return {\n        metadata:                       nextObject(),\n        textureData:                    nextArray(Uint8Array),  // <<----------------------------- ??? ZIPPing to blame?\n        eachTextureDataPortion:         nextArray(Uint32Array),\n        eachTextureAttributes:          nextArray(Uint16Array),\n        positions:                      nextArray(Uint16Array),\n        normals:                        nextArray(Int8Array),\n        colors:                         nextArray(Uint8Array),\n        uvs:                            nextArray(Float32Array),\n        indices:                        nextArray(Uint32Array),\n        edgeIndices:                    nextArray(Uint32Array),\n        eachTextureSetTextures:         nextArray(Int32Array),\n        matrices:                       nextArray(Float32Array),\n        reusedGeometriesDecodeMatrix:   nextArray(Float32Array),\n        eachGeometryPrimitiveType:      nextArray(Uint8Array),\n        eachGeometryPositionsPortion:   nextArray(Uint32Array),\n        eachGeometryNormalsPortion:     nextArray(Uint32Array),\n        eachGeometryColorsPortion:      nextArray(Uint32Array),\n        eachGeometryUVsPortion:         nextArray(Uint32Array),\n        eachGeometryIndicesPortion:     nextArray(Uint32Array),\n        eachGeometryEdgeIndicesPortion: nextArray(Uint32Array),\n        eachMeshGeometriesPortion:      nextArray(Uint32Array),\n        eachMeshMatricesPortion:        nextArray(Uint32Array),\n        eachMeshTextureSet:             nextArray(Int32Array), // Can be -1\n        eachMeshMaterialAttributes:     nextArray(Uint8Array),\n        eachEntityId:                   nextObject(),\n        eachEntityMeshesPortion:        nextArray(Uint32Array),\n        eachTileAABB:                   nextArray(Float64Array),\n        eachTileEntitiesPortion:        nextArray(Uint32Array),\n    };\n}\n\nconst decompressColor$1 = (function () {\n    const floatColor = new Float32Array(3);\n    return function (intColor) {\n        floatColor[0] = intColor[0] / 255.0;\n        floatColor[1] = intColor[1] / 255.0;\n        floatColor[2] = intColor[2] / 255.0;\n        return floatColor;\n    };\n})();\n\n((function () {\n    const canvas = document.createElement('canvas');\n    const context = canvas.getContext('2d');\n    return function (imagedata) {\n        canvas.width = imagedata.width;\n        canvas.height = imagedata.height;\n        context.putImageData(imagedata, 0, 0);\n        return canvas.toDataURL();\n    };\n}))();\n\nfunction load$1(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    const metadata = inflatedData.metadata;\n    const textureData = inflatedData.textureData;\n    const eachTextureDataPortion = inflatedData.eachTextureDataPortion;\n    const eachTextureAttributes = inflatedData.eachTextureAttributes;\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const colors = inflatedData.colors;\n    const uvs = inflatedData.uvs;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n    const eachTextureSetTextures = inflatedData.eachTextureSetTextures;\n    const matrices = inflatedData.matrices;\n    const reusedGeometriesDecodeMatrix = inflatedData.reusedGeometriesDecodeMatrix;\n    const eachGeometryPrimitiveType = inflatedData.eachGeometryPrimitiveType;\n    const eachGeometryPositionsPortion = inflatedData.eachGeometryPositionsPortion;\n    const eachGeometryNormalsPortion = inflatedData.eachGeometryNormalsPortion;\n    const eachGeometryColorsPortion = inflatedData.eachGeometryColorsPortion;\n    const eachGeometryUVsPortion = inflatedData.eachGeometryUVsPortion;\n    const eachGeometryIndicesPortion = inflatedData.eachGeometryIndicesPortion;\n    const eachGeometryEdgeIndicesPortion = inflatedData.eachGeometryEdgeIndicesPortion;\n    const eachMeshGeometriesPortion = inflatedData.eachMeshGeometriesPortion;\n    const eachMeshMatricesPortion = inflatedData.eachMeshMatricesPortion;\n    const eachMeshTextureSet = inflatedData.eachMeshTextureSet;\n    const eachMeshMaterialAttributes = inflatedData.eachMeshMaterialAttributes;\n    const eachEntityId = inflatedData.eachEntityId;\n    const eachEntityMeshesPortion = inflatedData.eachEntityMeshesPortion;\n    const eachTileAABB = inflatedData.eachTileAABB;\n    const eachTileEntitiesPortion = inflatedData.eachTileEntitiesPortion;\n\n    const numTextures = eachTextureDataPortion.length;\n    const numTextureSets = eachTextureSetTextures.length / 5;\n    const numGeometries = eachGeometryPositionsPortion.length;\n    const numMeshes = eachMeshGeometriesPortion.length;\n    const numEntities = eachEntityMeshesPortion.length;\n    const numTiles = eachTileEntitiesPortion.length;\n\n    if (metaModel) {\n        metaModel.loadData(metadata, {\n            includeTypes: options.includeTypes,\n            excludeTypes: options.excludeTypes,\n            globalizeObjectIds: options.globalizeObjectIds\n        }); // Can be empty\n    }\n\n    // Create textures\n\n    for (let textureIndex = 0; textureIndex < numTextures; textureIndex++) {\n        const atLastTexture = (textureIndex === (numTextures - 1));\n        const textureDataPortionStart = eachTextureDataPortion[textureIndex];\n        const textureDataPortionEnd = atLastTexture ? textureData.length : (eachTextureDataPortion[textureIndex + 1]);\n\n        const textureDataPortionSize = textureDataPortionEnd - textureDataPortionStart;\n        const textureDataPortionExists = (textureDataPortionSize > 0);\n\n        const textureAttrBaseIdx = (textureIndex * NUM_TEXTURE_ATTRIBUTES$1);\n\n        const compressed = (eachTextureAttributes[textureAttrBaseIdx + 0] === 1);\n        const mediaType = eachTextureAttributes[textureAttrBaseIdx + 1];\n        eachTextureAttributes[textureAttrBaseIdx + 2];\n        eachTextureAttributes[textureAttrBaseIdx + 3];\n        const minFilter = eachTextureAttributes[textureAttrBaseIdx + 4];\n        const magFilter = eachTextureAttributes[textureAttrBaseIdx + 5]; // LinearFilter | NearestFilter\n        const wrapS = eachTextureAttributes[textureAttrBaseIdx + 6]; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n        const wrapT = eachTextureAttributes[textureAttrBaseIdx + 7]; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n        const wrapR = eachTextureAttributes[textureAttrBaseIdx + 8]; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n\n        if (textureDataPortionExists) {\n\n            const imageDataSubarray = new Uint8Array(textureData.subarray(textureDataPortionStart, textureDataPortionEnd));\n            const arrayBuffer = imageDataSubarray.buffer;\n            const textureId = `${modelPartId}-texture-${textureIndex}`;\n\n            if (compressed) {\n\n                sceneModel.createTexture({\n                    id: textureId,\n                    buffers: [arrayBuffer],\n                    minFilter,\n                    magFilter,\n                    wrapS,\n                    wrapT,\n                    wrapR\n                });\n\n            } else {\n\n                const mimeType = mediaType === JPEGMediaType ? \"image/jpeg\" : (mediaType === PNGMediaType ? \"image/png\" : \"image/gif\");\n                const blob = new Blob([arrayBuffer], {type: mimeType});\n                const urlCreator = window.URL || window.webkitURL;\n                const imageUrl = urlCreator.createObjectURL(blob);\n                const img = document.createElement('img');\n                img.src = imageUrl;\n\n                sceneModel.createTexture({\n                    id: textureId,\n                    image: img,\n                    //mediaType,\n                    minFilter,\n                    magFilter,\n                    wrapS,\n                    wrapT,\n                    wrapR\n                });\n            }\n        }\n    }\n\n    // Create texture sets\n\n    for (let textureSetIndex = 0; textureSetIndex < numTextureSets; textureSetIndex++) {\n        const eachTextureSetTexturesIndex = textureSetIndex * 5;\n        const textureSetId = `${modelPartId}-textureSet-${textureSetIndex}`;\n        const colorTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 0];\n        const metallicRoughnessTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 1];\n        const normalsTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 2];\n        const emissiveTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 3];\n        const occlusionTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 4];\n        sceneModel.createTextureSet({\n            id: textureSetId,\n            colorTextureId: colorTextureIndex >= 0 ? `${modelPartId}-texture-${colorTextureIndex}` : null,\n            normalsTextureId: normalsTextureIndex >= 0 ? `${modelPartId}-texture-${normalsTextureIndex}` : null,\n            metallicRoughnessTextureId: metallicRoughnessTextureIndex >= 0 ? `${modelPartId}-texture-${metallicRoughnessTextureIndex}` : null,\n            emissiveTextureId: emissiveTextureIndex >= 0 ? `${modelPartId}-texture-${emissiveTextureIndex}` : null,\n            occlusionTextureId: occlusionTextureIndex >= 0 ? `${modelPartId}-texture-${occlusionTextureIndex}` : null\n        });\n    }\n\n    // Count instances of each geometry\n\n    const geometryReuseCounts = new Uint32Array(numGeometries);\n\n    for (let meshIndex = 0; meshIndex < numMeshes; meshIndex++) {\n        const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n        if (geometryReuseCounts[geometryIndex] !== undefined) {\n            geometryReuseCounts[geometryIndex]++;\n        } else {\n            geometryReuseCounts[geometryIndex] = 1;\n        }\n    }\n\n    // Iterate over tiles\n\n    const tileCenter = math.vec3();\n    const rtcAABB = math.AABB3();\n\n    const geometryArraysCache = {};\n\n    for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {\n\n        const lastTileIndex = (numTiles - 1);\n\n        const atLastTile = (tileIndex === lastTileIndex);\n\n        const firstTileEntityIndex = eachTileEntitiesPortion [tileIndex];\n        const lastTileEntityIndex = atLastTile ? (numEntities - 1) : (eachTileEntitiesPortion[tileIndex + 1] - 1);\n\n        const tileAABBIndex = tileIndex * 6;\n        const tileAABB = eachTileAABB.subarray(tileAABBIndex, tileAABBIndex + 6);\n\n        math.getAABB3Center(tileAABB, tileCenter);\n\n        rtcAABB[0] = tileAABB[0] - tileCenter[0];\n        rtcAABB[1] = tileAABB[1] - tileCenter[1];\n        rtcAABB[2] = tileAABB[2] - tileCenter[2];\n        rtcAABB[3] = tileAABB[3] - tileCenter[0];\n        rtcAABB[4] = tileAABB[4] - tileCenter[1];\n        rtcAABB[5] = tileAABB[5] - tileCenter[2];\n\n        const tileDecodeMatrix = geometryCompressionUtils.createPositionsDecodeMatrix(rtcAABB);\n\n        const geometryCreatedInTile = {};\n\n        // Iterate over each tile's entities\n\n        for (let tileEntityIndex = firstTileEntityIndex; tileEntityIndex <= lastTileEntityIndex; tileEntityIndex++) {\n\n            const xktEntityId = eachEntityId[tileEntityIndex];\n\n            const entityId = options.globalizeObjectIds ? math.globalizeObjectId(sceneModel.id, xktEntityId) : xktEntityId;\n\n            const finalTileEntityIndex = (numEntities - 1);\n            const atLastTileEntity = (tileEntityIndex === finalTileEntityIndex);\n            const firstMeshIndex = eachEntityMeshesPortion [tileEntityIndex];\n            const lastMeshIndex = atLastTileEntity ? (eachMeshGeometriesPortion.length - 1) : (eachEntityMeshesPortion[tileEntityIndex + 1] - 1);\n\n            const meshIds = [];\n\n            const metaObject = viewer.metaScene.metaObjects[entityId];\n            const entityDefaults = {};\n            const meshDefaults = {};\n\n            if (metaObject) {\n\n                // Mask loading of object types\n\n                if (options.excludeTypesMap && metaObject.type && options.excludeTypesMap[metaObject.type]) {\n                    continue;\n                }\n\n                if (options.includeTypesMap && metaObject.type && (!options.includeTypesMap[metaObject.type])) {\n                    continue;\n                }\n\n                // Mask loading of object ids\n\n                if (options.includeIdsMap && metaObject.id && (!options.includeIdsMap[metaObject.id])) {\n                    continue;\n                }\n\n                // Get initial property values for object types\n\n                const props = options.objectDefaults ? options.objectDefaults[metaObject.type] || options.objectDefaults[\"DEFAULT\"] : null;\n\n                if (props) {\n                    if (props.visible === false) {\n                        entityDefaults.visible = false;\n                    }\n                    if (props.pickable === false) {\n                        entityDefaults.pickable = false;\n                    }\n                    if (props.colorize) {\n                        meshDefaults.color = props.colorize;\n                    }\n                    if (props.opacity !== undefined && props.opacity !== null) {\n                        meshDefaults.opacity = props.opacity;\n                    }\n                    if (props.metallic !== undefined && props.metallic !== null) {\n                        meshDefaults.metallic = props.metallic;\n                    }\n                    if (props.roughness !== undefined && props.roughness !== null) {\n                        meshDefaults.roughness = props.roughness;\n                    }\n                }\n\n            } else {\n                if (options.excludeUnclassifiedObjects) {\n                    continue;\n                }\n            }\n\n            // Iterate each entity's meshes\n\n            for (let meshIndex = firstMeshIndex; meshIndex <= lastMeshIndex; meshIndex++) {\n\n                const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n                const geometryReuseCount = geometryReuseCounts[geometryIndex];\n                const isReusedGeometry = (geometryReuseCount > 1);\n\n                const atLastGeometry = (geometryIndex === (numGeometries - 1));\n\n                const textureSetIndex = eachMeshTextureSet[meshIndex];\n\n                const textureSetId = (textureSetIndex >= 0) ? `${modelPartId}-textureSet-${textureSetIndex}` : null;\n\n                const meshColor = decompressColor$1(eachMeshMaterialAttributes.subarray((meshIndex * 6), (meshIndex * 6) + 3));\n                const meshOpacity = eachMeshMaterialAttributes[(meshIndex * 6) + 3] / 255.0;\n                const meshMetallic = eachMeshMaterialAttributes[(meshIndex * 6) + 4] / 255.0;\n                const meshRoughness = eachMeshMaterialAttributes[(meshIndex * 6) + 5] / 255.0;\n\n                const meshId = manifestCtx.getNextId();\n\n                if (isReusedGeometry) {\n\n                    // Create mesh for multi-use geometry - create (or reuse) geometry, create mesh using that geometry\n\n                    const meshMatrixIndex = eachMeshMatricesPortion[meshIndex];\n                    const meshMatrix = matrices.slice(meshMatrixIndex, meshMatrixIndex + 16);\n\n                    const geometryId = `${modelPartId}-geometry.${tileIndex}.${geometryIndex}`; // These IDs are local to the SceneModel\n\n                    let geometryArrays = geometryArraysCache[geometryId];\n\n                    if (!geometryArrays) {\n                        geometryArrays = {\n                            batchThisMesh: (!options.reuseGeometries)\n                        };\n                        const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n                        let geometryValid = false;\n                        switch (primitiveType) {\n                            case 0:\n                                geometryArrays.primitiveName = \"solid\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 1:\n                                geometryArrays.primitiveName = \"surface\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 2:\n                                geometryArrays.primitiveName = \"points\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryColors = colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0);\n                                break;\n                            case 3:\n                                geometryArrays.primitiveName = \"lines\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 4:\n                                geometryArrays.primitiveName = \"lines\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = lineStripToLines$1(\n                                    geometryArrays.geometryPositions,\n                                    indices.subarray(eachGeometryIndicesPortion [geometryIndex],\n                                        atLastGeometry\n                                            ? indices.length\n                                            : eachGeometryIndicesPortion [geometryIndex + 1]));\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            default:\n                                continue;\n                        }\n\n                        if (!geometryValid) {\n                            geometryArrays = null;\n                        }\n\n                        if (geometryArrays) {\n                            if (geometryArrays.geometryPositions.length > 1000) ;\n                            if (geometryArrays.batchThisMesh) {\n                                geometryArrays.decompressedPositions = new Float32Array(geometryArrays.geometryPositions.length);\n                                geometryArrays.transformedAndRecompressedPositions = new Uint16Array(geometryArrays.geometryPositions.length);\n                                const geometryPositions = geometryArrays.geometryPositions;\n                                const decompressedPositions = geometryArrays.decompressedPositions;\n                                for (let i = 0, len = geometryPositions.length; i < len; i += 3) {\n                                    decompressedPositions[i + 0] = geometryPositions[i + 0] * reusedGeometriesDecodeMatrix[0] + reusedGeometriesDecodeMatrix[12];\n                                    decompressedPositions[i + 1] = geometryPositions[i + 1] * reusedGeometriesDecodeMatrix[5] + reusedGeometriesDecodeMatrix[13];\n                                    decompressedPositions[i + 2] = geometryPositions[i + 2] * reusedGeometriesDecodeMatrix[10] + reusedGeometriesDecodeMatrix[14];\n                                }\n                                geometryArrays.geometryPositions = null;\n                                geometryArraysCache[geometryId] = geometryArrays;\n                            }\n                        }\n                    }\n\n                    if (geometryArrays) {\n\n                        if (geometryArrays.batchThisMesh) {\n\n                            const decompressedPositions = geometryArrays.decompressedPositions;\n                            const transformedAndRecompressedPositions = geometryArrays.transformedAndRecompressedPositions;\n\n                            for (let i = 0, len = decompressedPositions.length; i < len; i += 3) {\n                                tempVec4a$1[0] = decompressedPositions[i + 0];\n                                tempVec4a$1[1] = decompressedPositions[i + 1];\n                                tempVec4a$1[2] = decompressedPositions[i + 2];\n                                tempVec4a$1[3] = 1;\n                                math.transformVec4(meshMatrix, tempVec4a$1, tempVec4b$1);\n                                geometryCompressionUtils.compressPosition(tempVec4b$1, rtcAABB, tempVec4a$1);\n                                transformedAndRecompressedPositions[i + 0] = tempVec4a$1[0];\n                                transformedAndRecompressedPositions[i + 1] = tempVec4a$1[1];\n                                transformedAndRecompressedPositions[i + 2] = tempVec4a$1[2];\n                            }\n\n                            sceneModel.createMesh(utils.apply(meshDefaults, {\n                                id: meshId,\n                                textureSetId,\n                                origin: tileCenter,\n                                primitive: geometryArrays.primitiveName,\n                                positionsCompressed: transformedAndRecompressedPositions,\n                                normalsCompressed: geometryArrays.geometryNormals,\n                                uv: geometryArrays.geometryUVs,\n                                colorsCompressed: geometryArrays.geometryColors,\n                                indices: geometryArrays.geometryIndices,\n                                edgeIndices: geometryArrays.geometryEdgeIndices,\n                                positionsDecodeMatrix: tileDecodeMatrix,\n                                color: meshColor,\n                                metallic: meshMetallic,\n                                roughness: meshRoughness,\n                                opacity: meshOpacity\n                            }));\n\n                            meshIds.push(meshId);\n\n                        } else {\n\n                            if (!geometryCreatedInTile[geometryId]) {\n\n                                sceneModel.createGeometry({\n                                    id: geometryId,\n                                    primitive: geometryArrays.primitiveName,\n                                    positionsCompressed: geometryArrays.geometryPositions,\n                                    normalsCompressed: geometryArrays.geometryNormals,\n                                    uv: geometryArrays.geometryUVs,\n                                    colorsCompressed: geometryArrays.geometryColors,\n                                    indices: geometryArrays.geometryIndices,\n                                    edgeIndices: geometryArrays.geometryEdgeIndices,\n                                    positionsDecodeMatrix: reusedGeometriesDecodeMatrix\n                                });\n\n                                geometryCreatedInTile[geometryId] = true;\n                            }\n\n                            sceneModel.createMesh(utils.apply(meshDefaults, {\n                                id: meshId,\n                                geometryId,\n                                textureSetId,\n                                matrix: meshMatrix,\n                                color: meshColor,\n                                metallic: meshMetallic,\n                                roughness: meshRoughness,\n                                opacity: meshOpacity,\n                                origin: tileCenter\n                            }));\n\n                            meshIds.push(meshId);\n                        }\n                    }\n\n                } else { // Do not reuse geometry\n\n                    const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n\n                    let primitiveName;\n                    let geometryPositions;\n                    let geometryNormals;\n                    let geometryUVs;\n                    let geometryColors;\n                    let geometryIndices;\n                    let geometryEdgeIndices;\n                    let geometryValid = false;\n\n                    switch (primitiveType) {\n                        case 0:\n                            primitiveName = \"solid\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 1:\n                            primitiveName = \"surface\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 2:\n                            primitiveName = \"points\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryColors = colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0);\n                            break;\n                        case 3:\n                            primitiveName = \"lines\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 4:\n                            primitiveName = \"lines\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryIndices = lineStripToLines$1(\n                                geometryPositions,\n                                indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry\n                                    ? indices.length\n                                    : eachGeometryIndicesPortion [geometryIndex + 1]));\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        default:\n                            continue;\n                    }\n\n                    if (geometryValid) {\n\n                        sceneModel.createMesh(utils.apply(meshDefaults, {\n                            id: meshId,\n                            textureSetId,\n                            origin: tileCenter,\n                            primitive: primitiveName,\n                            positionsCompressed: geometryPositions,\n                            normalsCompressed: geometryNormals,\n                            uv: geometryUVs && geometryUVs.length > 0 ? geometryUVs : null,\n                            colorsCompressed: geometryColors,\n                            indices: geometryIndices,\n                            edgeIndices: geometryEdgeIndices,\n                            positionsDecodeMatrix: tileDecodeMatrix,\n                            color: meshColor,\n                            metallic: meshMetallic,\n                            roughness: meshRoughness,\n                            opacity: meshOpacity\n                        }));\n\n                        meshIds.push(meshId);\n                    }\n                }\n            }\n\n            if (meshIds.length > 0) {\n\n                sceneModel.createEntity(utils.apply(entityDefaults, {\n                    id: entityId,\n                    isObject: true,\n                    meshIds: meshIds\n                }));\n            }\n        }\n    }\n}\n\nfunction lineStripToLines$1(positions, indices) {\n    const linesIndices = [];\n    if (indices.length > 1) {\n        for (let i = 0, len = indices.length - 1; i < len; i++) {\n            linesIndices.push(indices[i]);\n            linesIndices.push(indices[i + 1]);\n        }\n    } else if (positions.length > 1) {\n        for (let i = 0, len = (positions.length / 3) - 1; i < len; i++) {\n            linesIndices.push(i);\n            linesIndices.push(i + 1);\n        }\n    }\n    return linesIndices;\n}\n\n/** @private */\n// V11 uses a single uncompressed Uint8Array buffer to store arrays of different types.\n// To efficiently create typed arrays from this buffer,\n// each typed array's source data needs to be aligned with its element byte size.\n// This sometimes requires padding subarrays inside the single Uint8Array, so the byteOffset needs to be stored alongside element count.\n// It is a different encoding than used in earlier versions, and requires different approach to parsing elements.\nconst ParserV11 = {\n    version: 11,\n    parseArrayBuffer: function (viewer, options, arrayBuffer, sceneModel, metaModel, manifestCtx) {\n        const inflatedData = decodeData$1(arrayBuffer);\n        load$1(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\n/*\n Parser for .XKT Format V11\n*/\n\nlet pako = window.pako || p;\nif (!pako.inflate) {  // See https://github.com/nodeca/pako/issues/97\n    pako = pako.default;\n}\n\nconst tempVec4a = math.vec4();\nconst tempVec4b = math.vec4();\n\nconst NUM_TEXTURE_ATTRIBUTES = 9;\n\nfunction decodeData(arrayBuffer) {\n    const requiresSwapFromLittleEndian = (function() {\n        const buffer = new ArrayBuffer(2);\n        new Uint16Array(buffer)[0] = 1;\n        return new Uint8Array(buffer)[0] !== 1;\n    })();\n\n    const nextArray = (function() {\n        let i = 0;\n        const dataView = new DataView(arrayBuffer);\n        return function(type) {\n            const idx = 1 + 2 * i++; // `1' for the version nr\n            const byteOffset = dataView.getUint32(idx       * 4, true);\n            const byteLength = dataView.getUint32((idx + 1) * 4, true);\n\n            const BPE = type.BYTES_PER_ELEMENT;\n            if (requiresSwapFromLittleEndian && (BPE > 1)) {\n                const subarray = new Uint8Array(arrayBuffer, byteOffset, byteLength);\n                const swaps = BPE / 2;\n                const cnt = subarray.length / BPE;\n                for (let b = 0; b < cnt; b++) {\n                    const offset = b * BPE;\n                    for (let j = 0; j < swaps; j++) {\n                        const i1 = offset + j;\n                        const i2 = offset - j + BPE - 1;\n                        const tmp = subarray[i1];\n                        subarray[i1] = subarray[i2];\n                        subarray[i2] = tmp;\n                    }\n                }\n            }\n\n            return new type(arrayBuffer, byteOffset, byteLength / BPE);\n        };\n    })();\n\n    const nextObject = (function() {\n        const decoder = new TextDecoder();\n        return () => JSON.parse(decoder.decode(nextArray(Uint8Array)));\n    })();\n\n    return {\n        metadata:                       nextObject(),\n        textureData:                    nextArray(Uint8Array),  // <<----------------------------- ??? ZIPPing to blame?\n        eachTextureDataPortion:         nextArray(Uint32Array),\n        eachTextureAttributes:          nextArray(Uint16Array),\n        positions:                      nextArray(Uint16Array),\n        normals:                        nextArray(Int8Array),\n        colors:                         nextArray(Uint8Array),\n        uvs:                            nextArray(Float32Array),\n        indices:                        nextArray(Uint32Array),\n        edgeIndices:                    nextArray(Uint32Array),\n        eachTextureSetTextures:         nextArray(Int32Array),\n        matrices:                       nextArray(Float32Array),\n        reusedGeometriesDecodeMatrix:   nextArray(Float32Array),\n        eachGeometryPrimitiveType:      nextArray(Uint8Array),\n        eachGeometryAxisLabel:          nextObject(),\n        eachGeometryPositionsPortion:   nextArray(Uint32Array),\n        eachGeometryNormalsPortion:     nextArray(Uint32Array),\n        eachGeometryColorsPortion:      nextArray(Uint32Array),\n        eachGeometryUVsPortion:         nextArray(Uint32Array),\n        eachGeometryIndicesPortion:     nextArray(Uint32Array),\n        eachGeometryEdgeIndicesPortion: nextArray(Uint32Array),\n        eachMeshGeometriesPortion:      nextArray(Uint32Array),\n        eachMeshMatricesPortion:        nextArray(Uint32Array),\n        eachMeshTextureSet:             nextArray(Int32Array), // Can be -1\n        eachMeshMaterialAttributes:     nextArray(Uint8Array),\n        eachEntityId:                   nextObject(),\n        eachEntityMeshesPortion:        nextArray(Uint32Array),\n        eachTileAABB:                   nextArray(Float64Array),\n        eachTileEntitiesPortion:        nextArray(Uint32Array),\n    };\n}\n\nfunction extract(elements) {\n\n    let i = 0;\n\n    return {\n        metadata: elements[i++],\n        textureData: elements[i++],\n        eachTextureDataPortion: elements[i++],\n        eachTextureAttributes: elements[i++],\n        positions: elements[i++],\n        normals: elements[i++],\n        colors: elements[i++],\n        uvs: elements[i++],\n        indices: elements[i++],\n        edgeIndices: elements[i++],\n        eachTextureSetTextures: elements[i++],\n        matrices: elements[i++],\n        reusedGeometriesDecodeMatrix: elements[i++],\n        eachGeometryPrimitiveType: elements[i++],\n        eachGeometryAxisLabel: elements[i++],\n        eachGeometryPositionsPortion: elements[i++],\n        eachGeometryNormalsPortion: elements[i++],\n        eachGeometryColorsPortion: elements[i++],\n        eachGeometryUVsPortion: elements[i++],\n        eachGeometryIndicesPortion: elements[i++],\n        eachGeometryEdgeIndicesPortion: elements[i++],\n        eachMeshGeometriesPortion: elements[i++],\n        eachMeshMatricesPortion: elements[i++],\n        eachMeshTextureSet: elements[i++],\n        eachMeshMaterialAttributes: elements[i++],\n        eachEntityId: elements[i++],\n        eachEntityMeshesPortion: elements[i++],\n        eachTileAABB: elements[i++],\n        eachTileEntitiesPortion: elements[i++],\n    };\n}\n\nfunction inflate(deflatedData) {\n\n    function inflate(array, options) {\n        return (array.length === 0) ? [] : pako.inflate(array, options).buffer;\n    }\n\n    return {\n        metadata: JSON.parse(pako.inflate(deflatedData.metadata, {to: 'string'})),\n        textureData: new Uint8Array(inflate(deflatedData.textureData)),  // <<----------------------------- ??? ZIPPing to blame?\n        eachTextureDataPortion: new Uint32Array(inflate(deflatedData.eachTextureDataPortion)),\n        eachTextureAttributes: new Uint16Array(inflate(deflatedData.eachTextureAttributes)),\n        positions: new Uint16Array(inflate(deflatedData.positions)),\n        normals: new Int8Array(inflate(deflatedData.normals)),\n        colors: new Uint8Array(inflate(deflatedData.colors)),\n        uvs: new Float32Array(inflate(deflatedData.uvs)),\n        indices: new Uint32Array(inflate(deflatedData.indices)),\n        edgeIndices: new Uint32Array(inflate(deflatedData.edgeIndices)),\n        eachTextureSetTextures: new Int32Array(inflate(deflatedData.eachTextureSetTextures)),\n        matrices: new Float32Array(inflate(deflatedData.matrices)),\n        reusedGeometriesDecodeMatrix: new Float32Array(inflate(deflatedData.reusedGeometriesDecodeMatrix)),\n        eachGeometryPrimitiveType: new Uint8Array(inflate(deflatedData.eachGeometryPrimitiveType)),\n        eachGeometryAxisLabel: JSON.parse(pako.inflate(deflatedData.eachGeometryAxisLabel, {to: 'string'})),\n        eachGeometryPositionsPortion: new Uint32Array(inflate(deflatedData.eachGeometryPositionsPortion)),\n        eachGeometryNormalsPortion: new Uint32Array(inflate(deflatedData.eachGeometryNormalsPortion)),\n        eachGeometryColorsPortion: new Uint32Array(inflate(deflatedData.eachGeometryColorsPortion)),\n        eachGeometryUVsPortion: new Uint32Array(inflate(deflatedData.eachGeometryUVsPortion)),\n        eachGeometryIndicesPortion: new Uint32Array(inflate(deflatedData.eachGeometryIndicesPortion)),\n        eachGeometryEdgeIndicesPortion: new Uint32Array(inflate(deflatedData.eachGeometryEdgeIndicesPortion)),\n        eachMeshGeometriesPortion: new Uint32Array(inflate(deflatedData.eachMeshGeometriesPortion)),\n        eachMeshMatricesPortion: new Uint32Array(inflate(deflatedData.eachMeshMatricesPortion)),\n        eachMeshTextureSet: new Int32Array(inflate(deflatedData.eachMeshTextureSet)), // Can be -1\n        eachMeshMaterialAttributes: new Uint8Array(inflate(deflatedData.eachMeshMaterialAttributes)),\n        eachEntityId: JSON.parse(pako.inflate(deflatedData.eachEntityId, {to: 'string'})),\n        eachEntityMeshesPortion: new Uint32Array(inflate(deflatedData.eachEntityMeshesPortion)),\n        eachTileAABB: new Float64Array(inflate(deflatedData.eachTileAABB)),\n        eachTileEntitiesPortion: new Uint32Array(inflate(deflatedData.eachTileEntitiesPortion)),\n    };\n}\n\nconst decompressColor = (function () {\n    const floatColor = new Float32Array(3);\n    return function (intColor) {\n        floatColor[0] = intColor[0] / 255.0;\n        floatColor[1] = intColor[1] / 255.0;\n        floatColor[2] = intColor[2] / 255.0;\n        return floatColor;\n    };\n})();\n\n((function () {\n    const canvas = document.createElement('canvas');\n    const context = canvas.getContext('2d');\n    return function (imagedata) {\n        canvas.width = imagedata.width;\n        canvas.height = imagedata.height;\n        context.putImageData(imagedata, 0, 0);\n        return canvas.toDataURL();\n    };\n}))();\n\nfunction load(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx) {\n\n    const modelPartId = manifestCtx.getNextId();\n\n    const metadata = inflatedData.metadata;\n    const textureData = inflatedData.textureData;\n    const eachTextureDataPortion = inflatedData.eachTextureDataPortion;\n    const eachTextureAttributes = inflatedData.eachTextureAttributes;\n    const positions = inflatedData.positions;\n    const normals = inflatedData.normals;\n    const colors = inflatedData.colors;\n    const uvs = inflatedData.uvs;\n    const indices = inflatedData.indices;\n    const edgeIndices = inflatedData.edgeIndices;\n    const eachTextureSetTextures = inflatedData.eachTextureSetTextures;\n    const matrices = inflatedData.matrices;\n    const reusedGeometriesDecodeMatrix = inflatedData.reusedGeometriesDecodeMatrix;\n    const eachGeometryPrimitiveType = inflatedData.eachGeometryPrimitiveType;\n    const eachGeometryAxisLabel = inflatedData.eachGeometryAxisLabel;\n    const eachGeometryPositionsPortion = inflatedData.eachGeometryPositionsPortion;\n    const eachGeometryNormalsPortion = inflatedData.eachGeometryNormalsPortion;\n    const eachGeometryColorsPortion = inflatedData.eachGeometryColorsPortion;\n    const eachGeometryUVsPortion = inflatedData.eachGeometryUVsPortion;\n    const eachGeometryIndicesPortion = inflatedData.eachGeometryIndicesPortion;\n    const eachGeometryEdgeIndicesPortion = inflatedData.eachGeometryEdgeIndicesPortion;\n    const eachMeshGeometriesPortion = inflatedData.eachMeshGeometriesPortion;\n    const eachMeshMatricesPortion = inflatedData.eachMeshMatricesPortion;\n    const eachMeshTextureSet = inflatedData.eachMeshTextureSet;\n    const eachMeshMaterialAttributes = inflatedData.eachMeshMaterialAttributes;\n    const eachEntityId = inflatedData.eachEntityId;\n    const eachEntityMeshesPortion = inflatedData.eachEntityMeshesPortion;\n    const eachTileAABB = inflatedData.eachTileAABB;\n    const eachTileEntitiesPortion = inflatedData.eachTileEntitiesPortion;\n\n    const numTextures = eachTextureDataPortion.length;\n    const numTextureSets = eachTextureSetTextures.length / 5;\n    const numGeometries = eachGeometryPositionsPortion.length;\n    const numMeshes = eachMeshGeometriesPortion.length;\n    const numEntities = eachEntityMeshesPortion.length;\n    const numTiles = eachTileEntitiesPortion.length;\n\n    if (metaModel) {\n        metaModel.loadData(metadata, {\n            includeTypes: options.includeTypes,\n            excludeTypes: options.excludeTypes,\n            globalizeObjectIds: options.globalizeObjectIds\n        }); // Can be empty\n    }\n\n    // Create textures\n\n    for (let textureIndex = 0; textureIndex < numTextures; textureIndex++) {\n        const atLastTexture = (textureIndex === (numTextures - 1));\n        const textureDataPortionStart = eachTextureDataPortion[textureIndex];\n        const textureDataPortionEnd = atLastTexture ? textureData.length : (eachTextureDataPortion[textureIndex + 1]);\n\n        const textureDataPortionSize = textureDataPortionEnd - textureDataPortionStart;\n        const textureDataPortionExists = (textureDataPortionSize > 0);\n\n        const textureAttrBaseIdx = (textureIndex * NUM_TEXTURE_ATTRIBUTES);\n\n        const compressed = (eachTextureAttributes[textureAttrBaseIdx + 0] === 1);\n        const mediaType = eachTextureAttributes[textureAttrBaseIdx + 1];\n        eachTextureAttributes[textureAttrBaseIdx + 2];\n        eachTextureAttributes[textureAttrBaseIdx + 3];\n        const minFilter = eachTextureAttributes[textureAttrBaseIdx + 4];\n        const magFilter = eachTextureAttributes[textureAttrBaseIdx + 5]; // LinearFilter | NearestFilter\n        const wrapS = eachTextureAttributes[textureAttrBaseIdx + 6]; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n        const wrapT = eachTextureAttributes[textureAttrBaseIdx + 7]; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n        const wrapR = eachTextureAttributes[textureAttrBaseIdx + 8]; // ClampToEdgeWrapping | MirroredRepeatWrapping | RepeatWrapping\n\n        if (textureDataPortionExists) {\n\n            const imageDataSubarray = new Uint8Array(textureData.subarray(textureDataPortionStart, textureDataPortionEnd));\n            const arrayBuffer = imageDataSubarray.buffer;\n            const textureId = `${modelPartId}-texture-${textureIndex}`;\n\n            if (compressed) {\n\n                sceneModel.createTexture({\n                    id: textureId,\n                    buffers: [arrayBuffer],\n                    minFilter,\n                    magFilter,\n                    wrapS,\n                    wrapT,\n                    wrapR\n                });\n\n            } else {\n\n                const mimeType = mediaType === JPEGMediaType ? \"image/jpeg\" : (mediaType === PNGMediaType ? \"image/png\" : \"image/gif\");\n                const blob = new Blob([arrayBuffer], {type: mimeType});\n                const urlCreator = window.URL || window.webkitURL;\n                const imageUrl = urlCreator.createObjectURL(blob);\n                const img = document.createElement('img');\n                img.src = imageUrl;\n\n                sceneModel.createTexture({\n                    id: textureId,\n                    image: img,\n                    //mediaType,\n                    minFilter,\n                    magFilter,\n                    wrapS,\n                    wrapT,\n                    wrapR\n                });\n            }\n        }\n    }\n\n    // Create texture sets\n\n    for (let textureSetIndex = 0; textureSetIndex < numTextureSets; textureSetIndex++) {\n        const eachTextureSetTexturesIndex = textureSetIndex * 5;\n        const textureSetId = `${modelPartId}-textureSet-${textureSetIndex}`;\n        const colorTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 0];\n        const metallicRoughnessTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 1];\n        const normalsTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 2];\n        const emissiveTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 3];\n        const occlusionTextureIndex = eachTextureSetTextures[eachTextureSetTexturesIndex + 4];\n        sceneModel.createTextureSet({\n            id: textureSetId,\n            colorTextureId: colorTextureIndex >= 0 ? `${modelPartId}-texture-${colorTextureIndex}` : null,\n            normalsTextureId: normalsTextureIndex >= 0 ? `${modelPartId}-texture-${normalsTextureIndex}` : null,\n            metallicRoughnessTextureId: metallicRoughnessTextureIndex >= 0 ? `${modelPartId}-texture-${metallicRoughnessTextureIndex}` : null,\n            emissiveTextureId: emissiveTextureIndex >= 0 ? `${modelPartId}-texture-${emissiveTextureIndex}` : null,\n            occlusionTextureId: occlusionTextureIndex >= 0 ? `${modelPartId}-texture-${occlusionTextureIndex}` : null\n        });\n    }\n\n    // Count instances of each geometry\n\n    const geometryReuseCounts = new Uint32Array(numGeometries);\n\n    for (let meshIndex = 0; meshIndex < numMeshes; meshIndex++) {\n        const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n        if (geometryReuseCounts[geometryIndex] !== undefined) {\n            geometryReuseCounts[geometryIndex]++;\n        } else {\n            geometryReuseCounts[geometryIndex] = 1;\n        }\n    }\n\n    // Iterate over tiles\n\n    const tileCenter = math.vec3();\n    const rtcAABB = math.AABB3();\n\n    const geometryArraysCache = {};\n\n    for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {\n\n        const lastTileIndex = (numTiles - 1);\n\n        const atLastTile = (tileIndex === lastTileIndex);\n\n        const firstTileEntityIndex = eachTileEntitiesPortion [tileIndex];\n        const lastTileEntityIndex = atLastTile ? (numEntities - 1) : (eachTileEntitiesPortion[tileIndex + 1] - 1);\n\n        const tileAABBIndex = tileIndex * 6;\n        const tileAABB = eachTileAABB.subarray(tileAABBIndex, tileAABBIndex + 6);\n\n        math.getAABB3Center(tileAABB, tileCenter);\n\n        rtcAABB[0] = tileAABB[0] - tileCenter[0];\n        rtcAABB[1] = tileAABB[1] - tileCenter[1];\n        rtcAABB[2] = tileAABB[2] - tileCenter[2];\n        rtcAABB[3] = tileAABB[3] - tileCenter[0];\n        rtcAABB[4] = tileAABB[4] - tileCenter[1];\n        rtcAABB[5] = tileAABB[5] - tileCenter[2];\n\n        const tileDecodeMatrix = geometryCompressionUtils.createPositionsDecodeMatrix(rtcAABB);\n\n        const geometryCreatedInTile = {};\n\n        // Iterate over each tile's entities\n\n        for (let tileEntityIndex = firstTileEntityIndex; tileEntityIndex <= lastTileEntityIndex; tileEntityIndex++) {\n\n            const xktEntityId = eachEntityId[tileEntityIndex];\n\n            const entityId = options.globalizeObjectIds ? math.globalizeObjectId(sceneModel.id, xktEntityId) : xktEntityId;\n\n            const finalTileEntityIndex = (numEntities - 1);\n            const atLastTileEntity = (tileEntityIndex === finalTileEntityIndex);\n            const firstMeshIndex = eachEntityMeshesPortion [tileEntityIndex];\n            const lastMeshIndex = atLastTileEntity ? (eachMeshGeometriesPortion.length - 1) : (eachEntityMeshesPortion[tileEntityIndex + 1] - 1);\n\n            const meshIds = [];\n\n            const metaObject = viewer.metaScene.metaObjects[entityId];\n            const entityDefaults = {};\n            const meshDefaults = {};\n\n            if (metaObject) {\n\n                // Mask loading of object types\n\n                if (options.excludeTypesMap && metaObject.type && options.excludeTypesMap[metaObject.type]) {\n                    continue;\n                }\n\n                if (options.includeTypesMap && metaObject.type && (!options.includeTypesMap[metaObject.type])) {\n                    continue;\n                }\n\n                // Mask loading of object ids\n\n                if (options.includeIdsMap && metaObject.id && (!options.includeIdsMap[metaObject.id])) {\n                    continue;\n                }\n\n                // Get initial property values for object types\n\n                const props = options.objectDefaults ? options.objectDefaults[metaObject.type] || options.objectDefaults[\"DEFAULT\"] : null;\n\n                if (props) {\n                    if (props.visible === false) {\n                        entityDefaults.visible = false;\n                    }\n                    if (props.pickable === false) {\n                        entityDefaults.pickable = false;\n                    }\n                    if (props.colorize) {\n                        meshDefaults.color = props.colorize;\n                    }\n                    if (props.opacity !== undefined && props.opacity !== null) {\n                        meshDefaults.opacity = props.opacity;\n                    }\n                    if (props.metallic !== undefined && props.metallic !== null) {\n                        meshDefaults.metallic = props.metallic;\n                    }\n                    if (props.roughness !== undefined && props.roughness !== null) {\n                        meshDefaults.roughness = props.roughness;\n                    }\n                }\n\n            } else {\n                if (options.excludeUnclassifiedObjects) {\n                    continue;\n                }\n            }\n\n            // Iterate each entity's meshes\n\n            for (let meshIndex = firstMeshIndex; meshIndex <= lastMeshIndex; meshIndex++) {\n\n                const geometryIndex = eachMeshGeometriesPortion[meshIndex];\n                const geometryReuseCount = geometryReuseCounts[geometryIndex];\n                const isReusedGeometry = (geometryReuseCount > 1);\n\n                const atLastGeometry = (geometryIndex === (numGeometries - 1));\n\n                const textureSetIndex = eachMeshTextureSet[meshIndex];\n\n                const textureSetId = (textureSetIndex >= 0) ? `${modelPartId}-textureSet-${textureSetIndex}` : null;\n\n                const meshColor = decompressColor(eachMeshMaterialAttributes.subarray((meshIndex * 6), (meshIndex * 6) + 3));\n                const meshOpacity = eachMeshMaterialAttributes[(meshIndex * 6) + 3] / 255.0;\n                const meshMetallic = eachMeshMaterialAttributes[(meshIndex * 6) + 4] / 255.0;\n                const meshRoughness = eachMeshMaterialAttributes[(meshIndex * 6) + 5] / 255.0;\n\n                const meshId = manifestCtx.getNextId();\n\n                if (isReusedGeometry) {\n\n                    // Create mesh for multi-use geometry - create (or reuse) geometry, create mesh using that geometry\n\n                    const meshMatrixIndex = eachMeshMatricesPortion[meshIndex];\n                    const meshMatrix = matrices.slice(meshMatrixIndex, meshMatrixIndex + 16);\n\n                    const geometryId = `${modelPartId}-geometry.${tileIndex}.${geometryIndex}`; // These IDs are local to the SceneModel\n\n                    let geometryArrays = geometryArraysCache[geometryId];\n\n                    if (!geometryArrays) {\n                        geometryArrays = {\n                            batchThisMesh: (!options.reuseGeometries)\n                        };\n                        const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n                        const axisLabel = eachGeometryAxisLabel[geometryIndex];\n                        let geometryValid = false;\n                        let ifcLabel;\n                        switch (primitiveType) {\n                            case 0:\n                                geometryArrays.primitiveName = \"solid\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 1:\n                                geometryArrays.primitiveName = \"surface\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 2:\n                                geometryArrays.primitiveName = \"points\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryColors = colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0);\n                                break;\n                            case 3:\n                                geometryArrays.primitiveName = \"lines\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 4:\n                                geometryArrays.primitiveName = \"lines\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.geometryIndices = lineStripToLines(\n                                    geometryArrays.geometryPositions,\n                                    indices.subarray(eachGeometryIndicesPortion [geometryIndex],\n                                        atLastGeometry\n                                            ? indices.length\n                                            : eachGeometryIndicesPortion [geometryIndex + 1]));\n                                geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            case 7:\n                                geometryArrays.primitiveName = \"lines\";\n                                geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                                geometryArrays.decompressedPositions = geometryCompressionUtils.decompressPositions(geometryArrays.geometryPositions, reusedGeometriesDecodeMatrix);\n                                ifcLabel = buildVectorTextGeometry({\n                                    origin: geometryArrays.decompressedPositions,\n                                    text: axisLabel,\n                                    size: 2\n                                });\n                                \n                                geometryArrays.decompressedPositions = ifcLabel.positions;\n                                geometryArrays.geometryIndices = ifcLabel.indices;\n                                geometryArrays.geometryPositions = null;\n    \n                                geometryValid = (geometryArrays.decompressedPositions.length > 0 && geometryArrays.geometryIndices.length > 0);\n                                break;\n                            default:\n                                continue;\n                        }\n\n                        if (!geometryValid) {\n                            geometryArrays = null;\n                        }\n\n                        if (geometryArrays) {\n                            if (geometryArrays.geometryPositions && geometryArrays.geometryPositions.length > 1000) ;\n                            if (geometryArrays.batchThisMesh) {\n                                if(primitiveType === 7) {\n                                    geometryArrays.transformedAndRecompressedPositions = new Uint16Array(geometryArrays.decompressedPositions.length);\n                                }\n                                else {\n                                    geometryArrays.decompressedPositions = new Float32Array(geometryArrays.geometryPositions.length);\n                                    geometryArrays.transformedAndRecompressedPositions = new Uint16Array(geometryArrays.geometryPositions.length);\n                                    const geometryPositions = geometryArrays.geometryPositions;\n                                    const decompressedPositions = geometryArrays.decompressedPositions;\n                                    for (let i = 0, len = geometryPositions.length; i < len; i += 3) {\n                                        decompressedPositions[i + 0] = geometryPositions[i + 0] * reusedGeometriesDecodeMatrix[0] + reusedGeometriesDecodeMatrix[12];\n                                        decompressedPositions[i + 1] = geometryPositions[i + 1] * reusedGeometriesDecodeMatrix[5] + reusedGeometriesDecodeMatrix[13];\n                                        decompressedPositions[i + 2] = geometryPositions[i + 2] * reusedGeometriesDecodeMatrix[10] + reusedGeometriesDecodeMatrix[14];\n                                    }\n                                    geometryArrays.geometryPositions = null;\n                                }\n                                \n                                geometryArraysCache[geometryId] = geometryArrays;\n                            }\n                        }\n                    }\n\n                    if (geometryArrays) {\n\n                        if (geometryArrays.batchThisMesh) {\n\n                            const decompressedPositions = geometryArrays.decompressedPositions;\n                            const transformedAndRecompressedPositions = geometryArrays.transformedAndRecompressedPositions;\n\n                            for (let i = 0, len = decompressedPositions.length; i < len; i += 3) {\n                                tempVec4a[0] = decompressedPositions[i + 0];\n                                tempVec4a[1] = decompressedPositions[i + 1];\n                                tempVec4a[2] = decompressedPositions[i + 2];\n                                tempVec4a[3] = 1;\n                                math.transformVec4(meshMatrix, tempVec4a, tempVec4b);\n                                geometryCompressionUtils.compressPosition(tempVec4b, rtcAABB, tempVec4a);\n                                transformedAndRecompressedPositions[i + 0] = tempVec4a[0];\n                                transformedAndRecompressedPositions[i + 1] = tempVec4a[1];\n                                transformedAndRecompressedPositions[i + 2] = tempVec4a[2];\n                            }\n\n                            sceneModel.createMesh(utils.apply(meshDefaults, {\n                                id: meshId,\n                                textureSetId,\n                                origin: tileCenter,\n                                primitive: geometryArrays.primitiveName,\n                                positionsCompressed: transformedAndRecompressedPositions,\n                                normalsCompressed: geometryArrays.geometryNormals,\n                                uv: geometryArrays.geometryUVs,\n                                colorsCompressed: geometryArrays.geometryColors,\n                                indices: geometryArrays.geometryIndices,\n                                edgeIndices: geometryArrays.geometryEdgeIndices,\n                                positionsDecodeMatrix: tileDecodeMatrix,\n                                color: meshColor,\n                                metallic: meshMetallic,\n                                roughness: meshRoughness,\n                                opacity: meshOpacity\n                            }));\n\n                            meshIds.push(meshId);\n\n                        } else {\n\n                            if (!geometryCreatedInTile[geometryId]) {\n                                let geometryCfg = {\n                                    id: geometryId,\n                                    primitive: geometryArrays.primitiveName,\n                                    normalsCompressed: geometryArrays.geometryNormals,\n                                    uv: geometryArrays.geometryUVs,\n                                    colorsCompressed: geometryArrays.geometryColors,\n                                    indices: geometryArrays.geometryIndices,\n                                    edgeIndices: geometryArrays.geometryEdgeIndices\n                                };\n\n                                if(geometryArrays.geometryPositions){\n                                    geometryCfg = {\n                                        ...geometryCfg,\n                                        positionsCompressed: geometryArrays.geometryPositions,\n                                        positionsDecodeMatrix: reusedGeometriesDecodeMatrix\n                                    };\n                                }\n                                else {\n                                    geometryCfg = {\n                                        ...geometryCfg,\n                                        positions: geometryArrays.decompressedPositions,\n                                    };\n                                }\n\n                                sceneModel.createGeometry(geometryCfg);\n\n                                geometryCreatedInTile[geometryId] = true;\n                            }\n\n                            sceneModel.createMesh(utils.apply(meshDefaults, {\n                                id: meshId,\n                                geometryId,\n                                textureSetId,\n                                matrix: meshMatrix,\n                                color: meshColor,\n                                metallic: meshMetallic,\n                                roughness: meshRoughness,\n                                opacity: meshOpacity,\n                                origin: tileCenter\n                            }));\n\n                            meshIds.push(meshId);\n                        }\n                    }\n\n                } else { // Do not reuse geometry\n\n                    const primitiveType = eachGeometryPrimitiveType[geometryIndex];\n                    const axisLabel = eachGeometryAxisLabel[geometryIndex];\n\n                    let primitiveName;\n                    let geometryPositions;\n                    let geometryNormals;\n                    let geometryUVs;\n                    let geometryColors;\n                    let geometryIndices;\n                    let geometryEdgeIndices;\n                    let geometryValid = false;\n                    let ifcLabel;\n\n                    switch (primitiveType) {\n                        case 0:\n                            primitiveName = \"solid\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 1:\n                            primitiveName = \"surface\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);\n                            geometryUVs = uvs.subarray(eachGeometryUVsPortion [geometryIndex], atLastGeometry ? uvs.length : eachGeometryUVsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 2:\n                            primitiveName = \"points\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryColors = colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0);\n                            break;\n                        case 3:\n                            primitiveName = \"lines\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        case 4:\n                            primitiveName = \"lines\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryIndices = lineStripToLines(\n                                geometryPositions,\n                                indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry\n                                    ? indices.length\n                                    : eachGeometryIndicesPortion [geometryIndex + 1]));\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                            //Ifc Labels\n                        case 7:\n                            primitiveName = \"lines\";\n                            geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);\n                            geometryPositions = geometryCompressionUtils.decompressPositions(geometryPositions, tileDecodeMatrix);\n                            ifcLabel = buildVectorTextGeometry({\n                                origin: geometryPositions,\n                                text: axisLabel,\n                                size: 2\n                            });\n                            \n                            geometryPositions = ifcLabel.positions;\n                            geometryIndices = ifcLabel.indices;\n\n                            geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);\n                            break;\n                        default:\n                            continue;\n                    }\n\n                    if (geometryValid) {\n\n                        let meshCfg = utils.apply(meshDefaults, {\n                            id: meshId,\n                            textureSetId,\n                            origin: tileCenter,\n                            primitive: primitiveName,\n                            normalsCompressed: geometryNormals,\n                            uv: geometryUVs && geometryUVs.length > 0 ? geometryUVs : null,\n                            colorsCompressed: geometryColors,\n                            indices: geometryIndices,\n                            edgeIndices: geometryEdgeIndices,\n                            color: meshColor,\n                            metallic: meshMetallic,\n                            roughness: meshRoughness,\n                            opacity: meshOpacity\n                        });\n\n                        if(primitiveType !== 7) {\n                            meshCfg = {\n                                ...meshCfg,\n                                positionsCompressed: geometryPositions,\n                                positionsDecodeMatrix: tileDecodeMatrix\n                            };\n                        }\n                        else {\n                            meshCfg = {\n                                ...meshCfg,\n                                positions: geometryPositions\n                            };\n                        }\n\n                        sceneModel.createMesh(meshCfg);\n\n                        meshIds.push(meshId);\n                    }\n                }\n            }\n\n            if (meshIds.length > 0) {\n\n                sceneModel.createEntity(utils.apply(entityDefaults, {\n                    id: entityId,\n                    isObject: true,\n                    meshIds: meshIds\n                }));\n            }\n        }\n    }\n}\n\nfunction lineStripToLines(positions, indices) {\n    const linesIndices = [];\n    if (indices.length > 1) {\n        for (let i = 0, len = indices.length - 1; i < len; i++) {\n            linesIndices.push(indices[i]);\n            linesIndices.push(indices[i + 1]);\n        }\n    } else if (positions.length > 1) {\n        for (let i = 0, len = (positions.length / 3) - 1; i < len; i++) {\n            linesIndices.push(i);\n            linesIndices.push(i + 1);\n        }\n    }\n    return linesIndices;\n}\n\n/** @private */\n// V11 uses a single uncompressed Uint8Array buffer to store arrays of different types.\n// To efficiently create typed arrays from this buffer,\n// each typed array's source data needs to be aligned with its element byte size.\n// This sometimes requires padding subarrays inside the single Uint8Array, so the byteOffset needs to be stored alongside element count.\n// It is a different encoding than used in earlier versions, and requires different approach to parsing elements.\nconst ParserV12 = {\n    version: 12,\n    parseArrayBuffer: function (viewer, options, arrayBuffer, sceneModel, metaModel, manifestCtx) {\n        const inflatedData = decodeData(arrayBuffer);\n        load(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    },\n    parse: function (viewer, options, elements, sceneModel, metaModel, manifestCtx) {\n        const deflatedData = extract(elements);\n        const inflatedData = inflate(deflatedData);\n        load(viewer, options, inflatedData, sceneModel, metaModel, manifestCtx);\n    }\n};\n\nconst parsers = {};\n\nparsers[ParserV1.version] = ParserV1;\nparsers[ParserV2.version] = ParserV2;\nparsers[ParserV3.version] = ParserV3;\nparsers[ParserV4.version] = ParserV4;\nparsers[ParserV5.version] = ParserV5;\nparsers[ParserV6.version] = ParserV6;\nparsers[ParserV7.version] = ParserV7;\nparsers[ParserV8.version] = ParserV8;\nparsers[ParserV9.version] = ParserV9;\nparsers[ParserV10.version] = ParserV10;\nparsers[ParserV11.version] = ParserV11;\nparsers[ParserV12.version] = ParserV12;\n\n/**\n * {@link Viewer} plugin that loads models from xeokit's optimized *````.XKT````* format.\n *\n * <a href=\"https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_XKT_OTCConferenceCenter\"><img src=\"http://xeokit.io/img/docs/XKTLoaderPlugin/XKTLoaderPlugin.png\"></a>\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_XKT_OTCConferenceCenter)]\n *\n * # Overview\n *\n * * XKTLoaderPlugin is the most efficient way to load high-detail models into xeokit.\n * * An *````.XKT````* file is a single BLOB containing a model, compressed using geometry quantization\n * and [pako](https://nodeca.github.io/pako/).\n * * Supports double-precision coordinates.\n * * Supports compressed textures.\n * * Set the position, scale and rotation of each model as you load it.\n * * Filter which IFC types get loaded.\n * * Configure initial default appearances for IFC types.\n * * Set a custom data source for *````.XKT````* and IFC metadata files.\n * * Option to load multiple copies of the same model, without object ID clashes.\n *\n * # Creating *````.XKT````* Files and Metadata\n *\n * We have several sways to convert your files into XKT. See these tutorials for more info:\n *\n * * [Converting Models to XKT with convert2xkt](https://www.notion.so/xeokit/Converting-Models-to-XKT-with-convert2xkt-fa567843313f4db8a7d6535e76da9380) - how to convert various file formats (glTF, IFC, CityJSON, LAS/LAZ...) to XKT using our nodejs-based converter.\n * * [Converting IFC Models to XKT using 3rd-Party Open Source Tools](https://www.notion.so/xeokit/Converting-IFC-Models-to-XKT-using-3rd-Party-Open-Source-Tools-c373e48bc4094ff5b6e5c5700ff580ee) - how to convert IFC files to XKT using 3rd-party open source CLI tools.\n *\n * # Scene representation\n *\n * When loading a model, XKTLoaderPlugin creates an {@link Entity} that represents the model, which\n * will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id}\n * in {@link Scene#models}. The XKTLoaderPlugin also creates an {@link Entity} for each object within the\n * model. Those Entities will have {@link Entity#isObject} set ````true```` and will be registered\n * by {@link Entity#id} in {@link Scene#objects}.\n *\n * # Metadata\n *\n * Since XKT V8, model metadata is included in the XKT file. If the XKT file has metadata, then loading it creates\n * model metadata components within the Viewer, namely a {@link MetaModel} corresponding to the model {@link Entity},\n * and a {@link MetaObject} for each object {@link Entity}.\n *\n * Each {@link MetaObject} has a {@link MetaObject#type}, which indicates the classification of its corresponding\n * {@link Entity}. When loading metadata, we can also configure XKTLoaderPlugin with a custom lookup table of initial\n * values to set on the properties of each type of {@link Entity}. By default, XKTLoaderPlugin uses its own map of\n * default colors and visibilities for IFC element types.\n *\n * For XKT versions prior to V8, we provided the metadata to XKTLoaderPlugin as an accompanying JSON file to load. We can\n * still do that for all XKT versions, and for XKT V8+ it will override any metadata provided within the XKT file.\n *\n * # Usage\n *\n * In the example below we'll load the Schependomlaan model from a [.XKT file](https://github.com/xeokit/xeokit-sdk/tree/master/examples/models/xkt/schependomlaan).\n *\n * This will create a bunch of {@link Entity}s that represents the model and its objects, along with a {@link MetaModel} and {@link MetaObject}s\n * that hold their metadata.\n *\n * Since this model contains IFC types, the XKTLoaderPlugin will set the initial appearance of each object\n * {@link Entity} according to its IFC type in {@link XKTLoaderPlugin#objectDefaults}.\n *\n * Read more about this example in the user guide on [Viewing BIM Models Offline](https://www.notion.so/xeokit/Viewing-an-IFC-Model-with-xeokit-c373e48bc4094ff5b6e5c5700ff580ee).\n *\n * * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#BIMOffline_XKT_metadata_Schependomlaan)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // 1. Create a Viewer,\n * // 2. Arrange the camera\n * //------------------------------------------------------------------------------------------------------------------\n *\n * // 1\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * // 2\n * viewer.camera.eye = [-2.56, 8.38, 8.27];\n * viewer.camera.look = [13.44, 3.31, -14.83];\n * viewer.camera.up = [0.10, 0.98, -0.14];\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // 1. Create a XKTLoaderPlugin,\n * // 2. Load a building model and JSON IFC metadata\n * //------------------------------------------------------------------------------------------------------------------\n *\n * // 1\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * // 2\n * const model = xktLoader.load({          // Returns an Entity that represents the model\n *     id: \"myModel\",\n *     src: \"./models/xkt/Schependomlaan.xkt\",\n *     edges: true\n * });\n *\n * model.on(\"loaded\", () => {\n *\n *     //--------------------------------------------------------------------------------------------------------------\n *     // 1. Find metadata on the third storey\n *     // 2. Select all the objects in the building's third storey\n *     // 3. Fit the camera to all the objects on the third storey\n *     //--------------------------------------------------------------------------------------------------------------\n *\n *     // 1\n *     const metaModel = viewer.metaScene.metaModels[\"myModel\"];       // MetaModel with ID \"myModel\"\n *     const metaObject\n *          = viewer.metaScene.metaObjects[\"0u4wgLe6n0ABVaiXyikbkA\"];  // MetaObject with ID \"0u4wgLe6n0ABVaiXyikbkA\"\n *\n *     const name = metaObject.name;                                   // \"01 eerste verdieping\"\n *     const type = metaObject.type;                                   // \"IfcBuildingStorey\"\n *     const parent = metaObject.parent;                               // MetaObject with type \"IfcBuilding\"\n *     const children = metaObject.children;                           // Array of child MetaObjects\n *     const objectId = metaObject.id;                                 // \"0u4wgLe6n0ABVaiXyikbkA\"\n *     const objectIds = viewer.metaScene.getObjectIDsInSubtree(objectId);   // IDs of leaf sub-objects\n *     const aabb = viewer.scene.getAABB(objectIds);                   // Axis-aligned boundary of the leaf sub-objects\n *\n *     // 2\n *     viewer.scene.setObjectsSelected(objectIds, true);\n *\n *     // 3\n *     viewer.cameraFlight.flyTo(aabb);\n * });\n *\n * // Find the model Entity by ID\n * model = viewer.scene.models[\"myModel\"];\n *\n * // Destroy the model\n * model.destroy();\n * ````\n *\n * # Loading XKT files containing textures\n *\n * XKTLoaderPlugin uses a {@link KTX2TextureTranscoder} to load textures in XKT files (XKT v10+). An XKTLoaderPlugin has its own\n * default KTX2TextureTranscoder, configured to load the Basis Codec from the CDN. If we wish, we can override that with our own\n * KTX2TextureTranscoder instance that's configured to load the Codec locally.\n *\n * In the example below, we'll create a {@link Viewer} and add an XKTLoaderPlugin\n * configured with a KTX2TextureTranscoder that finds the Codec in our local file system. Then we'll use the\n * XKTLoaderPlugin to load an XKT file that contains KTX2 textures, which the plugin will transcode using\n * its KTX2TextureTranscoder.\n *\n * We'll configure our KTX2TextureTranscoder to load the Basis Codec from a local directory. If we were happy with loading the\n * Codec from our CDN (ie. our app will always have an Internet connection) then we could just leave out the\n * KTX2TextureTranscoder altogether, and let the XKTLoaderPlugin use its internal default KTX2TextureTranscoder, which is configured to\n * load the Codec from the CDN. We'll stick with loading our own Codec, in case we want to run our app without an Internet connection.\n *\n * <a href=\"https://xeokit.github.io/xeokit-sdk/examples/buildings/#xkt_vbo_textures_HousePlan\"><img src=\"https://xeokit.github.io/xeokit-sdk/assets/images/xktWithTextures.png\"></a>\n *\n * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/buildings/#xkt_vbo_textures_HousePlan)]\n *\n * ````javascript\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * viewer.camera.eye = [-2.56, 8.38, 8.27];\n * viewer.camera.look = [13.44, 3.31, -14.83];\n * viewer.camera.up = [0.10, 0.98, -0.14];\n *\n * const textureTranscoder = new KTX2TextureTranscoder({\n *     viewer,\n *     transcoderPath: \"https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/\" // <------ Path to Basis Universal transcoder\n * });\n *\n * const xktLoader = new XKTLoaderPlugin(viewer, {\n *     textureTranscoder // <<------------- Transcodes KTX2 textures in XKT files\n * });\n *\n * const sceneModel = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"./HousePlan.xkt\" // <<------ XKT file with KTX2 textures\n * });\n * ````\n *\n * # Transforming\n *\n * We have the option to rotate, scale and translate each  *````.XKT````* model as we load it.\n *\n * This lets us load multiple models, or even multiple copies of the same model, and position them apart from each other.\n *\n * In the example below, we'll scale our model to half its size, rotate it 90 degrees about its local X-axis, then\n * translate it 100 units along its X axis.\n *\n * ````javascript\n * xktLoader.load({\n *      src: \"./models/xkt/Duplex.ifc.xkt\",\n *      rotation: [90,0,0],\n *      scale: [0.5, 0.5, 0.5],\n *      position: [100, 0, 0]\n * });\n * ````\n *\n * # Including and excluding IFC types\n *\n * We can also load only those objects that have the specified IFC types.\n *\n * In the example below, we'll load only the objects that represent walls.\n *\n * ````javascript\n * const model2 = xktLoader.load({\n *     id: \"myModel2\",\n *     src: \"./models/xkt/OTCConferenceCenter.xkt\",\n *     includeTypes: [\"IfcWallStandardCase\"]\n * });\n * ````\n *\n * We can also load only those objects that **don't** have the specified IFC types.\n *\n * In the example below, we'll load only the objects that do not represent empty space.\n *\n * ````javascript\n * const model3 = xktLoader.load({\n *     id: \"myModel3\",\n *     src: \"./models/xkt/OTCConferenceCenter.xkt\",\n *     excludeTypes: [\"IfcSpace\"]\n * });\n * ````\n *\n * # Including specific elements by id\n *\n * We can also load only those objects that have the specified ids.\n *\n * In the example below, we'll load only the objects that represent a specified wall with 4 windows.\n *\n * ````javascript\n * const model4 = xktLoader.load({\n *      id: \"myModel4\",\n *      src: \"../../assets/models/xkt/v10/glTF-Embedded/Duplex_A_20110505.glTFEmbedded.xkt\",\n *      includeIds: [\"2O2Fr$t4X7Zf8NOew3FLOH\", \"1hOSvn6df7F8_7GcBWlS_W\", \"1hOSvn6df7F8_7GcBWlS4Q\", \"1hOSvn6df7F8_7GcBWlS1M\", \"1hOSvn6df7F8_7GcBWlS2V\"],\n * });\n * ````\n *\n * # Configuring initial IFC object appearances\n *\n * We can specify the custom initial appearance of loaded objects according to their IFC types.\n *\n * This is useful for things like:\n *\n * * setting the colors to our objects according to their IFC types,\n * * automatically hiding ````IfcSpace```` objects, and\n * * ensuring that ````IfcWindow```` objects are always transparent.\n * <br>\n * In the example below, we'll load a model, while configuring ````IfcSpace```` elements to be always initially invisible,\n * and ````IfcWindow```` types to be always translucent blue.\n *\n * ````javascript\n * const myObjectDefaults = {\n *\n *      IfcSpace: {\n *          visible: false\n *      },\n *      IfcWindow: {\n *          colorize: [0.337255, 0.303922, 0.870588], // Blue\n *          opacity: 0.3\n *      },\n *\n *      //...\n *\n *      DEFAULT: {\n *          colorize: [0.5, 0.5, 0.5]\n *      }\n * };\n *\n * const model4 = xktLoader.load({\n *      id: \"myModel4\",\n *      src: \"./models/xkt/Duplex.ifc.xkt\",\n *      objectDefaults: myObjectDefaults // Use our custom initial default states for object Entities\n * });\n * ````\n *\n * When we don't customize the appearance of IFC types, as just above, then IfcSpace elements tend to obscure other\n * elements, which can be confusing.\n *\n * It's often helpful to make IfcSpaces transparent and unpickable, like this:\n *\n * ````javascript\n * const xktLoader = new XKTLoaderPlugin(viewer, {\n *    objectDefaults: {\n *        IfcSpace: {\n *            pickable: false,\n *            opacity: 0.2\n *        }\n *    }\n * });\n * ````\n *\n * Alternatively, we could just make IfcSpaces invisible, which also makes them unpickable:\n *\n * ````javascript\n * const xktLoader = new XKTLoaderPlugin(viewer, {\n *    objectDefaults: {\n *        IfcSpace: {\n *            visible: false\n *        }\n *    }\n * });\n * ````\n *\n * # Configuring a custom data source\n *\n * By default, XKTLoaderPlugin will load *````.XKT````* files and metadata JSON over HTTP.\n *\n * In the example below, we'll customize the way XKTLoaderPlugin loads the files by configuring it with our own data source\n * object. For simplicity, our custom data source example also uses HTTP, using a couple of xeokit utility functions.\n *\n * ````javascript\n * import {utils} from \"xeokit-sdk.es.js\";\n *\n * class MyDataSource {\n *\n *      constructor() {\n *      }\n *\n *      // Gets metamodel JSON\n *      getMetaModel(metaModelSrc, ok, error) {\n *          console.log(\"MyDataSource#getMetaModel(\" + metaModelSrc + \", ... )\");\n *          utils.loadJSON(metaModelSrc,\n *              (json) => {\n *                  ok(json);\n *              },\n *              function (errMsg) {\n *                  error(errMsg);\n *              });\n *      }\n *\n *      // Gets the contents of the given .XKT file in an arraybuffer\n *      getXKT(src, ok, error) {\n *          console.log(\"MyDataSource#getXKT(\" + xKTSrc + \", ... )\");\n *          utils.loadArraybuffer(src,\n *              (arraybuffer) => {\n *                  ok(arraybuffer);\n *              },\n *              function (errMsg) {\n *                  error(errMsg);\n *              });\n *      }\n * }\n *\n * const xktLoader2 = new XKTLoaderPlugin(viewer, {\n *       dataSource: new MyDataSource()\n * });\n *\n * const model5 = xktLoader2.load({\n *      id: \"myModel5\",\n *      src: \"./models/xkt/Duplex.ifc.xkt\"\n * });\n * ````\n *\n * # Loading multiple copies of a model, without object ID clashes\n *\n * Sometimes we need to load two or more instances of the same model, without having clashes\n * between the IDs of the equivalent objects in the model instances.\n *\n * As shown in the example below, we do this by setting {@link XKTLoaderPlugin#globalizeObjectIds} ````true```` before we load our models.\n *\n * * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#TreeViewPlugin_Containment_MultipleModels)]\n *\n * ````javascript\n * xktLoader.globalizeObjectIds = true;\n *\n * const model = xktLoader.load({\n *      id: \"model1\",\n *      src: \"./models/xkt/Schependomlaan.xkt\"\n * });\n *\n * const model2 = xktLoader.load({\n *    id: \"model2\",\n *    src: \"./models/xkt/Schependomlaan.xkt\"\n * });\n * ````\n *\n * For each {@link Entity} loaded by these two calls, {@link Entity#id} and {@link MetaObject#id} will get prefixed by\n * the ID of their model, in order to avoid ID clashes between the two models.\n *\n * An Entity belonging to the first model will get an ID like this:\n *\n * ````\n * myModel1#0BTBFw6f90Nfh9rP1dlXrb\n * ````\n *\n * The equivalent Entity in the second model will get an ID like this:\n *\n * ````\n * myModel2#0BTBFw6f90Nfh9rP1dlXrb\n * ````\n *\n * Now, to update the visibility of both of those Entities collectively, using {@link Scene#setObjectsVisible}, we can\n * supply just the IFC product ID part to that method:\n *\n * ````javascript\n * myViewer.scene.setObjectVisibilities(\"0BTBFw6f90Nfh9rP1dlXrb\", true);\n * ````\n *\n * The method, along with {@link Scene#setObjectsXRayed}, {@link Scene#setObjectsHighlighted} etc, will internally expand\n * the given ID to refer to the instances of that Entity in both models.\n *\n * We can also, of course, reference each Entity directly, using its globalized ID:\n *\n * ````javascript\n * myViewer.scene.setObjectVisibilities(\"myModel1#0BTBFw6f90Nfh9rP1dlXrb\", true);\n *````\n *\n * We can also provide an HTTP URL to the XKT file:\n *\n * ````javascript\n * const sceneModel = xktLoader.load({\n *   src: \"https://xeokit.github.io/xeokit-sdk/assets/models/models/xkt/Schependomlaan.xkt\",\n *   id: \"myModel\",\n * });\n * ````\n *\n * # Loading a model from a manifest of XKT files\n *\n * The `ifc2gltf` tool from Creoox, which converts IFC files into glTF geometry and JSON metadata files, has the option to\n * split its output into multiple pairs of glTF and JSON files, accompanied by a JSON manifest that lists the files.\n *\n * To integrate with that option, the `convert2xkt` tool, which converts glTF geometry and JSON metadata files into XKT files,\n * also has the option to batch-convert the glTF+JSON files in the manifest, in one invocation.\n *\n * When we use this option, convert2xkt will output a bunch of XKT files, along with a JSON manifest file that lists those XKT files.\n *\n * Working down the pipeline, the XKTLoaderPlugin has the option batch-load all XKT files listed in that manifest\n * into a xeokit Viewer in one load operation, combining the XKT files into a single SceneModel and MetaModel.\n *\n * You can learn more about this conversion and loading process, with splitting, batch converting and batch loading,\n * in [this tutorial](https://www.notion.so/xeokit/Importing-Huge-IFC-Models-as-Multiple-XKT-Files-165fc022e94742cf966ee50003572259).\n *\n * To show how to use XKTLoaderPlugin to load a manifest of XKT files, let's imagine that we have a set of such XKT files. As\n * described in the tutorial, they were converted by `ifc2gltf` from an IFC file into a set of glTF+JSON files, that were\n * then converted by convert2xkt into this set of XKT files and a manifest, as shown below.\n *\n * ````bash\n * ./\n * ├── model_1.xkt\n * ├── model_2.xkt\n * ├── model_3.xkt\n * ├── model_4..xkt\n * └── model.xkt.manifest.json\n * ````\n *\n * The `model.xkt.manifest.json` XKT manifest would look something like this:\n *\n * ````json\n * {\n *   \"inputFile\": null,\n *   \"converterApplication\": \"convert2xkt\",\n *   \"converterApplicationVersion\": \"v1.1.9\",\n *   \"conversionDate\": \"10-08-2023- 02-05-01\",\n *   \"outputDir\": null,\n *   \"xktFiles\": [\n *     \"model_1.xkt\",\n *     \"model_2.xkt\",\n *     \"model_3.xkt\",\n *     \"model_4.xkt\"\n *   ]\n * }\n * ````\n *\n * Now, to load all those XKT files into a single SceneModel and MetaModel in one operation, we pass a path to the XKT\n * manifest to `XKTLoaderPlugin.load`, as shown in the example below:\n *\n * * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/buildings/#xkt_manifest_KarhumakiBridge)]\n *\n * ````javascript\n * import {\n *   Viewer,\n *   XKTLoaderPlugin,\n *   TreeViewPlugin,\n * } from \"xeokit-sdk.es.js\";\n *\n * constviewer = new Viewer({\n *   canvasId: \"myCanvas\"\n * });\n *\n * viewer.scene.camera.eye = [26.54, 29.29, 36.20,];\n * viewer.scene.camera.look = [-23.51, -8.26, -21.65,];\n * viewer.scene.camera.up = [-0.2, 0.89, -0.33,];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const sceneModel = xktLoader.load({\n *   manifestSrc: \"model.xkt.manifest.json\",\n *   id: \"myModel\",\n * });\n *\n * const metaModel = viewer.metaScene.metaModels[sceneModel.id];\n *\n * // Then when we need to, we can destroy the SceneModel\n * // and MetaModel in one shot, like so:\n *\n * sceneModel.destroy();\n * metaModel.destroy();\n * ````\n *\n * The main advantage here, of splitting IFC files like this within the conversion and import pipeline,\n * is to reduce the memory pressure on each of the `ifc2gltf`, `convert2xkt` and XKTLoaderPlugin components.\n * They work much reliably (and faster) when processing smaller files (eg. 20MB) than when processing large files (eg. 500MB), where\n * they have less trouble allocating the system memory they need for conversion and parsing.\n *\n * We can also provide an HTTP URL to the manifest:\n *\n * ````javascript\n * const sceneModel = xktLoader.load({\n *   manifestSrc: \"https://xeokit.github.io/xeokit-sdk/assets/models/xkt/v10/split/Karhumaki-Bridge/model.xkt.manifest.json\",\n *   id: \"myModel\",\n * });\n * ````\n *\n * We can also provide the manifest as parameter object:\n *\n * ````javascript\n * const sceneModel = xktLoader.load({\n *   id: \"myModel\",\n *   manifest: {\n *   inputFile: \"assets/models/gltf/Karhumaki/model.glb.manifest.json\",\n *   converterApplication: \"convert2xkt\",\n *   converterApplicationVersion: \"v1.1.10\",\n *   conversionDate\": \"09-11-2023- 18-29-01\",\n *     xktFiles: [\n *       \"../../assets/models/xkt/v10/split/Karhumaki-Bridge/model.xkt\",\n *       \"../../assets/models/xkt/v10/split/Karhumaki-Bridge/model_1.xkt\",\n *       \"../../assets/models/xkt/v10/split/Karhumaki-Bridge/model_2.xkt\",\n *       \"../../assets/models/xkt/v10/split/Karhumaki-Bridge/model_3.xkt\",\n *       \"../../assets/models/xkt/v10/split/Karhumaki-Bridge/model_4.xkt\",\n *       \"../../assets/models/xkt/v10/split/Karhumaki-Bridge/model_5.xkt\",\n *       \"../../assets/models/xkt/v10/split/Karhumaki-Bridge/model_6.xkt\",\n *       \"../../assets/models/xkt/v10/split/Karhumaki-Bridge/model_7.xkt\",\n *       \"../../assets/models/xkt/v10/split/Karhumaki-Bridge/model_8.xkt\"\n *     ]\n *   }\n * });\n * ````\n *\n * We can also provide the paths to the XKT files as HTTP URLs:\n *\n * ````javascript\n * const sceneModel = xktLoader.load({\n *   id: \"myModel\",\n *   manifest: {\n *   inputFile: \"assets/models/gltf/Karhumaki/model.glb.manifest.json\",\n *   converterApplication: \"convert2xkt\",\n *   converterApplicationVersion: \"v1.1.10\",\n *   conversionDate\": \"09-11-2023- 18-29-01\",\n *     xktFiles: [\n *       \"https://xeokit.github.io/xeokit-sdk/assets/models/xkt/v10/split/Karhumaki-Bridge/model.xkt\",\n *       \"https://xeokit.github.io/xeokit-sdk/assets/models/xkt/v10/split/Karhumaki-Bridge/model_1.xkt\",\n *       \"https://xeokit.github.io/xeokit-sdk/assets/models/xkt/v10/split/Karhumaki-Bridge/model_2.xkt\",\n *       \"https://xeokit.github.io/xeokit-sdk/assets/models/xkt/v10/split/Karhumaki-Bridge/model_3.xkt\",\n *       \"https://xeokit.github.io/xeokit-sdk/assets/models/xkt/v10/split/Karhumaki-Bridge/model_4.xkt\",\n *       \"https://xeokit.github.io/xeokit-sdk/assets/models/xkt/v10/split/Karhumaki-Bridge/model_5.xkt\",\n *       \"https://xeokit.github.io/xeokit-sdk/assets/models/xkt/v10/split/Karhumaki-Bridge/model_6.xkt\",\n *       \"https://xeokit.github.io/xeokit-sdk/assets/models/xkt/v10/split/Karhumaki-Bridge/model_7.xkt\",\n *       \"https://xeokit.github.io/xeokit-sdk/assets/models/xkt/v10/split/Karhumaki-Bridge/model_8.xkt\"\n *     ]\n *   }\n * });\n * ````\n *\n * @class XKTLoaderPlugin\n */\nclass XKTLoaderPlugin extends Plugin {\n\n    /**\n     * @constructor\n     *\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"XKTLoader\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {Object} [cfg.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object.  Default value is {@link IFCObjectDefaults}.\n     * @param {Object} [cfg.dataSource] A custom data source through which the XKTLoaderPlugin can load model and metadata files. Defaults to an instance of {@link XKTDefaultDataSource}, which loads uover HTTP.\n     * @param {String[]} [cfg.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.\n     * @param {String[]} [cfg.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.\n     * @param {Boolean} [cfg.excludeUnclassifiedObjects=false] When loading metadata and this is ````true````, will only load {@link Entity}s that have {@link MetaObject}s (that are not excluded). This is useful when we don't want Entitys in the Scene that are not represented within IFC navigation components, such as {@link TreeViewPlugin}.\n     * @param {Boolean} [cfg.reuseGeometries=true] Indicates whether to enable geometry reuse (````true```` by default) or whether to internally expand\n     * all geometry instances into batches (````false````), and not use instancing to render them. Setting this ````false```` can significantly\n     * improve Viewer performance for models that have a lot of geometry reuse, but may also increase the amount of\n     * browser and GPU memory they require. See [#769](https://github.com/xeokit/xeokit-sdk/issues/769) for more info.\n     * @param {Number} [cfg.maxGeometryBatchSize=50000000] Maximum geometry batch size, as number of vertices. This is optionally supplied\n     * to limit the size of the batched geometry arrays that {@link SceneModel} internally creates for batched geometries.\n     * A low value means less heap allocation/de-allocation while loading batched geometries, but more draw calls and\n     * slower rendering speed. A high value means larger heap allocation/de-allocation while loading, but less draw calls\n     * and faster rendering speed. It's recommended to keep this somewhere roughly between ````50000```` and ````50000000```.\n     * @param {KTX2TextureTranscoder} [cfg.textureTranscoder] Transcoder used internally to transcode KTX2\n     * textures within the XKT. Only required when the XKT is version 10 or later, and contains KTX2 textures.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"XKTLoader\", viewer, cfg);\n\n        this._maxGeometryBatchSize = cfg.maxGeometryBatchSize;\n\n        this.textureTranscoder = cfg.textureTranscoder;\n        this.dataSource = cfg.dataSource;\n        this.objectDefaults = cfg.objectDefaults;\n        this.includeTypes = cfg.includeTypes;\n        this.excludeTypes = cfg.excludeTypes;\n        this.excludeUnclassifiedObjects = cfg.excludeUnclassifiedObjects;\n        this.reuseGeometries = cfg.reuseGeometries;\n    }\n\n    /**\n     * Gets the ````.xkt```` format versions supported by this XKTLoaderPlugin/\n     * @returns {string[]}\n     */\n    get supportedVersions() {\n        return Object.keys(parsers);\n    }\n\n    /**\n     * Gets the texture transcoder.\n     *\n     * @type {TextureTranscoder}\n     */\n    get textureTranscoder() {\n        return this._textureTranscoder;\n    }\n\n    /**\n     * Sets the texture transcoder.\n     *\n     * @type {TextureTranscoder}\n     */\n    set textureTranscoder(textureTranscoder) {\n        this._textureTranscoder = textureTranscoder;\n    }\n\n    /**\n     * Gets the custom data source through which the XKTLoaderPlugin can load models and metadata.\n     *\n     * Default value is {@link XKTDefaultDataSource}, which loads via HTTP.\n     *\n     * @type {Object}\n     */\n    get dataSource() {\n        return this._dataSource;\n    }\n\n    /**\n     * Sets a custom data source through which the XKTLoaderPlugin can load models and metadata.\n     *\n     * Default value is {@link XKTDefaultDataSource}, which loads via HTTP.\n     *\n     * @type {Object}\n     */\n    set dataSource(value) {\n        this._dataSource = value || new XKTDefaultDataSource();\n    }\n\n    /**\n     * Gets map of initial default states for each loaded {@link Entity} that represents an object.\n     *\n     * Default value is {@link IFCObjectDefaults}.\n     *\n     * @type {{String: Object}}\n     */\n    get objectDefaults() {\n        return this._objectDefaults;\n    }\n\n    /**\n     * Sets map of initial default states for each loaded {@link Entity} that represents an object.\n     *\n     * Default value is {@link IFCObjectDefaults}.\n     *\n     * @type {{String: Object}}\n     */\n    set objectDefaults(value) {\n        this._objectDefaults = value || IFCObjectDefaults;\n    }\n\n    /**\n     * Gets the whitelist of the IFC types loaded by this XKTLoaderPlugin.\n     *\n     * When loading models with metadata, causes this XKTLoaderPlugin to only load objects whose types are in this\n     * list. An object's type is indicated by its {@link MetaObject}'s {@link MetaObject#type}.\n     *\n     * Default value is ````undefined````.\n     *\n     * @type {String[]}\n     */\n    get includeTypes() {\n        return this._includeTypes;\n    }\n\n    /**\n     * Sets the whitelist of the IFC types loaded by this XKTLoaderPlugin.\n     *\n     * When loading models with metadata, causes this XKTLoaderPlugin to only load objects whose types are in this\n     * list. An object's type is indicated by its {@link MetaObject}'s {@link MetaObject#type}.\n     *\n     * Default value is ````undefined````.\n     *\n     * @type {String[]}\n     */\n    set includeTypes(value) {\n        this._includeTypes = value;\n    }\n\n    /**\n     * Gets the blacklist of IFC types that are never loaded by this XKTLoaderPlugin.\n     *\n     * When loading models with metadata, causes this XKTLoaderPlugin to **not** load objects whose types are in this\n     * list. An object's type is indicated by its {@link MetaObject}'s {@link MetaObject#type}.\n     *\n     * Default value is ````undefined````.\n     *\n     * @type {String[]}\n     */\n    get excludeTypes() {\n        return this._excludeTypes;\n    }\n\n    /**\n     * Sets the blacklist of IFC types that are never loaded by this XKTLoaderPlugin.\n     *\n     * When loading models with metadata, causes this XKTLoaderPlugin to **not** load objects whose types are in this\n     * list. An object's type is indicated by its {@link MetaObject}'s {@link MetaObject#type}.\n     *\n     * Default value is ````undefined````.\n     *\n     * @type {String[]}\n     */\n    set excludeTypes(value) {\n        this._excludeTypes = value;\n    }\n\n    /**\n     * Gets the whitelist of the specified elements loaded by this XKTLoaderPlugin.\n     *\n     * When loading models with metadata, causes this XKTLoaderPlugin to only load objects whose ids are in this\n     * list. An object's id is indicated by its {@link MetaObject}'s {@link MetaObject#id}.\n     *\n     * Default value is ````undefined````.\n     *\n     * @type {String[]}\n     */\n    get includeIds() {\n        return this._includeIds;\n    }\n\n    /**\n     * Sets the whitelist of the specified elements by this XKTLoaderPlugin.\n     *\n     * When loading models with metadata, causes this XKTLoaderPlugin to only load objects whose ids are in this\n     * list. An object's id is indicated by its {@link MetaObject}'s {@link MetaObject#id}.\n     *\n     * Default value is ````undefined````.\n     *\n     * @type {String[]}\n     */\n    set includeIds(value) {\n        this._includeIds = value;\n    }\n\n    /**\n     * Gets whether we load objects that don't have IFC types.\n     *\n     * When loading models with metadata and this is ````true````, XKTLoaderPlugin will not load objects\n     * that don't have IFC types.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get excludeUnclassifiedObjects() {\n        return this._excludeUnclassifiedObjects;\n    }\n\n    /**\n     * Sets whether we load objects that don't have IFC types.\n     *\n     * When loading models with metadata and this is ````true````, XKTLoaderPlugin will not load objects\n     * that don't have IFC types.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set excludeUnclassifiedObjects(value) {\n        this._excludeUnclassifiedObjects = !!value;\n    }\n\n    /**\n     * Gets whether XKTLoaderPlugin globalizes each {@link Entity#id} and {@link MetaObject#id} as it loads a model.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get globalizeObjectIds() {\n        return this._globalizeObjectIds;\n    }\n\n    /**\n     * Sets whether XKTLoaderPlugin globalizes each {@link Entity#id} and {@link MetaObject#id} as it loads a model.\n     *\n     * Set  this ````true```` when you need to load multiple instances of the same model, to avoid ID clashes\n     * between the objects in the different instances.\n     *\n     * When we load a model with this set ````true````, then each {@link Entity#id} and {@link MetaObject#id} will be\n     * prefixed by the ID of the model, ie. ````<modelId>#<objectId>````.\n     *\n     * {@link Entity#originalSystemId} and {@link MetaObject#originalSystemId} will always hold the original, un-prefixed, ID values.\n     *\n     * Default value is ````false````.\n     *\n     * See the main {@link XKTLoaderPlugin} class documentation for usage info.\n     *\n     * @type {Boolean}\n     */\n    set globalizeObjectIds(value) {\n        this._globalizeObjectIds = !!value;\n    }\n\n    /**\n     * Gets whether XKTLoaderPlugin enables geometry reuse when loading models.\n     *\n     * Default value is ````true````.\n     *\n     * @type {Boolean}\n     */\n    get reuseGeometries() {\n        return this._reuseGeometries;\n    }\n\n    /**\n     * Sets whether XKTLoaderPlugin enables geometry reuse when loading models.\n     *\n     * Default value is ````true````.\n     *\n     * Geometry reuse saves memory, but can impact Viewer performance when there are many reused geometries. For\n     * this reason, we can set this ````false```` to disable geometry reuse for models loaded by this XKTLoaderPlugin\n     * (which will then \"expand\" the geometry instances into batches instead).\n     *\n     * The result will be be less WebGL draw calls (which are expensive), at the cost of increased memory footprint.\n     *\n     * See [#769](https://github.com/xeokit/xeokit-sdk/issues/769) for more info.\n     *\n     * @type {Boolean}\n     */\n    set reuseGeometries(value) {\n        this._reuseGeometries = value !== false;\n    }\n\n    /**\n     * Loads an ````.xkt```` model into this XKTLoaderPlugin's {@link Viewer}.\n     *\n     * Since xeokit/xeokit-sdk 1.9.0, XKTLoaderPlugin has supported XKT 8, which bundles the metamodel\n     * data (eg. an IFC element hierarchy) in the XKT file itself. For XKT 8, we therefore no longer need to\n     * load the metamodel data from a separate accompanying JSON file, as we did with previous XKT versions.\n     * However, if we do choose to specify a separate metamodel JSON file to load (eg. for backward compatibility\n     * in data pipelines), then that metamodel will be loaded and the metamodel in the XKT 8 file will be ignored.\n     *\n     * @param {*} params Loading parameters.\n     * @param {String} [params.id] ID to assign to the root {@link Entity#id}, unique among all components in the Viewer's {@link Scene}, generated automatically by default.\n     * @param {String} [params.src] Path or URL to an *````.xkt````* file, as an alternative to the ````xkt```` parameter.\n     * @param {ArrayBuffer} [params.xkt] The *````.xkt````* file data, as an alternative to the ````src```` parameter.\n     * @param {String} [params.metaModelSrc] Path or URL to an optional metadata file, as an alternative to the ````metaModelData```` parameter.\n     * @param {*} [params.metaModelData] JSON model metadata, as an alternative to the ````metaModelSrc```` parameter.\n     * @param {String} [params.manifestSrc] Path or URL to a JSON manifest file that provides paths to ````.xkt```` files to load as parts of the model. Use this option to load models that have been split into\n     * multiple XKT files. See [tutorial](https://www.notion.so/xeokit/Automatically-Splitting-Large-Models-for-Better-Performance-165fc022e94742cf966ee50003572259) for more info.\n     * @param {Object} [params.manifest] A JSON manifest object (as an alternative to a path or URL) that provides paths to ````.xkt```` files to load as parts of the model. Use this option to load models that have been split into\n     * multiple XKT files. See [tutorial](https://www.notion.so/xeokit/Automatically-Splitting-Large-Models-for-Better-Performance-165fc022e94742cf966ee50003572259) for more info.\n     * @param {{String:Object}} [params.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.\n     * @param {String[]} [params.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.\n     * @param {String[]} [params.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.\n     * @param {String[]} [params.includeIds] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#id} values in this list.\n     * @param {Boolean} [params.edges=false] Whether or not xeokit renders the model with edges emphasized.\n     * @param {Number[]} [params.origin=[0,0,0]] The model's World-space double-precision 3D origin. Use this to position the model within xeokit's World coordinate system, using double-precision coordinates.\n     * @param {Number[]} [params.position=[0,0,0]] The model single-precision 3D position, relative to the ````origin```` parameter.\n     * @param {Number[]} [params.scale=[1,1,1]] The model's scale.\n     * @param {Number[]} [params.rotation=[0,0,0]] The model's orientation, given as Euler angles in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [params.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] The model's world transform matrix. Overrides the position, scale and rotation parameters. Relative to ````origin````.\n     * @param {Boolean} [params.edges=false] Indicates if the model's edges are initially emphasized.\n     * @param {Boolean} [params.saoEnabled=true] Indicates if Scalable Ambient Obscurance (SAO) is enabled for the model. SAO is configured by the Scene's {@link SAO} component. Only works when {@link SAO#enabled} is also ````true````\n     * @param {Boolean} [params.pbrEnabled=true] Indicates if physically-based rendering (PBR) is enabled for the model. Overrides ````colorTextureEnabled````. Only works when {@link Scene#pbrEnabled} is also ````true````.\n     * @param {Boolean} [params.colorTextureEnabled=true] Indicates if base color texture rendering is enabled for the model. Overridden by ````pbrEnabled````.  Only works when {@link Scene#colorTextureEnabled} is also ````true````.\n     * @param {Number} [params.backfaces=false] When we set this ````true````, then we force rendering of backfaces for the model. When\n     * we leave this ````false````, then we allow the Viewer to decide when to render backfaces. In that case, the\n     * Viewer will hide backfaces on watertight meshes, show backfaces on open meshes, and always show backfaces on meshes when we slice them open with {@link SectionPlane}s.\n     * @param {Boolean} [params.excludeUnclassifiedObjects=false] When loading metadata and this is ````true````, will only load {@link Entity}s that have {@link MetaObject}s (that are not excluded). This is useful when we don't want Entitys in the Scene that are not represented within IFC navigation components, such as {@link TreeViewPlugin}.\n     * @param {Boolean} [params.globalizeObjectIds=false] Indicates whether to globalize each {@link Entity#id} and {@link MetaObject#id}, in case you need to prevent ID clashes with other models. See {@link XKTLoaderPlugin#globalizeObjectIds} for more info.\n     * @param {Boolean} [params.reuseGeometries=true] Indicates whether to enable geometry reuse (````true```` by default) or whether to expand\n     * all geometry instances into batches (````false````), and not use instancing to render them. Setting this ````false```` can significantly\n     * improve Viewer performance for models that have excessive geometry reuse, but may also increases the amount of\n     * browser and GPU memory used by the model. See [#769](https://github.com/xeokit/xeokit-sdk/issues/769) for more info.\n     * @param {Boolean} [params.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to\n     * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable\n     * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point\n     * primitives. Only works while {@link DTX#enabled} is also ````true````.\n     * @param {Number} [params.renderOrder=0] Specifies the rendering order for the model. This is used to control the order in which\n     * SceneModels are drawn when they have transparent objects, to give control over the order in which those objects are blended within the transparent\n     * render pass.\n     * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.\n     */\n    load(params = {}) {\n\n        if (params.id && this.viewer.scene.components[params.id]) {\n            this.error(\"Component with this ID already exists in viewer: \" + params.id + \" - will autogenerate this ID\");\n            delete params.id;\n        }\n\n        if (!params.src && !params.xkt && !params.manifestSrc && !params.manifest)\n            throw new Error(\"XKTLoaderPlugin: load() param expected: src, xkt, manifestSrc or manifestData\");\n\n        const options = {};\n        const includeTypes = params.includeTypes || this._includeTypes;\n        const excludeTypes = params.excludeTypes || this._excludeTypes;\n        const includeIds = params.includeIds || this._includeIds;\n        const objectDefaults = params.objectDefaults || this._objectDefaults;\n\n        options.reuseGeometries = (params.reuseGeometries !== null && params.reuseGeometries !== undefined) ? params.reuseGeometries : (this._reuseGeometries !== false);\n\n        if (includeTypes) {\n            options.includeTypesMap = {};\n            for (let i = 0, len = includeTypes.length; i < len; i++) {\n                options.includeTypesMap[includeTypes[i]] = true;\n            }\n        }\n\n        if (excludeTypes) {\n            options.excludeTypesMap = {};\n            for (let i = 0, len = excludeTypes.length; i < len; i++) {\n                options.excludeTypesMap[excludeTypes[i]] = true;\n            }\n        }\n\n        if (includeIds) {\n            options.includeIdsMap = {};\n            for (let i = 0, len = includeIds.length; i < len; i++) {\n                options.includeIdsMap[includeIds[i]] = true;\n            }\n        }\n\n        if (objectDefaults) {\n            options.objectDefaults = objectDefaults;\n        }\n\n        options.excludeUnclassifiedObjects = (params.excludeUnclassifiedObjects !== undefined) ? (!!params.excludeUnclassifiedObjects) : this._excludeUnclassifiedObjects;\n        options.globalizeObjectIds = (params.globalizeObjectIds !== undefined && params.globalizeObjectIds !== null) ? (!!params.globalizeObjectIds) : this._globalizeObjectIds;\n\n        const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {\n            isModel: true,\n            textureTranscoder: this._textureTranscoder,\n            maxGeometryBatchSize: this._maxGeometryBatchSize,\n            origin: params.origin,\n            disableVertexWelding: params.disableVertexWelding || false,\n            disableIndexRebucketing: params.disableIndexRebucketing || false,\n            dtxEnabled: params.dtxEnabled,\n            renderOrder: params.renderOrder\n        }));\n\n        const modelId = sceneModel.id;  // In case ID was auto-generated\n\n        const metaModel = new MetaModel({\n            metaScene: this.viewer.metaScene,\n            id: modelId\n        });\n\n        this.viewer.scene.canvas.spinner.processes++;\n\n        const finish = () => {\n            if (sceneModel.destroyed) {\n                return;\n            }\n            // this._createDefaultMetaModelIfNeeded(sceneModel, params, options);\n            sceneModel.finalize();\n            metaModel.finalize();\n            this.viewer.scene.canvas.spinner.processes--;\n            sceneModel.once(\"destroyed\", () => {\n                this.viewer.metaScene.destroyMetaModel(metaModel.id);\n            });\n            this.scheduleTask(() => {\n                if (sceneModel.destroyed) {\n                    return;\n                }\n                sceneModel.scene.fire(\"modelLoaded\", sceneModel.id); // FIXME: Assumes listeners know order of these two events\n                sceneModel.fire(\"loaded\", true, false); // Don't forget the event, for late subscribers\n            });\n        };\n\n        const error = (errMsg) => {\n            this.viewer.scene.canvas.spinner.processes--;\n            this.error(errMsg);\n            sceneModel.fire(\"error\", errMsg);\n        };\n\n        let nextId = 0;\n        const manifestCtx = {\n            getNextId: () => {\n                return `${modelId}.${nextId++}`;\n            }\n        };\n\n        if (params.metaModelSrc || params.metaModelData) {\n\n            if (params.metaModelSrc) {\n\n                const metaModelSrc = params.metaModelSrc;\n\n                this._dataSource.getMetaModel(metaModelSrc, (metaModelData) => {\n                    if (sceneModel.destroyed) {\n                        return;\n                    }\n                    metaModel.loadData(metaModelData, {\n                        includeTypes: includeTypes,\n                        excludeTypes: excludeTypes,\n                        globalizeObjectIds: options.globalizeObjectIds\n                    });\n                    if (params.src) {\n                        this._loadModel(params.src, options, sceneModel, null, manifestCtx, finish, error);\n                    } else {\n                        this._parseModel(params.xkt, options, sceneModel, null, manifestCtx);\n                        finish();\n                    }\n                }, (errMsg) => {\n                    error(`load(): Failed to load model metadata for model '${modelId} from  '${metaModelSrc}' - ${errMsg}`);\n                });\n\n            } else if (params.metaModelData) {\n                metaModel.loadData(params.metaModelData, {\n                    includeTypes: includeTypes,\n                    excludeTypes: excludeTypes,\n                    globalizeObjectIds: options.globalizeObjectIds\n                });\n                if (params.src) {\n                    this._loadModel(params.src, options, sceneModel, null, manifestCtx, finish, error);\n                } else {\n                    this._parseModel(params.xkt, options, sceneModel, null, manifestCtx);\n                    finish();\n                }\n            }\n\n\n        } else {\n\n            if (params.src) {\n                this._loadModel(params.src, options, sceneModel, metaModel, manifestCtx, finish, error);\n            } else if (params.xkt) {\n                this._parseModel(params.xkt, options, sceneModel, metaModel, manifestCtx);\n                finish();\n            } else if (params.manifestSrc || params.manifest) {\n                const baseDir = params.manifestSrc ? getBaseDirectory$1(params.manifestSrc) : \"\";\n                const loadJSONs = (metaDataFiles, done, error) => {\n                    let i = 0;\n                    const loadNext = () => {\n                        if (sceneModel.destroyed) {\n                            done();\n                        } else if (i >= metaDataFiles.length) {\n                            done();\n                        } else {\n                            this._dataSource.getMetaModel(`${baseDir}${metaDataFiles[i]}`, (metaModelData) => {\n                                metaModel.loadData(metaModelData, {\n                                    includeTypes: includeTypes,\n                                    excludeTypes: excludeTypes,\n                                    globalizeObjectIds: options.globalizeObjectIds\n                                });\n                                i++;\n                                this.scheduleTask(loadNext, 200);\n                            }, error);\n                        }\n                    };\n                    loadNext();\n                };\n                const loadXKTs_excludeTheirMetaModels = (xktFiles, done, error) => { // Load XKTs, ignore metamodels in the XKT\n                    let i = 0;\n                    const loadNext = () => {\n                        if (sceneModel.destroyed) {\n                            done();\n                        } else if (i >= xktFiles.length) {\n                            done();\n                        } else {\n                            this._dataSource.getXKT(`${baseDir}${xktFiles[i]}`, (arrayBuffer) => {\n                                this._parseModel(arrayBuffer, options, sceneModel, null /* Ignore metamodel in XKT */, manifestCtx);\n                                sceneModel.preFinalize();\n                                i++;\n                                this.scheduleTask(loadNext, 200);\n                            }, error);\n                        }\n                    };\n                    loadNext();\n                };\n                const loadXKTs_includeTheirMetaModels = (xktFiles, done, error) => { // Load XKTs, parse metamodels from the XKT\n                    let i = 0;\n                    const loadNext = () => {\n                        if (sceneModel.destroyed) {\n                            done();\n                        } else if (i >= xktFiles.length) {\n                            done();\n                        } else {\n                            this._dataSource.getXKT(`${baseDir}${xktFiles[i]}`, (arrayBuffer) => {\n                                this._parseModel(arrayBuffer, options, sceneModel, metaModel, manifestCtx);\n                                sceneModel.preFinalize();\n                                i++;\n                                this.scheduleTask(loadNext, 200);\n                            }, error);\n                        }\n                    };\n                    loadNext();\n                };\n                if (params.manifest) {\n                    const manifestData = params.manifest;\n                    const xktFiles = manifestData.xktFiles;\n                    if (!xktFiles || xktFiles.length === 0) {\n                        error(`load(): Failed to load model manifest - manifest not valid`);\n                        return;\n                    }\n                    const metaModelFiles = manifestData.metaModelFiles;\n                    if (metaModelFiles) {\n                        loadJSONs(metaModelFiles, () => {\n                            loadXKTs_excludeTheirMetaModels(xktFiles, finish, error);\n                        }, error);\n                    } else {\n                        loadXKTs_includeTheirMetaModels(xktFiles, finish, error);\n                    }\n                } else {\n                    this._dataSource.getManifest(params.manifestSrc, (manifestData) => {\n                        if (sceneModel.destroyed) {\n                            return;\n                        }\n                        const xktFiles = manifestData.xktFiles;\n                        if (!xktFiles || xktFiles.length === 0) {\n                            error(`load(): Failed to load model manifest - manifest not valid`);\n                            return;\n                        }\n                        const metaModelFiles = manifestData.metaModelFiles;\n                        if (metaModelFiles) {\n                            loadJSONs(metaModelFiles, () => {\n                                loadXKTs_excludeTheirMetaModels(xktFiles, finish, error);\n                            }, error);\n                        } else {\n                            loadXKTs_includeTheirMetaModels(xktFiles, finish, error);\n                        }\n                    }, error);\n                }\n            }\n        }\n\n        return sceneModel;\n    }\n\n    _loadModel(src, options, sceneModel, metaModel, manifestCtx, done, error) {\n        this._dataSource.getXKT(src, (arrayBuffer) => {\n            this._parseModel(arrayBuffer, options, sceneModel, metaModel, manifestCtx);\n            sceneModel.preFinalize();\n            done();\n        }, error);\n    }\n\n    async _parseModel(arrayBuffer, options, sceneModel, metaModel, manifestCtx) {\n        if (sceneModel.destroyed) {\n            return;\n        }\n        const dataView = new DataView(arrayBuffer);\n        const dataArray = new Uint8Array(arrayBuffer);\n        const firstUint = dataView.getUint32(0, true);\n        const xktVersion = firstUint & 0x7fffffff;\n        const zipped = (xktVersion < 11) || ((xktVersion >= 12) && (firstUint >>> 31));\n        const parser = parsers[xktVersion];\n        if (!parser) {\n            this.error(\"Unsupported .XKT file version: \" + xktVersion + \" - this XKTLoaderPlugin supports versions \" + Object.keys(parsers));\n            return;\n        }\n        //   this.log(\"Loading .xkt V\" + xktVersion);\n\n        if (!zipped) {\n            parser.parseArrayBuffer(this.viewer, options, arrayBuffer, sceneModel, metaModel, manifestCtx);\n            return;\n        }\n\n        const numElements = dataView.getUint32(4, true);\n        const elements = [];\n        let byteOffset = (numElements + 2) * 4;\n        for (let i = 0; i < numElements; i++) {\n            const elementSize = dataView.getUint32((i + 2) * 4, true);\n            elements.push(dataArray.subarray(byteOffset, byteOffset + elementSize));\n            byteOffset += elementSize;\n        }\n        parser.parse(this.viewer, options, elements, sceneModel, metaModel, manifestCtx);\n    }\n}\n\nfunction getBaseDirectory$1(filePath) {\n    if (filePath.indexOf('?') > -1) {\n        filePath = filePath.split('?')[0];\n    }\n\n    const pathArray = filePath.split('/');\n    pathArray.pop(); // Remove the file name or the last segment of the path\n    return pathArray.join('/') + '/';\n}\n\n/*\n Copyright (c) 2013 Gildas Lormeau. All rights reserved.\n\n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n this list of conditions and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in\n the documentation and/or other materials provided with the distribution.\n\n 3. The names of the authors may not be used to endorse or promote products\n derived from this software without specific prior written permission.\n\n THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\n INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\n FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,\n INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,\n INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * @private\n * @type {{}}\n */\nvar zipLib = {};\n\n(function (obj) {\n\n    var ERR_BAD_FORMAT = \"File format is not recognized.\";\n    var ERR_CRC = \"CRC failed.\";\n    var ERR_ENCRYPTED = \"File contains encrypted entry.\";\n    var ERR_ZIP64 = \"File is using Zip64 (4gb+ file size).\";\n    var ERR_READ = \"Error while reading zip file.\";\n    var ERR_WRITE = \"Error while writing zip file.\";\n    var ERR_WRITE_DATA = \"Error while writing file data.\";\n    var ERR_READ_DATA = \"Error while reading file data.\";\n    var ERR_DUPLICATED_NAME = \"File already exists.\";\n    var CHUNK_SIZE = 512 * 1024;\n\n    var TEXT_PLAIN = \"text/plain\";\n\n    var appendABViewSupported;\n    try {\n        appendABViewSupported = new Blob([new DataView(new ArrayBuffer(0))]).size === 0;\n    } catch (e) {\n    }\n\n    function Crc32() {\n        this.crc = -1;\n    }\n\n    Crc32.prototype.append = function append(data) {\n        var crc = this.crc | 0, table = this.table;\n        for (var offset = 0, len = data.length | 0; offset < len; offset++)\n            crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF];\n        this.crc = crc;\n    };\n    Crc32.prototype.get = function get() {\n        return ~this.crc;\n    };\n    Crc32.prototype.table = (function () {\n        var i, j, t, table = []; // Uint32Array is actually slower than []\n        for (i = 0; i < 256; i++) {\n            t = i;\n            for (j = 0; j < 8; j++)\n                if (t & 1)\n                    t = (t >>> 1) ^ 0xEDB88320;\n                else\n                    t = t >>> 1;\n            table[i] = t;\n        }\n        return table;\n    })();\n\n    // \"no-op\" codec\n    function NOOP() {\n    }\n\n    NOOP.prototype.append = function append(bytes, onprogress) {\n        return bytes;\n    };\n    NOOP.prototype.flush = function flush() {\n    };\n\n    function blobSlice(blob, index, length) {\n        if (index < 0 || length < 0 || index + length > blob.size)\n            throw new RangeError('offset:' + index + ', length:' + length + ', size:' + blob.size);\n        if (blob.slice)\n            return blob.slice(index, index + length);\n        else if (blob.webkitSlice)\n            return blob.webkitSlice(index, index + length);\n        else if (blob.mozSlice)\n            return blob.mozSlice(index, index + length);\n        else if (blob.msSlice)\n            return blob.msSlice(index, index + length);\n    }\n\n    function getDataHelper(byteLength, bytes) {\n        var dataBuffer, dataArray;\n        dataBuffer = new ArrayBuffer(byteLength);\n        dataArray = new Uint8Array(dataBuffer);\n        if (bytes)\n            dataArray.set(bytes, 0);\n        return {\n            buffer: dataBuffer,\n            array: dataArray,\n            view: new DataView(dataBuffer)\n        };\n    }\n\n    // Readers\n    function Reader() {\n    }\n\n    function TextReader(text) {\n        var that = this, blobReader;\n\n        function init(callback, onerror) {\n            var blob = new Blob([text], {\n                type: TEXT_PLAIN\n            });\n            blobReader = new BlobReader(blob);\n            blobReader.init(function () {\n                that.size = blobReader.size;\n                callback();\n            }, onerror);\n        }\n\n        function readUint8Array(index, length, callback, onerror) {\n            blobReader.readUint8Array(index, length, callback, onerror);\n        }\n\n        that.size = 0;\n        that.init = init;\n        that.readUint8Array = readUint8Array;\n    }\n\n    TextReader.prototype = new Reader();\n    TextReader.prototype.constructor = TextReader;\n\n    function Data64URIReader(dataURI) {\n        var that = this, dataStart;\n\n        function init(callback) {\n            var dataEnd = dataURI.length;\n            while (dataURI.charAt(dataEnd - 1) == \"=\")\n                dataEnd--;\n            dataStart = dataURI.indexOf(\",\") + 1;\n            that.size = Math.floor((dataEnd - dataStart) * 0.75);\n            callback();\n        }\n\n        function readUint8Array(index, length, callback) {\n            var i, data = getDataHelper(length);\n            var start = Math.floor(index / 3) * 4;\n            var end = Math.ceil((index + length) / 3) * 4;\n            var bytes = obj.atob(dataURI.substring(start + dataStart, end + dataStart));\n            var delta = index - Math.floor(start / 4) * 3;\n            for (i = delta; i < delta + length; i++)\n                data.array[i - delta] = bytes.charCodeAt(i);\n            callback(data.array);\n        }\n\n        that.size = 0;\n        that.init = init;\n        that.readUint8Array = readUint8Array;\n    }\n\n    Data64URIReader.prototype = new Reader();\n    Data64URIReader.prototype.constructor = Data64URIReader;\n\n    function BlobReader(blob) {\n        var that = this;\n\n        function init(callback) {\n            that.size = blob.size;\n            callback();\n        }\n\n        function readUint8Array(index, length, callback, onerror) {\n            var reader = new FileReader();\n            reader.onload = function (e) {\n                callback(new Uint8Array(e.target.result));\n            };\n            reader.onerror = onerror;\n            try {\n                reader.readAsArrayBuffer(blobSlice(blob, index, length));\n            } catch (e) {\n                onerror(e);\n            }\n        }\n\n        that.size = 0;\n        that.init = init;\n        that.readUint8Array = readUint8Array;\n    }\n\n    BlobReader.prototype = new Reader();\n    BlobReader.prototype.constructor = BlobReader;\n\n    // Writers\n\n    function Writer() {\n    }\n\n    Writer.prototype.getData = function (callback) {\n        callback(this.data);\n    };\n\n    function TextWriter(encoding) {\n        var that = this, blob;\n\n        function init(callback) {\n            blob = new Blob([], {\n                type: TEXT_PLAIN\n            });\n            callback();\n        }\n\n        function writeUint8Array(array, callback) {\n            blob = new Blob([blob, appendABViewSupported ? array : array.buffer], {\n                type: TEXT_PLAIN\n            });\n            callback();\n        }\n\n        function getData(callback, onerror) {\n            var reader = new FileReader();\n            reader.onload = function (e) {\n                callback(e.target.result);\n            };\n            reader.onerror = onerror;\n            reader.readAsText(blob, encoding);\n        }\n\n        that.init = init;\n        that.writeUint8Array = writeUint8Array;\n        that.getData = getData;\n    }\n\n    TextWriter.prototype = new Writer();\n    TextWriter.prototype.constructor = TextWriter;\n\n    function Data64URIWriter(contentType) {\n        var that = this, data = \"\", pending = \"\";\n\n        function init(callback) {\n            data += \"data:\" + (contentType || \"\") + \";base64,\";\n            callback();\n        }\n\n        function writeUint8Array(array, callback) {\n            var i, delta = pending.length, dataString = pending;\n            pending = \"\";\n            for (i = 0; i < (Math.floor((delta + array.length) / 3) * 3) - delta; i++)\n                dataString += String.fromCharCode(array[i]);\n            for (; i < array.length; i++)\n                pending += String.fromCharCode(array[i]);\n            if (dataString.length > 2)\n                data += obj.btoa(dataString);\n            else\n                pending = dataString;\n            callback();\n        }\n\n        function getData(callback) {\n            callback(data + obj.btoa(pending));\n        }\n\n        that.init = init;\n        that.writeUint8Array = writeUint8Array;\n        that.getData = getData;\n    }\n\n    Data64URIWriter.prototype = new Writer();\n    Data64URIWriter.prototype.constructor = Data64URIWriter;\n\n    function BlobWriter(contentType) {\n        var blob, that = this;\n\n        function init(callback) {\n            blob = new Blob([], {\n                type: contentType\n            });\n            callback();\n        }\n\n        function writeUint8Array(array, callback) {\n            blob = new Blob([blob, appendABViewSupported ? array : array.buffer], {\n                type: contentType\n            });\n            callback();\n        }\n\n        function getData(callback) {\n            callback(blob);\n        }\n\n        that.init = init;\n        that.writeUint8Array = writeUint8Array;\n        that.getData = getData;\n    }\n\n    BlobWriter.prototype = new Writer();\n    BlobWriter.prototype.constructor = BlobWriter;\n\n    /**\n     * inflate/deflate core functions\n     * @param worker {Worker} web worker for the task.\n     * @param initialMessage {Object} initial message to be sent to the worker. should contain\n     *   sn(serial number for distinguishing multiple tasks sent to the worker), and codecClass.\n     *   This function may add more properties before sending.\n     */\n    function launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror) {\n        var chunkIndex = 0, index, outputSize, sn = initialMessage.sn, crc;\n\n        function onflush() {\n            worker.removeEventListener('message', onmessage, false);\n            onend(outputSize, crc);\n        }\n\n        function onmessage(event) {\n            var message = event.data, data = message.data, err = message.error;\n            if (err) {\n                err.toString = function () {\n                    return 'Error: ' + this.message;\n                };\n                onreaderror(err);\n                return;\n            }\n            if (message.sn !== sn)\n                return;\n            if (typeof message.codecTime === 'number')\n                worker.codecTime += message.codecTime; // should be before onflush()\n            if (typeof message.crcTime === 'number')\n                worker.crcTime += message.crcTime;\n\n            switch (message.type) {\n                case 'append':\n                    if (data) {\n                        outputSize += data.length;\n                        writer.writeUint8Array(data, function () {\n                            step();\n                        }, onwriteerror);\n                    } else\n                        step();\n                    break;\n                case 'flush':\n                    crc = message.crc;\n                    if (data) {\n                        outputSize += data.length;\n                        writer.writeUint8Array(data, function () {\n                            onflush();\n                        }, onwriteerror);\n                    } else\n                        onflush();\n                    break;\n                case 'progress':\n                    if (onprogress)\n                        onprogress(index + message.loaded, size);\n                    break;\n                case 'importScripts': //no need to handle here\n                case 'newTask':\n                case 'echo':\n                    break;\n                default:\n                    console.warn('zip.js:launchWorkerProcess: unknown message: ', message);\n            }\n        }\n\n        function step() {\n            index = chunkIndex * CHUNK_SIZE;\n            // use `<=` instead of `<`, because `size` may be 0.\n            if (index <= size) {\n                reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function (array) {\n                    if (onprogress)\n                        onprogress(index, size);\n                    var msg = index === 0 ? initialMessage : {sn: sn};\n                    msg.type = 'append';\n                    msg.data = array;\n\n                    // posting a message with transferables will fail on IE10\n                    try {\n                        worker.postMessage(msg, [array.buffer]);\n                    } catch (ex) {\n                        worker.postMessage(msg); // retry without transferables\n                    }\n                    chunkIndex++;\n                }, onreaderror);\n            } else {\n                worker.postMessage({\n                    sn: sn,\n                    type: 'flush'\n                });\n            }\n        }\n\n        outputSize = 0;\n        worker.addEventListener('message', onmessage, false);\n        step();\n    }\n\n    function launchProcess(process, reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror) {\n        var chunkIndex = 0, index, outputSize = 0,\n            crcInput = crcType === 'input',\n            crcOutput = crcType === 'output',\n            crc = new Crc32();\n\n        function step() {\n            var outputData;\n            index = chunkIndex * CHUNK_SIZE;\n            if (index < size)\n                reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function (inputData) {\n                    var outputData;\n                    try {\n                        outputData = process.append(inputData, function (loaded) {\n                            if (onprogress)\n                                onprogress(index + loaded, size);\n                        });\n                    } catch (e) {\n                        onreaderror(e);\n                        return;\n                    }\n                    if (outputData) {\n                        outputSize += outputData.length;\n                        writer.writeUint8Array(outputData, function () {\n                            chunkIndex++;\n                            setTimeout(step, 1);\n                        }, onwriteerror);\n                        if (crcOutput)\n                            crc.append(outputData);\n                    } else {\n                        chunkIndex++;\n                        setTimeout(step, 1);\n                    }\n                    if (crcInput)\n                        crc.append(inputData);\n                    if (onprogress)\n                        onprogress(index, size);\n                }, onreaderror);\n            else {\n                try {\n                    outputData = process.flush();\n                } catch (e) {\n                    onreaderror(e);\n                    return;\n                }\n                if (outputData) {\n                    if (crcOutput)\n                        crc.append(outputData);\n                    outputSize += outputData.length;\n                    writer.writeUint8Array(outputData, function () {\n                        onend(outputSize, crc.get());\n                    }, onwriteerror);\n                } else\n                    onend(outputSize, crc.get());\n            }\n        }\n\n        step();\n    }\n\n    function inflate(worker, sn, reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) {\n        var crcType = computeCrc32 ? 'output' : 'none';\n        if (obj.zip.useWebWorkers) {\n            var initialMessage = {\n                sn: sn,\n                codecClass: 'Inflater',\n                crcType: crcType,\n            };\n            launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror);\n        } else\n            launchProcess(new obj.zip.Inflater(), reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror);\n    }\n\n    function deflate(worker, sn, reader, writer, level, onend, onprogress, onreaderror, onwriteerror) {\n        var crcType = 'input';\n        if (obj.zip.useWebWorkers) {\n            var initialMessage = {\n                sn: sn,\n                options: {level: level},\n                codecClass: 'Deflater',\n                crcType: crcType,\n            };\n            launchWorkerProcess(worker, initialMessage, reader, writer, 0, reader.size, onprogress, onend, onreaderror, onwriteerror);\n        } else\n            launchProcess(new obj.zip.Deflater(), reader, writer, 0, reader.size, crcType, onprogress, onend, onreaderror, onwriteerror);\n    }\n\n    function copy(worker, sn, reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) {\n        var crcType = 'input';\n        if (obj.zip.useWebWorkers && computeCrc32) {\n            var initialMessage = {\n                sn: sn,\n                codecClass: 'NOOP',\n                crcType: crcType,\n            };\n            launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror);\n        } else\n            launchProcess(new NOOP(), reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror);\n    }\n\n    // ZipReader\n\n    function decodeASCII(str) {\n        var i, out = \"\", charCode, extendedASCII = ['\\u00C7', '\\u00FC', '\\u00E9', '\\u00E2', '\\u00E4', '\\u00E0', '\\u00E5', '\\u00E7', '\\u00EA', '\\u00EB',\n            '\\u00E8', '\\u00EF', '\\u00EE', '\\u00EC', '\\u00C4', '\\u00C5', '\\u00C9', '\\u00E6', '\\u00C6', '\\u00F4', '\\u00F6', '\\u00F2', '\\u00FB', '\\u00F9',\n            '\\u00FF', '\\u00D6', '\\u00DC', '\\u00F8', '\\u00A3', '\\u00D8', '\\u00D7', '\\u0192', '\\u00E1', '\\u00ED', '\\u00F3', '\\u00FA', '\\u00F1', '\\u00D1',\n            '\\u00AA', '\\u00BA', '\\u00BF', '\\u00AE', '\\u00AC', '\\u00BD', '\\u00BC', '\\u00A1', '\\u00AB', '\\u00BB', '_', '_', '_', '\\u00A6', '\\u00A6',\n            '\\u00C1', '\\u00C2', '\\u00C0', '\\u00A9', '\\u00A6', '\\u00A6', '+', '+', '\\u00A2', '\\u00A5', '+', '+', '-', '-', '+', '-', '+', '\\u00E3',\n            '\\u00C3', '+', '+', '-', '-', '\\u00A6', '-', '+', '\\u00A4', '\\u00F0', '\\u00D0', '\\u00CA', '\\u00CB', '\\u00C8', 'i', '\\u00CD', '\\u00CE',\n            '\\u00CF', '+', '+', '_', '_', '\\u00A6', '\\u00CC', '_', '\\u00D3', '\\u00DF', '\\u00D4', '\\u00D2', '\\u00F5', '\\u00D5', '\\u00B5', '\\u00FE',\n            '\\u00DE', '\\u00DA', '\\u00DB', '\\u00D9', '\\u00FD', '\\u00DD', '\\u00AF', '\\u00B4', '\\u00AD', '\\u00B1', '_', '\\u00BE', '\\u00B6', '\\u00A7',\n            '\\u00F7', '\\u00B8', '\\u00B0', '\\u00A8', '\\u00B7', '\\u00B9', '\\u00B3', '\\u00B2', '_', ' '];\n        for (i = 0; i < str.length; i++) {\n            charCode = str.charCodeAt(i) & 0xFF;\n            if (charCode > 127)\n                out += extendedASCII[charCode - 128];\n            else\n                out += String.fromCharCode(charCode);\n        }\n        return out;\n    }\n\n    function decodeUTF8(string) {\n        return decodeURIComponent(escape(string));\n    }\n\n    function getString(bytes) {\n        var i, str = \"\";\n        for (i = 0; i < bytes.length; i++)\n            str += String.fromCharCode(bytes[i]);\n        return str;\n    }\n\n    function getDate(timeRaw) {\n        var date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff;\n        try {\n            return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5,\n                (time & 0x001F) * 2, 0);\n        } catch (e) {\n        }\n    }\n\n    function readCommonHeader(entry, data, index, centralDirectory, onerror) {\n        entry.version = data.view.getUint16(index, true);\n        entry.bitFlag = data.view.getUint16(index + 2, true);\n        entry.compressionMethod = data.view.getUint16(index + 4, true);\n        entry.lastModDateRaw = data.view.getUint32(index + 6, true);\n        entry.lastModDate = getDate(entry.lastModDateRaw);\n        if ((entry.bitFlag & 0x01) === 0x01) {\n            onerror(ERR_ENCRYPTED);\n            return;\n        }\n        if (centralDirectory || (entry.bitFlag & 0x0008) != 0x0008) {\n            entry.crc32 = data.view.getUint32(index + 10, true);\n            entry.compressedSize = data.view.getUint32(index + 14, true);\n            entry.uncompressedSize = data.view.getUint32(index + 18, true);\n        }\n        if (entry.compressedSize === 0xFFFFFFFF || entry.uncompressedSize === 0xFFFFFFFF) {\n            onerror(ERR_ZIP64);\n            return;\n        }\n        entry.filenameLength = data.view.getUint16(index + 22, true);\n        entry.extraFieldLength = data.view.getUint16(index + 24, true);\n    }\n\n    function createZipReader(reader, callback, onerror) {\n        var inflateSN = 0;\n\n        function Entry() {\n        }\n\n        Entry.prototype.getData = function (writer, onend, onprogress, checkCrc32) {\n            var that = this;\n\n            function testCrc32(crc32) {\n                var dataCrc32 = getDataHelper(4);\n                dataCrc32.view.setUint32(0, crc32);\n                return that.crc32 == dataCrc32.view.getUint32(0);\n            }\n\n            function getWriterData(uncompressedSize, crc32) {\n                if (checkCrc32 && !testCrc32(crc32))\n                    onerror(ERR_CRC);\n                else\n                    writer.getData(function (data) {\n                        onend(data);\n                    });\n            }\n\n            function onreaderror(err) {\n                onerror(err || ERR_READ_DATA);\n            }\n\n            function onwriteerror(err) {\n                onerror(err || ERR_WRITE_DATA);\n            }\n\n            reader.readUint8Array(that.offset, 30, function (bytes) {\n                var data = getDataHelper(bytes.length, bytes), dataOffset;\n                if (data.view.getUint32(0) != 0x504b0304) {\n                    onerror(ERR_BAD_FORMAT);\n                    return;\n                }\n                readCommonHeader(that, data, 4, false, onerror);\n                dataOffset = that.offset + 30 + that.filenameLength + that.extraFieldLength;\n                writer.init(function () {\n                    if (that.compressionMethod === 0)\n                        copy(that._worker, inflateSN++, reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror);\n                    else\n                        inflate(that._worker, inflateSN++, reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror);\n                }, onwriteerror);\n            }, onreaderror);\n        };\n\n        function seekEOCDR(eocdrCallback) {\n            // \"End of central directory record\" is the last part of a zip archive, and is at least 22 bytes long.\n            // Zip file comment is the last part of EOCDR and has max length of 64KB,\n            // so we only have to search the last 64K + 22 bytes of a archive for EOCDR signature (0x06054b50).\n            var EOCDR_MIN = 22;\n            if (reader.size < EOCDR_MIN) {\n                onerror(ERR_BAD_FORMAT);\n                return;\n            }\n            var ZIP_COMMENT_MAX = 256 * 256, EOCDR_MAX = EOCDR_MIN + ZIP_COMMENT_MAX;\n\n            // In most cases, the EOCDR is EOCDR_MIN bytes long\n            doSeek(EOCDR_MIN, function () {\n                // If not found, try within EOCDR_MAX bytes\n                doSeek(Math.min(EOCDR_MAX, reader.size), function () {\n                    onerror(ERR_BAD_FORMAT);\n                });\n            });\n\n            // seek last length bytes of file for EOCDR\n            function doSeek(length, eocdrNotFoundCallback) {\n                reader.readUint8Array(reader.size - length, length, function (bytes) {\n                    for (var i = bytes.length - EOCDR_MIN; i >= 0; i--) {\n                        if (bytes[i] === 0x50 && bytes[i + 1] === 0x4b && bytes[i + 2] === 0x05 && bytes[i + 3] === 0x06) {\n                            eocdrCallback(new DataView(bytes.buffer, i, EOCDR_MIN));\n                            return;\n                        }\n                    }\n                    eocdrNotFoundCallback();\n                }, function () {\n                    onerror(ERR_READ);\n                });\n            }\n        }\n\n        var zipReader = {\n            getEntries: function (callback) {\n                var worker = this._worker;\n                // look for End of central directory record\n                seekEOCDR(function (dataView) {\n                    var datalength, fileslength;\n                    datalength = dataView.getUint32(16, true);\n                    fileslength = dataView.getUint16(8, true);\n                    if (datalength < 0 || datalength >= reader.size) {\n                        onerror(ERR_BAD_FORMAT);\n                        return;\n                    }\n                    reader.readUint8Array(datalength, reader.size - datalength, function (bytes) {\n                        var i, index = 0, entries = [], entry, filename, comment, data = getDataHelper(bytes.length, bytes);\n                        for (i = 0; i < fileslength; i++) {\n                            entry = new Entry();\n                            entry._worker = worker;\n                            if (data.view.getUint32(index) != 0x504b0102) {\n                                onerror(ERR_BAD_FORMAT);\n                                return;\n                            }\n                            readCommonHeader(entry, data, index + 6, true, onerror);\n                            entry.commentLength = data.view.getUint16(index + 32, true);\n                            entry.directory = ((data.view.getUint8(index + 38) & 0x10) == 0x10);\n                            entry.offset = data.view.getUint32(index + 42, true);\n                            filename = getString(data.array.subarray(index + 46, index + 46 + entry.filenameLength));\n                            entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename);\n                            if (!entry.directory && entry.filename.charAt(entry.filename.length - 1) == \"/\")\n                                entry.directory = true;\n                            comment = getString(data.array.subarray(index + 46 + entry.filenameLength + entry.extraFieldLength, index + 46\n                                + entry.filenameLength + entry.extraFieldLength + entry.commentLength));\n                            entry.comment = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(comment) : decodeASCII(comment);\n                            entries.push(entry);\n                            index += 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength;\n                        }\n                        callback(entries);\n                    }, function () {\n                        onerror(ERR_READ);\n                    });\n                });\n            },\n            close: function (callback) {\n                if (this._worker) {\n                    this._worker.terminate();\n                    this._worker = null;\n                }\n                if (callback)\n                    callback();\n            },\n            _worker: null\n        };\n\n        if (!obj.zip.useWebWorkers)\n            callback(zipReader);\n        else {\n            createWorker('inflater',\n                function (worker) {\n                    zipReader._worker = worker;\n                    callback(zipReader);\n                },\n                function (err) {\n                    onerror(err);\n                }\n            );\n        }\n    }\n\n    // ZipWriter\n\n    function encodeUTF8(string) {\n        return unescape(encodeURIComponent(string));\n    }\n\n    function getBytes(str) {\n        var i, array = [];\n        for (i = 0; i < str.length; i++)\n            array.push(str.charCodeAt(i));\n        return array;\n    }\n\n    function createZipWriter(writer, callback, onerror, dontDeflate) {\n        var files = {}, filenames = [], datalength = 0;\n        var deflateSN = 0;\n\n        function onwriteerror(err) {\n            onerror(err || ERR_WRITE);\n        }\n\n        function onreaderror(err) {\n            onerror(err || ERR_READ_DATA);\n        }\n\n        var zipWriter = {\n            add: function (name, reader, onend, onprogress, options) {\n                var header, filename, date;\n                var worker = this._worker;\n\n                function writeHeader(callback) {\n                    var data;\n                    date = options.lastModDate || new Date();\n                    header = getDataHelper(26);\n                    files[name] = {\n                        headerArray: header.array,\n                        directory: options.directory,\n                        filename: filename,\n                        offset: datalength,\n                        comment: getBytes(encodeUTF8(options.comment || \"\"))\n                    };\n                    header.view.setUint32(0, 0x14000808);\n                    if (options.version)\n                        header.view.setUint8(0, options.version);\n                    if (!dontDeflate && options.level !== 0 && !options.directory)\n                        header.view.setUint16(4, 0x0800);\n                    header.view.setUint16(6, (((date.getHours() << 6) | date.getMinutes()) << 5) | date.getSeconds() / 2, true);\n                    header.view.setUint16(8, ((((date.getFullYear() - 1980) << 4) | (date.getMonth() + 1)) << 5) | date.getDate(), true);\n                    header.view.setUint16(22, filename.length, true);\n                    data = getDataHelper(30 + filename.length);\n                    data.view.setUint32(0, 0x504b0304);\n                    data.array.set(header.array, 4);\n                    data.array.set(filename, 30);\n                    datalength += data.array.length;\n                    writer.writeUint8Array(data.array, callback, onwriteerror);\n                }\n\n                function writeFooter(compressedLength, crc32) {\n                    var footer = getDataHelper(16);\n                    datalength += compressedLength || 0;\n                    footer.view.setUint32(0, 0x504b0708);\n                    if (typeof crc32 != \"undefined\") {\n                        header.view.setUint32(10, crc32, true);\n                        footer.view.setUint32(4, crc32, true);\n                    }\n                    if (reader) {\n                        footer.view.setUint32(8, compressedLength, true);\n                        header.view.setUint32(14, compressedLength, true);\n                        footer.view.setUint32(12, reader.size, true);\n                        header.view.setUint32(18, reader.size, true);\n                    }\n                    writer.writeUint8Array(footer.array, function () {\n                        datalength += 16;\n                        onend();\n                    }, onwriteerror);\n                }\n\n                function writeFile() {\n                    options = options || {};\n                    name = name.trim();\n                    if (options.directory && name.charAt(name.length - 1) != \"/\")\n                        name += \"/\";\n                    if (files.hasOwnProperty(name)) {\n                        onerror(ERR_DUPLICATED_NAME);\n                        return;\n                    }\n                    filename = getBytes(encodeUTF8(name));\n                    filenames.push(name);\n                    writeHeader(function () {\n                        if (reader)\n                            if (dontDeflate || options.level === 0)\n                                copy(worker, deflateSN++, reader, writer, 0, reader.size, true, writeFooter, onprogress, onreaderror, onwriteerror);\n                            else\n                                deflate(worker, deflateSN++, reader, writer, options.level, writeFooter, onprogress, onreaderror, onwriteerror);\n                        else\n                            writeFooter();\n                    });\n                }\n\n                if (reader)\n                    reader.init(writeFile, onreaderror);\n                else\n                    writeFile();\n            },\n            close: function (callback) {\n                if (this._worker) {\n                    this._worker.terminate();\n                    this._worker = null;\n                }\n\n                var data, length = 0, index = 0, indexFilename, file;\n                for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) {\n                    file = files[filenames[indexFilename]];\n                    length += 46 + file.filename.length + file.comment.length;\n                }\n                data = getDataHelper(length + 22);\n                for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) {\n                    file = files[filenames[indexFilename]];\n                    data.view.setUint32(index, 0x504b0102);\n                    data.view.setUint16(index + 4, 0x1400);\n                    data.array.set(file.headerArray, index + 6);\n                    data.view.setUint16(index + 32, file.comment.length, true);\n                    if (file.directory)\n                        data.view.setUint8(index + 38, 0x10);\n                    data.view.setUint32(index + 42, file.offset, true);\n                    data.array.set(file.filename, index + 46);\n                    data.array.set(file.comment, index + 46 + file.filename.length);\n                    index += 46 + file.filename.length + file.comment.length;\n                }\n                data.view.setUint32(index, 0x504b0506);\n                data.view.setUint16(index + 8, filenames.length, true);\n                data.view.setUint16(index + 10, filenames.length, true);\n                data.view.setUint32(index + 12, length, true);\n                data.view.setUint32(index + 16, datalength, true);\n                writer.writeUint8Array(data.array, function () {\n                    writer.getData(callback);\n                }, onwriteerror);\n            },\n            _worker: null\n        };\n\n        if (!obj.zip.useWebWorkers)\n            callback(zipWriter);\n        else {\n            createWorker('deflater',\n                function (worker) {\n                    zipWriter._worker = worker;\n                    callback(zipWriter);\n                },\n                function (err) {\n                    onerror(err);\n                }\n            );\n        }\n    }\n\n    function resolveURLs(urls) {\n        var a = document.createElement('a');\n        return urls.map(function (url) {\n            a.href = url;\n            return a.href;\n        });\n    }\n\n    var DEFAULT_WORKER_SCRIPTS = {\n        deflater: ['z-worker.js', 'deflate.js'],\n        inflater: ['z-worker.js', 'inflate.js']\n    };\n\n    function createWorker(type, callback, onerror) {\n        if (obj.zip.workerScripts !== null && obj.zip.workerScriptsPath !== null) {\n            onerror(new Error('Either zip.workerScripts or zip.workerScriptsPath may be set, not both.'));\n            return;\n        }\n        var scripts;\n        if (obj.zip.workerScripts) {\n            scripts = obj.zip.workerScripts[type];\n            if (!Array.isArray(scripts)) {\n                onerror(new Error('zip.workerScripts.' + type + ' is not an array!'));\n                return;\n            }\n            scripts = resolveURLs(scripts);\n        } else {\n            scripts = DEFAULT_WORKER_SCRIPTS[type].slice(0);\n            scripts[0] = (obj.zip.workerScriptsPath || '') + scripts[0];\n        }\n        var worker = new Worker(scripts[0]);\n        // record total consumed time by inflater/deflater/crc32 in this worker\n        worker.codecTime = worker.crcTime = 0;\n        worker.postMessage({type: 'importScripts', scripts: scripts.slice(1)});\n        worker.addEventListener('message', onmessage);\n        function onmessage(ev) {\n            var msg = ev.data;\n            if (msg.error) {\n                worker.terminate(); // should before onerror(), because onerror() may throw.\n                onerror(msg.error);\n                return;\n            }\n            if (msg.type === 'importScripts') {\n                worker.removeEventListener('message', onmessage);\n                worker.removeEventListener('error', errorHandler);\n                callback(worker);\n            }\n        }\n\n        // catch entry script loading error and other unhandled errors\n        worker.addEventListener('error', errorHandler);\n        function errorHandler(err) {\n            worker.terminate();\n            onerror(err);\n        }\n    }\n\n    function onerror_default(error) {\n        console.error(error);\n    }\n\n    obj.zip = {\n        Reader: Reader,\n        Writer: Writer,\n        BlobReader: BlobReader,\n        Data64URIReader: Data64URIReader,\n        TextReader: TextReader,\n        BlobWriter: BlobWriter,\n        Data64URIWriter: Data64URIWriter,\n        TextWriter: TextWriter,\n        createReader: function (reader, callback, onerror) {\n            onerror = onerror || onerror_default;\n\n            reader.init(function () {\n                createZipReader(reader, callback, onerror);\n            }, onerror);\n        },\n        createWriter: function (writer, callback, onerror, dontDeflate) {\n            onerror = onerror || onerror_default;\n            dontDeflate = !!dontDeflate;\n\n            writer.init(function () {\n                createZipWriter(writer, callback, onerror, dontDeflate);\n            }, onerror);\n        },\n        useWebWorkers: true,\n        /**\n         * Directory containing the default worker scripts (z-worker.js, deflate.js, and inflate.js), relative to current base url.\n         * E.g.: zip.workerScripts = './';\n         */\n        workerScriptsPath: null,\n        /**\n         * Advanced option to control which scripts are loaded in the Web worker. If this option is specified, then workerScriptsPath must not be set.\n         * workerScripts.deflater/workerScripts.inflater should be arrays of urls to scripts for deflater/inflater, respectively.\n         * Scripts in the array are executed in order, and the first one should be z-worker.js, which is used to start the worker.\n         * All urls are relative to current base url.\n         * E.g.:\n         * zip.workerScripts = {\n\t\t *   deflater: ['z-worker.js', 'deflate.js'],\n\t\t *   inflater: ['z-worker.js', 'inflate.js']\n\t\t * };\n         */\n        workerScripts: null,\n    };\n\n})(zipLib);\n\n/*\n Copyright (c) 2013 Gildas Lormeau. All rights reserved.\n\n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n this list of conditions and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in\n the documentation and/or other materials provided with the distribution.\n\n 3. The names of the authors may not be used to endorse or promote products\n derived from this software without specific prior written permission.\n\n THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\n INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\n FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,\n INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,\n INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * @private\n */\nconst zipExt = function(zipObj) {\n\n\tvar ERR_HTTP_RANGE = \"HTTP Range not supported.\";\n\n\tvar Reader = zipObj.Reader;\n\tvar Writer = zipObj.Writer;\n\n\tvar ZipDirectoryEntry;\n\n\tvar appendABViewSupported;\n\ttry {\n\t\tappendABViewSupported = new Blob([new DataView(new ArrayBuffer(0))]).size === 0;\n\t} catch (e) {\n\t}\n\n\tfunction isHttpFamily(url) {\n\t\tvar a = document.createElement(\"a\");\n\t\ta.href = url;\n\t\treturn a.protocol === \"http:\" || a.protocol === \"https:\";\n\t}\n\n\tfunction HttpReader(url) {\n\t\tvar that = this;\n\n\t\tfunction getData(callback, onerror) {\n\t\t\tvar request;\n\t\t\tif (!that.data) {\n\t\t\t\trequest = new XMLHttpRequest();\n\t\t\t\trequest.addEventListener(\"load\", function () {\n\t\t\t\t\tif (!that.size)\n\t\t\t\t\t\tthat.size = Number(request.getResponseHeader(\"Content-Length\")) || Number(request.response.byteLength);\n\t\t\t\t\tthat.data = new Uint8Array(request.response);\n\t\t\t\t\tcallback();\n\t\t\t\t}, false);\n\t\t\t\trequest.addEventListener(\"error\", onerror, false);\n\t\t\t\trequest.open(\"GET\", url);\n\t\t\t\trequest.responseType = \"arraybuffer\";\n\t\t\t\trequest.send();\n\t\t\t} else\n\t\t\t\tcallback();\n\t\t}\n\n\t\tfunction init(callback, onerror) {\n\t\t\tif (!isHttpFamily(url)) {\n\t\t\t\t// For schemas other than http(s), HTTP HEAD may be unavailable,\n\t\t\t\t// so use HTTP GET instead.\n\t\t\t\tgetData(callback, onerror);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar request = new XMLHttpRequest();\n\t\t\trequest.addEventListener(\"load\", function () {\n\t\t\t\tthat.size = Number(request.getResponseHeader(\"Content-Length\"));\n\t\t\t\t// If response header doesn't return size then prefetch the content.\n\t\t\t\tif (!that.size) {\n\t\t\t\t\tgetData(callback, onerror);\n\t\t\t\t} else {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}, false);\n\t\t\trequest.addEventListener(\"error\", onerror, false);\n\t\t\trequest.open(\"HEAD\", url);\n\t\t\trequest.send();\n\t\t}\n\n\t\tfunction readUint8Array(index, length, callback, onerror) {\n\t\t\tgetData(function () {\n\t\t\t\tcallback(new Uint8Array(that.data.subarray(index, index + length)));\n\t\t\t}, onerror);\n\t\t}\n\n\t\tthat.size = 0;\n\t\tthat.init = init;\n\t\tthat.readUint8Array = readUint8Array;\n\t}\n\n\tHttpReader.prototype = new Reader();\n\tHttpReader.prototype.constructor = HttpReader;\n\n\tfunction HttpRangeReader(url) {\n\t\tvar that = this;\n\n\t\tfunction init(callback, onerror) {\n\t\t\tvar request = new XMLHttpRequest();\n\t\t\trequest.addEventListener(\"load\", function () {\n\t\t\t\tthat.size = Number(request.getResponseHeader(\"Content-Length\"));\n\t\t\t\tif (request.getResponseHeader(\"Accept-Ranges\") == \"bytes\")\n\t\t\t\t\tcallback();\n\t\t\t\telse\n\t\t\t\t\tonerror(ERR_HTTP_RANGE);\n\t\t\t}, false);\n\t\t\trequest.addEventListener(\"error\", onerror, false);\n\t\t\trequest.open(\"HEAD\", url);\n\t\t\trequest.send();\n\t\t}\n\n\t\tfunction readArrayBuffer(index, length, callback, onerror) {\n\t\t\tvar request = new XMLHttpRequest();\n\t\t\trequest.open(\"GET\", url);\n\t\t\trequest.responseType = \"arraybuffer\";\n\t\t\trequest.setRequestHeader(\"Range\", \"bytes=\" + index + \"-\" + (index + length - 1));\n\t\t\trequest.addEventListener(\"load\", function () {\n\t\t\t\tcallback(request.response);\n\t\t\t}, false);\n\t\t\trequest.addEventListener(\"error\", onerror, false);\n\t\t\trequest.send();\n\t\t}\n\n\t\tfunction readUint8Array(index, length, callback, onerror) {\n\t\t\treadArrayBuffer(index, length, function (arraybuffer) {\n\t\t\t\tcallback(new Uint8Array(arraybuffer));\n\t\t\t}, onerror);\n\t\t}\n\n\t\tthat.size = 0;\n\t\tthat.init = init;\n\t\tthat.readUint8Array = readUint8Array;\n\t}\n\n\tHttpRangeReader.prototype = new Reader();\n\tHttpRangeReader.prototype.constructor = HttpRangeReader;\n\n\tfunction ArrayBufferReader(arrayBuffer) {\n\t\tvar that = this;\n\n\t\tfunction init(callback, onerror) {\n\t\t\tthat.size = arrayBuffer.byteLength;\n\t\t\tcallback();\n\t\t}\n\n\t\tfunction readUint8Array(index, length, callback, onerror) {\n\t\t\tcallback(new Uint8Array(arrayBuffer.slice(index, index + length)));\n\t\t}\n\n\t\tthat.size = 0;\n\t\tthat.init = init;\n\t\tthat.readUint8Array = readUint8Array;\n\t}\n\n\tArrayBufferReader.prototype = new Reader();\n\tArrayBufferReader.prototype.constructor = ArrayBufferReader;\n\n\tfunction ArrayBufferWriter() {\n\t\tvar array, that = this;\n\n\t\tfunction init(callback, onerror) {\n\t\t\tarray = new Uint8Array();\n\t\t\tcallback();\n\t\t}\n\n\t\tfunction writeUint8Array(arr, callback, onerror) {\n\t\t\tvar tmpArray = new Uint8Array(array.length + arr.length);\n\t\t\ttmpArray.set(array);\n\t\t\ttmpArray.set(arr, array.length);\n\t\t\tarray = tmpArray;\n\t\t\tcallback();\n\t\t}\n\n\t\tfunction getData(callback) {\n\t\t\tcallback(array.buffer);\n\t\t}\n\n\t\tthat.init = init;\n\t\tthat.writeUint8Array = writeUint8Array;\n\t\tthat.getData = getData;\n\t}\n\n\tArrayBufferWriter.prototype = new Writer();\n\tArrayBufferWriter.prototype.constructor = ArrayBufferWriter;\n\n\tfunction FileWriter(fileEntry, contentType) {\n\t\tvar writer, that = this;\n\n\t\tfunction init(callback, onerror) {\n\t\t\tfileEntry.createWriter(function (fileWriter) {\n\t\t\t\twriter = fileWriter;\n\t\t\t\tcallback();\n\t\t\t}, onerror);\n\t\t}\n\n\t\tfunction writeUint8Array(array, callback, onerror) {\n\t\t\tvar blob = new Blob([appendABViewSupported ? array : array.buffer], {\n\t\t\t\ttype: contentType\n\t\t\t});\n\t\t\twriter.onwrite = function () {\n\t\t\t\twriter.onwrite = null;\n\t\t\t\tcallback();\n\t\t\t};\n\t\t\twriter.onerror = onerror;\n\t\t\twriter.write(blob);\n\t\t}\n\n\t\tfunction getData(callback) {\n\t\t\tfileEntry.file(callback);\n\t\t}\n\n\t\tthat.init = init;\n\t\tthat.writeUint8Array = writeUint8Array;\n\t\tthat.getData = getData;\n\t}\n\n\tFileWriter.prototype = new Writer();\n\tFileWriter.prototype.constructor = FileWriter;\n\n\tzipObj.FileWriter = FileWriter;\n\tzipObj.HttpReader = HttpReader;\n\tzipObj.HttpRangeReader = HttpRangeReader;\n\tzipObj.ArrayBufferReader = ArrayBufferReader;\n\tzipObj.ArrayBufferWriter = ArrayBufferWriter;\n\n\tif (zipObj.fs) {\n\t\tZipDirectoryEntry = zipObj.fs.ZipDirectoryEntry;\n\t\tZipDirectoryEntry.prototype.addHttpContent = function (name, URL, useRangeHeader) {\n\t\t\tfunction addChild(parent, name, params, directory) {\n\t\t\t\tif (parent.directory)\n\t\t\t\t\treturn directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new zipObj.fs.ZipFileEntry(parent.fs, name, params, parent);\n\t\t\t\telse\n\t\t\t\t\tthrow \"Parent entry is not a directory.\";\n\t\t\t}\n\n\t\t\treturn addChild(this, name, {\n\t\t\t\tdata: URL,\n\t\t\t\tReader: useRangeHeader ? HttpRangeReader : HttpReader\n\t\t\t});\n\t\t};\n\t\tZipDirectoryEntry.prototype.importHttpContent = function (URL, useRangeHeader, onend, onerror) {\n\t\t\tthis.importZip(useRangeHeader ? new HttpRangeReader(URL) : new HttpReader(URL), onend, onerror);\n\t\t};\n\t\tzipObj.fs.FS.prototype.importHttpContent = function (URL, useRangeHeader, onend, onerror) {\n\t\t\tthis.entries = [];\n\t\t\tthis.root = new ZipDirectoryEntry(this);\n\t\t\tthis.root.importHttpContent(URL, useRangeHeader, onend, onerror);\n\t\t};\n\t}\n};\n\nconst zip = zipLib.zip;\nzipExt(zip);\n\nconst supportedSchemas = [\"4.2\"];\n\n/**\n * @private\n */\nclass XML3DSceneGraphLoader {\n\n    constructor(plugin, cfg = {}) {\n\n        /**\n         * Supported 3DXML schema versions\n         * @property supportedSchemas\n         * @type {string[]}\n         */\n        this.supportedSchemas = supportedSchemas;\n\n        this._xrayOpacity = 0.7;\n        this._src = null;\n        this._options = cfg;\n\n        /**\n         * Default viewpoint, containing eye, look and up vectors.\n         * Only defined if found in the 3DXML file.\n         * @property viewpoint\n         * @type {Number[]}\n         */\n        this.viewpoint = null;\n\n        if (!cfg.workerScriptsPath) {\n            plugin.error(\"Config expected: workerScriptsPath\");\n            return\n        }\n        zip.workerScriptsPath = cfg.workerScriptsPath;\n\n        this.src = cfg.src;\n        this.xrayOpacity = 0.7;\n        this.displayEffect = cfg.displayEffect;\n        this.createMetaModel = cfg.createMetaModel;\n    }\n\n    load(plugin, modelNode, src, options, ok, error) {\n\n        switch (options.materialType) {\n            case \"MetallicMaterial\":\n                modelNode._defaultMaterial = new MetallicMaterial(modelNode, {\n                    baseColor: [1, 1, 1],\n                    metallic: 0.6,\n                    roughness: 0.6\n                });\n                break;\n\n            case \"SpecularMaterial\":\n                modelNode._defaultMaterial = new SpecularMaterial(modelNode, {\n                    diffuse: [1, 1, 1],\n                    specular: math.vec3([1.0, 1.0, 1.0]),\n                    glossiness: 0.5\n                });\n                break;\n\n            default:\n                modelNode._defaultMaterial = new PhongMaterial(modelNode, {\n                    reflectivity: 0.75,\n                    shiness: 100,\n                    diffuse: [1, 1, 1]\n                });\n        }\n\n        modelNode._wireframeMaterial = new LambertMaterial(modelNode, {\n            color: [0, 0, 0],\n            lineWidth: 2\n        });\n\n        var spinner = modelNode.scene.canvas.spinner;\n        spinner.processes++;\n\n        load3DXML(plugin, modelNode, src, options, function () {\n                spinner.processes--;\n                if (ok) {\n                    ok();\n                }\n                modelNode.fire(\"loaded\", true, false);\n            },\n            function (msg) {\n                spinner.processes--;\n                modelNode.error(msg);\n                if (error) {\n                    error(msg);\n                }\n                /**\n                 Fired whenever this XML3D fails to load the 3DXML file\n                 specified by {@link XML3D/src}.\n                 @event error\n                 @param msg {String} Description of the error\n                 */\n                modelNode.fire(\"error\", msg);\n            },\n            function (err) {\n                console.log(\"Error, Will Robinson: \" + err);\n            });\n    }\n}\n\nvar load3DXML = (function () {\n    return function (plugin, modelNode, src, options, ok, error) {\n        loadZIP(src, function (zip) { // OK\n                parse3DXML(plugin, zip, options, modelNode, ok, error);\n            },\n            error);\n    };\n})();\n\nvar parse3DXML = (function () {\n    return function (plugin, zip, options, modelNode, ok) {\n        var ctx = {\n            plugin: plugin,\n            zip: zip,\n            edgeThreshold: 30, // Guess at degrees of normal deviation between adjacent tris below which we remove edge between them\n            materialType: options.materialType,\n            scene: modelNode.scene,\n            modelNode: modelNode,\n            info: {\n                references: {}\n            },\n            materials: {}\n        };\n\n        if (options.createMetaModel) {\n            ctx.metaModelData = {\n                modelId: modelNode.id,\n                metaObjects: [{\n                    name: modelNode.id,\n                    type: \"Default\",\n                    id: modelNode.id\n                }]\n            };\n        }\n        modelNode.scene.loading++; // Disables (re)compilation\n\n        parseDocument(ctx, function () {\n            if (ctx.metaModelData) {\n                plugin.viewer.metaScene.createMetaModel(modelNode.id, ctx.metaModelData);\n            }\n            modelNode.scene.loading--; // Re-enables (re)compilation\n            ok();\n        });\n    };\n\n    function parseDocument(ctx, ok) {\n        ctx.zip.getFile(\"Manifest.xml\", function (xmlDoc, json) {\n            var node = json;\n            var children = node.children;\n            for (var i = 0, len = children.length; i < len; i++) {\n                var child = children[i];\n                switch (child.type) {\n                    case \"Manifest\":\n                        parseManifest(ctx, child, ok);\n                        break;\n                }\n            }\n        });\n    }\n\n    function parseManifest(ctx, manifest, ok) {\n        var children = manifest.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"Root\":\n                    var rootFileSrc = child.children[0];\n                    ctx.zip.getFile(rootFileSrc, function (xmlDoc, json) {\n                        parseRoot(ctx, json, ok);\n                    });\n                    break;\n            }\n        }\n    }\n\n    function parseRoot(ctx, node, ok) {\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"Model_3dxml\":\n                    parseModel(ctx, child, ok);\n                    break;\n            }\n        }\n    }\n\n    function parseModel(ctx, node, ok) {\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"Header\":\n                    parseHeader(ctx, child);\n                    break;\n                case \"ProductStructure\":\n                    parseProductStructure(ctx, child, ok);\n                    break;\n                case \"DefaultView\":\n                    parseDefaultView(ctx, child);\n                    break;\n            }\n        }\n    }\n\n    function parseHeader(ctx, node) {\n        var children = node.children;\n        var metaData = {};\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"SchemaVersion\":\n                    metaData.schemaVersion = child.children[0];\n                    if (!isSchemaVersionSupported(ctx, metaData.schemaVersion)) {\n                        ctx.plugin.error(\"Schema version not supported: \" + metaData.schemaVersion + \" - supported versions are: \" + supportedSchemas.join(\",\"));\n                    }\n                    break;\n                case \"Title\":\n                    metaData.title = child.children[0];\n                    break;\n                case \"Author\":\n                    metaData.author = child.children[0];\n                    break;\n                case \"Created\":\n                    metaData.created = child.children[0];\n                    break;\n            }\n        }\n        ctx.modelNode.meta = metaData;\n    }\n\n    function isSchemaVersionSupported(ctx, schemaVersion) {\n        for (var i = 0, len = supportedSchemas.length; i < len; i++) {\n            if (schemaVersion === supportedSchemas[i]) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    function parseProductStructure(ctx, productStructureNode, ok) {\n\n        parseReferenceReps(ctx, productStructureNode, function (referenceReps) {\n\n            // Parse out an intermediate scene DAG representation, that we can then\n            // recursive descend through to build a xeokit Object hierarchy.\n\n            var children = productStructureNode.children;\n\n            var reference3Ds = {};\n            var instanceReps = {};\n            var instance3Ds = {};\n\n            // Map all the elements\n\n            for (var i = 0, len = children.length; i < len; i++) {\n                var child = children[i];\n                switch (child.type) {\n\n                    case \"Reference3D\":\n                        reference3Ds[child.id] = {\n                            type: \"Reference3D\",\n                            id: child.id,\n                            name: child.name,\n                            instance3Ds: {},\n                            instanceReps: {}\n                        };\n                        break;\n\n                    case \"InstanceRep\":\n                        var isAggregatedBy;\n                        var isInstanceOf;\n                        var relativeMatrix;\n                        for (var j = 0, lenj = child.children.length; j < lenj; j++) {\n                            var child2 = child.children[j];\n                            switch (child2.type) {\n                                case \"IsAggregatedBy\":\n                                    isAggregatedBy = child2.children[0];\n                                    break;\n                                case \"IsInstanceOf\":\n                                    isInstanceOf = child2.children[0];\n                                    break;\n                            }\n                        }\n                        instanceReps[child.id] = {\n                            type: \"InstanceRep\",\n                            id: child.id,\n                            name: child.name,\n                            isAggregatedBy: isAggregatedBy,\n                            isInstanceOf: isInstanceOf,\n                            referenceReps: {}\n                        };\n                        break;\n\n                    case \"Instance3D\":\n                        var isAggregatedBy;\n                        var isInstanceOf;\n                        var relativeMatrix;\n                        for (var j = 0, lenj = child.children.length; j < lenj; j++) {\n                            var child2 = child.children[j];\n                            switch (child2.type) {\n                                case \"IsAggregatedBy\":\n                                    isAggregatedBy = child2.children[0];\n                                    break;\n                                case \"IsInstanceOf\":\n                                    isInstanceOf = child2.children[0];\n                                    break;\n                                case \"RelativeMatrix\":\n                                    relativeMatrix = child2.children[0];\n                                    break;\n                            }\n                        }\n                        instance3Ds[child.id] = {\n                            type: \"Instance3D\",\n                            id: child.id,\n                            name: child.name,\n                            isAggregatedBy: isAggregatedBy,\n                            isInstanceOf: isInstanceOf,\n                            relativeMatrix: relativeMatrix,\n                            reference3Ds: {}\n                        };\n                        break;\n                }\n            }\n\n            // Connect Reference3Ds to the Instance3Ds they aggregate\n\n            for (var id in instance3Ds) {\n                var instance3D = instance3Ds[id];\n                var reference3D = reference3Ds[instance3D.isAggregatedBy];\n                if (reference3D) {\n                    reference3D.instance3Ds[instance3D.id] = instance3D;\n                } else {\n                    alert(\"foo\");\n                }\n            }\n\n            // Connect Instance3Ds to the Reference3Ds they instantiate\n\n            for (var id in instance3Ds) {\n                var instance3D = instance3Ds[id];\n                var reference3D = reference3Ds[instance3D.isInstanceOf];\n                instance3D.reference3Ds[reference3D.id] = reference3D;\n                reference3D.instance3D = instance3D;\n            }\n\n            // Connect InstanceReps to the ReferenceReps they instantiate\n\n            for (var id in instanceReps) {\n                var instanceRep = instanceReps[id];\n                var referenceRep = referenceReps[instanceRep.isInstanceOf];\n                if (referenceRep) {\n                    instanceRep.referenceReps[referenceRep.id] = referenceRep;\n                }\n            }\n\n            // Connect Reference3Ds to the InstanceReps they aggregate\n\n            for (var id in instanceReps) {\n                var instanceRep = instanceReps[id];\n                var reference3D = reference3Ds[instanceRep.isAggregatedBy];\n                if (reference3D) {\n                    reference3D.instanceReps[instanceRep.id] = instanceRep;\n                }\n            }\n\n            function parseReference3D(ctx, reference3D, group) {\n                //ctx.plugin.log(\"parseReference3D( \" + reference3D.id + \" )\");\n                for (var id in reference3D.instance3Ds) {\n                    parseInstance3D(ctx, reference3D.instance3Ds[id], group);\n                }\n                for (var id in reference3D.instanceReps) {\n                    parseInstanceRep(ctx, reference3D.instanceReps[id], group);\n                }\n            }\n\n            function parseInstance3D(ctx, instance3D, group) {\n                //ctx.plugin.log(\"parseInstance3D( \" + instance3D.id + \" )\");\n\n                if (instance3D.relativeMatrix) {\n                    var matrix = parseFloatArray(instance3D.relativeMatrix, 12);\n                    var translate = [matrix[9], matrix[10], matrix[11]];\n                    var mat3 = matrix.slice(0, 9); // Rotation matrix\n                    var mat4 = math.mat3ToMat4(mat3, math.identityMat4()); // Convert rotation matrix to 4x4\n                    var childGroup = new Node$1(ctx.modelNode, {\n                        position: translate\n                    });\n                    if (ctx.metaModelData) {\n                        ctx.metaModelData.metaObjects.push({\n                            id: childGroup.id,\n                            type: \"Default\",\n                            name: instance3D.name,\n                            parent: group ? group.id : ctx.modelNode.id\n                        });\n                    }\n                    if (group) {\n                        group.addChild(childGroup, true);\n                    } else {\n                        ctx.modelNode.addChild(childGroup, true);\n                    }\n                    group = childGroup;\n                    childGroup = new Node$1(ctx.modelNode, {\n                        matrix: mat4\n                    });\n                    if (ctx.metaModelData) {\n                        ctx.metaModelData.metaObjects.push({\n                            id: childGroup.id,\n                            type: \"Default\",\n                            name: instance3D.name,\n                            parent: group ? group.id : ctx.modelNode.id\n                        });\n                    }\n                    group.addChild(childGroup, true);\n                    group = childGroup;\n                } else {\n                    var childGroup = new Node$1(ctx.modelNode, {});\n                    if (ctx.metaModelData) {\n                        ctx.metaModelData.metaObjects.push({\n                            id: childGroup.id,\n                            type: \"Default\",\n                            name: instance3D.name,\n                            parent: group ? group.id : ctx.modelNode.id\n                        });\n                    }\n                    if (group) {\n                        group.addChild(childGroup, true);\n                    } else {\n                        ctx.modelNode.addChild(childGroup, true);\n                    }\n                    group = childGroup;\n                }\n                for (var id in instance3D.reference3Ds) {\n                    parseReference3D(ctx, instance3D.reference3Ds[id], group);\n                }\n            }\n\n            function parseInstanceRep(ctx, instanceRep, group) {\n                //ctx.plugin.log(\"parseInstanceRep( \" + instanceRep.id + \" )\");\n                if (instanceRep.referenceReps) {\n                    for (var id in instanceRep.referenceReps) {\n                        var referenceRep = instanceRep.referenceReps[id];\n                        for (var id2 in referenceRep) {\n                            if (id2 === \"id\") {\n                                continue; // HACK\n                            }\n                            var meshCfg = referenceRep[id2];\n                            var lines = meshCfg.geometry.primitive === \"lines\";\n                            var material = lines ? ctx.modelNode._wireframeMaterial : (meshCfg.materialId ? ctx.materials[meshCfg.materialId] : null);\n                            var colorize = meshCfg.color;\n                            var mesh = new Mesh(ctx.modelNode, {\n                                isObject: true,\n                                geometry: meshCfg.geometry,\n                                material: material || ctx.modelNode._defaultMaterial,\n                                colorize: colorize,\n                                backfaces: false\n                            });\n                            if (ctx.metaModelData) {\n                                ctx.metaModelData.metaObjects.push({\n                                    id: mesh.id,\n                                    type: \"Default\",\n                                    name: instanceRep.name,\n                                    parent: group ? group.id : ctx.modelNode.id\n                                });\n                            }\n                            if (group) {\n                                group.addChild(mesh, true);\n                            } else {\n                                ctx.modelNode.addChild(mesh, true);\n                            }\n                            mesh.colorize = colorize; // HACK: Mesh has inherited modelNode's colorize state, so we need to restore it (we'd better not modify colorize on the modelNode).\n                        }\n                    }\n                }\n            }\n\n            // Find the root Reference3D\n\n            for (var id in reference3Ds) {\n                var reference3D = reference3Ds[id];\n                if (!reference3D.instance3D) {\n                    parseReference3D(ctx, reference3D, null); // HACK: Assuming that root has id == \"1\"\n                    ok();\n                    return;\n                }\n            }\n\n            alert(\"No root Reference3D element found in this modelNode - can't load.\");\n\n            ok();\n        });\n    }\n\n    function parseIntArray(str) {\n        var parts = str.trim().split(\" \");\n        var result = new Int32Array(parts.length);\n        for (var i = 0; i < parts.length; i++) {\n            result[i] = parseInt(parts[i]);\n        }\n        return result;\n    }\n\n    function parseReferenceReps(ctx, node, ok) {\n        var referenceReps = {};\n        var children = node.children;\n        var numToLoad = 0;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            if (child.type === \"ReferenceRep\") {\n                numToLoad++;\n            }\n        }\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"ReferenceRep\":\n                    if (child.associatedFile) {\n                        var src = stripURN(child.associatedFile);\n                        (function () {\n                            var childId = child.id;\n                            ctx.zip.getFile(src, function (xmlDoc, json) {\n\n                                    var materialIds = xmlDoc.getElementsByTagName(\"MaterialId\");\n\n                                    loadCATMaterialRefDocuments(ctx, materialIds, function () {\n\n                                        // ctx.plugin.log(\"reference loaded: \" + src);\n                                        var referenceRep = {\n                                            id: childId\n                                        };\n                                        parse3DRepDocument(ctx, json, referenceRep);\n                                        referenceReps[childId] = referenceRep;\n                                        if (--numToLoad === 0) {\n                                            ok(referenceReps);\n                                        }\n                                    });\n                                },\n                                function (error) {\n                                    // TODO:\n                                });\n                        })();\n                    }\n                    break;\n            }\n        }\n    }\n\n\n    function parseDefaultView(ctx, node) {\n        // ctx.plugin.log(\"parseDefaultView\");\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"Viewpoint\":\n                    var children2 = child.children;\n                    ctx.modelNode.viewpoint = {};\n                    for (var i2 = 0, len2 = children2.length; i2 < len2; i2++) {\n                        var child2 = children2[i];\n                        switch (child2.type) {\n                            case \"Position\":\n                                ctx.modelNode.viewpoint.eye = parseFloatArray(child2.children[0], 3);\n                                break;\n                            case \"Sight\":\n                                ctx.modelNode.viewpoint.look = parseFloatArray(child2.children[0], 3);\n                                break;\n                            case \"Up\":\n                                ctx.modelNode.viewpoint.up = parseFloatArray(child2.children[0], 3);\n                                break;\n                        }\n                    }\n                    break;\n            }\n        }\n    }\n\n    function parse3DRepDocument(ctx, node, result) {\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"XMLRepresentation\":\n                    parseXMLRepresentation(ctx, child, result);\n                    break;\n            }\n        }\n    }\n\n    function parseXMLRepresentation(ctx, node, result) {\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"Root\":\n                    parse3DRepRoot(ctx, child, result);\n                    break;\n            }\n        }\n    }\n\n    function parse3DRepRoot(ctx, node, result) {\n        switch (node[\"xsi:type\"]) {\n                    }\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"Rep\":\n                    parse3DRepRep(ctx, child, result);\n                    break;\n            }\n        }\n    }\n\n    function parse3DRepRep(ctx, node, result) {\n        switch (node[\"xsi:type\"]) {\n                    }\n        var meshesResult = {\n            edgeThreshold: ctx.edgeThreshold || 30,\n            compressGeometry: true\n        };\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"Rep\":\n                    parse3DRepRep(ctx, child, result);\n                    break;\n                case \"Edges\":\n                    // Ignoring edges because we auto-generate our own using xeokit\n                    break;\n                case \"Faces\":\n                    meshesResult.primitive = \"triangles\";\n                    parseFaces(ctx, child, meshesResult);\n                    break;\n                case \"VertexBuffer\":\n                    parseVertexBuffer(ctx, child, meshesResult);\n                    break;\n                case \"SurfaceAttributes\":\n                    parseSurfaceAttributes(ctx, child, meshesResult);\n                    break;\n            }\n        }\n        if (meshesResult.positions) {\n            var geometry = new ReadableGeometry(ctx.modelNode, meshesResult);\n            result[geometry.id] = {\n                geometry: geometry,\n                color: meshesResult.color || [1.0, 1.0, 1.0, 1.0],\n                materialId: meshesResult.materialId\n            };\n        }\n    }\n\n    function parseFaces(ctx, node, result) {\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"Face\":\n                    parseFace(ctx, child, result);\n                    break;\n            }\n        }\n    }\n\n    function parseFace(ctx, node, result) {\n        var strips = node.strips;\n        if (strips) {\n            // Triangle strips\n            var arrays = parseIntArrays(strips);\n            if (arrays.length > 0) {\n                result.primitive = \"triangles\";\n                var indices = [];\n                for (var i = 0, len = arrays.length; i < len; i++) {\n                    var array = convertTriangleStrip(arrays[i]);\n                    for (var j = 0, lenj = array.length; j < lenj; j++) {\n                        indices.push(array[j]);\n                    }\n                }\n                result.indices = indices; // TODO\n            }\n        } else {\n            // Triangle meshes\n            var triangles = node.triangles;\n            if (triangles) {\n                result.primitive = \"triangles\";\n                result.indices = parseIntArray(triangles);\n            }\n        }\n        // Material\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"SurfaceAttributes\":\n                    parseSurfaceAttributes(ctx, child, result);\n                    break;\n            }\n        }\n    }\n\n    function convertTriangleStrip(indices) {\n        var indices2 = [];\n        for (var i = 0, len = indices.length; i < len - 2; i++) {\n            {\n                if (i & 1) { //\n                    indices2.push(indices[i]);\n                    indices2.push(indices[i + 2]);\n                    indices2.push(indices[i + 1]);\n                } else {\n                    indices2.push(indices[i]);\n                    indices2.push(indices[i + 1]);\n                    indices2.push(indices[i + 2]);\n                }\n            }\n        }\n        return indices2;\n    }\n\n    function parseVertexBuffer(ctx, node, result) {\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"Positions\":\n                    result.positions = parseFloatArray(child.children[0], 3);\n                    break;\n                case \"Normals\":\n                    result.normals = parseFloatArray(child.children[0], 3);\n                    break;\n                case \"TextureCoordinates\": // TODO: Support dimension and channel?\n                    result.uv = parseFloatArray(child.children[0], 2);\n                    break;\n            }\n        }\n    }\n\n    function parseIntArrays(str) {\n        var coordStrings = str.split(\",\");\n        var array = [];\n        for (var i = 0, len = coordStrings.length; i < len; i++) {\n            var coordStr = coordStrings[i].trim();\n            if (coordStr.length > 0) {\n                var elemStrings = coordStr.trim().split(\" \");\n                var arr = new Int16Array(elemStrings.length);\n                var arrIdx = 0;\n                for (var j = 0, lenj = elemStrings.length; j < lenj; j++) {\n                    if (elemStrings[j] !== \"\") {\n                        arr[arrIdx++] = parseInt(elemStrings[j]);\n                    }\n                }\n                array.push(arr);\n            }\n        }\n        return array;\n    }\n\n    function parseFloatArray(str, numElems) {\n        str = str.split(\",\");\n        var arr = new Float32Array(str.length * numElems);\n        var arrIdx = 0;\n        for (var i = 0, len = str.length; i < len; i++) {\n            var value = str[i];\n            value = value.split(\" \");\n            for (var j = 0, lenj = value.length; j < lenj; j++) {\n                if (value[j] !== \"\") {\n                    arr[arrIdx++] = parseFloat(value[j]);\n                }\n            }\n        }\n        return arr;\n    }\n\n    function parseIntArray(str) {\n        str = str.trim().split(\" \");\n        var arr = new Int32Array(str.length);\n        for (var i = 0, len = str.length; i < len; i++) {\n            var value = str[i];\n            arr[i] = parseInt(value);\n        }\n        return arr;\n    }\n\n    function parseSurfaceAttributes(ctx, node, result) {\n        result.color = [1, 1, 1, 1];\n        var children = node.children;\n        for (var i = 0, len = children.length; i < len; i++) {\n            var child = children[i];\n            switch (child.type) {\n                case \"Color\":\n                    result.color[0] = child.red;\n                    result.color[1] = child.green;\n                    result.color[2] = child.blue;\n                    result.color[3] = child.alpha;\n                    break;\n                case \"MaterialApplication\":\n                    var children2 = child.children;\n                    for (var j = 0, lenj = children2.length; j < lenj; j++) {\n                        var child2 = children2[j];\n                        switch (child2.type) {\n                            case \"MaterialId\":\n                                var materialId = getIDFromURI(child2.id);\n                                var material = ctx.materials[materialId];\n                                if (!material) {\n                                    ctx.plugin.error(\"material  not found: \" + materialId);\n                                }\n                                result.materialId = materialId;\n                                break;\n                        }\n                    }\n                    break;\n            }\n        }\n    }\n})();\n\nfunction loadCATMaterialRefDocuments(ctx, materialIds, ok) {\n    var loaded = {};\n\n    function load(i, done) {\n        if (i >= materialIds.length) {\n            ok();\n            return;\n        }\n        var materialId = materialIds[i];\n        var src = materialId.id;\n        var colonIdx = src.lastIndexOf(\":\");\n        if (colonIdx > 0) {\n            src = src.substring(colonIdx + 1);\n        }\n        var hashIdx = src.lastIndexOf(\"#\");\n        if (hashIdx > 0) {\n            src = src.substring(0, hashIdx);\n        }\n        if (!loaded[src]) {\n            loadCATMaterialRefDocument(ctx, src, function () {\n                loaded[src] = true;\n                load(i + 1);\n            });\n        } else {\n            load(i + 1);\n        }\n    }\n\n    load(0);\n}\n\nfunction loadCATMaterialRefDocument(ctx, src, ok) { // Loads CATMaterialRef.3dxml\n    ctx.zip.getFile(src, function (xmlDoc, json) {\n        parseCATMaterialRefDocument(ctx, json, ok);\n    });\n}\n\nfunction parseCATMaterialRefDocument(ctx, node, ok) { // Parse CATMaterialRef.3dxml\n    // ctx.plugin.log(\"parseCATMaterialRefDocument\");\n    var children = node.children;\n    var child;\n    for (var i = 0, len = children.length; i < len; i++) {\n        child = children[i];\n        if (child.type === \"Model_3dxml\") {\n            parseModel_3dxml(ctx, child, ok);\n        }\n    }\n}\n\nfunction parseModel_3dxml(ctx, node, ok) { // Parse CATMaterialRef.3dxml\n    // ctx.plugin.log(\"parseModel_3dxml\");\n    var children = node.children;\n    var child;\n    for (var i = 0, len = children.length; i < len; i++) {\n        child = children[i];\n        if (child.type === \"CATMaterialRef\") {\n            parseCATMaterialRef(ctx, child, ok);\n        }\n    }\n}\n\nfunction parseCATMaterialRef(ctx, node, ok) {\n    var domainToReferenceMap = {};\n    var children = node.children;\n    var numToLoad = 0;\n    for (var j = 0, lenj = children.length; j < lenj; j++) {\n        var child2 = children[j];\n        switch (child2.type) {\n            case \"MaterialDomainInstance\":\n                var isAggregatedBy;\n                var isInstanceOf;\n                for (var k = 0, lenk = child2.children.length; k < lenk; k++) {\n                    var child3 = child2.children[k];\n                    switch (child3.type) {\n                        case \"IsAggregatedBy\":\n                            isAggregatedBy = child3.children[0];\n                            break;\n                        case \"IsInstanceOf\":\n                            isInstanceOf = child3.children[0];\n                            break;\n                    }\n                }\n                domainToReferenceMap[isInstanceOf] = isAggregatedBy;\n                break;\n        }\n    }\n    for (var j = 0, lenj = children.length; j < lenj; j++) {\n        var child2 = children[j];\n        switch (child2.type) {\n            case \"MaterialDomain\":\n                numToLoad++;\n                break;\n        }\n    }\n    // Now load them\n    for (var j = 0, lenj = children.length; j < lenj; j++) {\n        var child2 = children[j];\n        switch (child2.type) {\n            case \"MaterialDomain\":\n                if (child2.associatedFile) {\n                    (function () {\n                        var childId = child2.id;\n                        var src = stripURN(child2.associatedFile);\n                        ctx.zip.getFile(src, function (xmlDoc, json) {\n                                // ctx.plugin.log(\"Material def loaded: \" + src);\n                                ctx.materials[domainToReferenceMap[childId]] = parseMaterialDefDocument(ctx, json);\n\n                                if (--numToLoad === 0) {\n                                    //       console.log(\"All ReferenceReps loaded.\");\n                                    ok();\n                                }\n                            },\n                            function (error) {\n                                // TODO:\n                            });\n                    })();\n                }\n                break;\n        }\n    }\n}\n\nfunction parseMaterialDefDocument(ctx, node) {\n    var children = node.children;\n    for (var i = 0, len = children.length; i < len; i++) {\n        var child = children[i];\n        switch (child.type) {\n            case \"Osm\":\n                return parseMaterialDefDocumentOsm(ctx, child);\n        }\n    }\n}\n\nfunction parseMaterialDefDocumentOsm(ctx, node) {\n    var children = node.children;\n    for (var i = 0, len = children.length; i < len; i++) {\n        var child = children[i];\n        switch (child.type) {\n            case \"RenderingRootFeature\":\n                //..\n                break;\n            case \"Feature\":\n\n                if (child.Alias === \"RenderingFeature\") {\n                    // Parse the coefficients, then parse the colors, scaling those by their coefficients.\n                    var coeffs = {};\n                    var materialCfg = {};\n                    var children2 = child.children;\n                    var j;\n                    var lenj;\n                    var child2;\n                    for (j = 0, lenj = children2.length; j < lenj; j++) {\n                        child2 = children2[j];\n                        switch (child2.Name) {\n                            case \"AmbientCoef\":\n                                coeffs.ambient = parseFloat(child2.Value);\n                                break;\n                            case \"DiffuseCoef\":\n                                coeffs.diffuse = parseFloat(child2.Value);\n                                break;\n                            case \"EmissiveCoef\":\n                                coeffs.emissive = parseFloat(child2.Value);\n                                break;\n                            case \"SpecularExponent\":\n                                coeffs.specular = parseFloat(child2.Value);\n                                break;\n                        }\n                    }\n                    for (j = 0, lenj = children2.length; j < lenj; j++) {\n                        child2 = children2[j];\n                        switch (child2.Name) {\n                            case \"AmbientColor\":\n                                materialCfg.ambient = parseRGB(child2.Value, coeffs.ambient);\n                                break;\n                            case \"DiffuseColor\":\n                                materialCfg.diffuse = parseRGB(child2.Value, coeffs.diffuse);\n                                break;\n                            case \"EmissiveColor\":\n                                materialCfg.emissive = parseRGB(child2.Value, coeffs.emissive);\n                                break;\n                            case \"SpecularColor\":\n                                materialCfg.specular = parseRGB(child2.Value, coeffs.specular);\n                                break;\n                            case \"Transparency\":\n                                var alpha = 1.0 - parseFloat(child2.Value); // GOTCHA: Degree of transparency, not degree of opacity\n                                if (alpha < 1.0) {\n                                    materialCfg.alpha = alpha;\n                                    materialCfg.alphaMode = \"blend\";\n                                }\n                                break;\n                        }\n                    }\n\n                    var material;\n\n                    switch (ctx.materialType) {\n                        case \"MetallicMaterial\":\n                            material = new MetallicMaterial(ctx.modelNode, {\n                                baseColor: materialCfg.diffuse,\n                                metallic: 0.7,\n                                roughness: 0.5,\n                                emissive: materialCfg.emissive,\n                                alpha: materialCfg.alpha,\n                                alphaMode: materialCfg.alphaMode\n                            });\n                            break;\n\n                        case \"SpecularMaterial\":\n                            material = new SpecularMaterial(ctx.modelNode, {\n                                diffuse: materialCfg.diffuse,\n                                specular: materialCfg.specular,\n                                glossiness: 0.5,\n                                emissive: materialCfg.emissive,\n                                alpha: materialCfg.alpha,\n                                alphaMode: materialCfg.alphaMode\n                            });\n                            break;\n\n                        default:\n                            material = new PhongMaterial(ctx.modelNode, {\n                                reflectivity: 0.5,\n                                ambient: materialCfg.ambient,\n                                diffuse: materialCfg.diffuse,\n                                specular: materialCfg.specular,\n                                // shininess: node.shine,\n                                emissive: materialCfg.emissive,\n                                alphaMode: materialCfg.alphaMode,\n                                alpha: node.alpha\n                            });\n                    }\n                    return material;\n                }\n                break;\n        }\n    }\n}\n\nfunction parseRGB(str, coeff) {\n    coeff = (coeff !== undefined) ? coeff : 0.5;\n    var openBracketIndex = str.indexOf(\"[\");\n    var closeBracketIndex = str.indexOf(\"]\");\n    str = str.substring(openBracketIndex + 1, closeBracketIndex - openBracketIndex);\n    str = str.split(\",\");\n    var arr = new Float32Array(str.length);\n    var arrIdx = 0;\n    for (var i = 0, len = str.length; i < len; i++) {\n        var value = str[i];\n        value = value.trim().split(\" \");\n        for (var j = 0, lenj = value.length; j < lenj; j++) {\n            if (value[j] !== \"\") {\n                arr[arrIdx++] = parseFloat(value[j]) * coeff;\n            }\n        }\n    }\n    return arr;\n}\n\n\n//----------------------------------------------------------------------------------------------------\n\n/**\n * Wraps zip.js to provide an in-memory ZIP archive representing the 3DXML file bundle.\n *\n * Allows us to pluck each file from it as XML and JSON.\n *\n * @constructor\n */\nvar ZIP = function () {\n\n    var reader;\n    var files = {};\n\n    /**\n     Loads this ZIP\n\n     @param src\n     @param ok\n     @param error\n     */\n    this.load = function (src, ok, error) {\n        zip.createReader(new zip.HttpReader(src), function (reader) {\n            reader.getEntries(function (entries) {\n                if (entries.length > 0) {\n                    for (var i = 0, len = entries.length; i < len; i++) {\n                        var entry = entries[i];\n                        files[entry.filename] = entry;\n                    }\n                }\n                ok();\n            });\n        }, error);\n    };\n\n    /**\n     Gets a file as XML and JSON from this ZIP\n     @param src\n     @param ok\n     @param error\n     */\n    this.getFile = function (src, ok, error) {\n        var entry = files[src];\n        if (!entry) {\n            var errMsg = \"ZIP entry not found: \" + src;\n            console.error(errMsg);\n            if (error) {\n                error(errMsg);\n            }\n            return;\n        }\n        entry.getData(new zip.TextWriter(), function (text) {\n\n            // Parse to XML\n            var parser = new DOMParser();\n            var xmlDoc = parser.parseFromString(text, \"text/xml\");\n\n            // Parse to JSON\n            var json = xmlToJSON(xmlDoc, {});\n\n            ok(xmlDoc, json);\n        });\n    };\n\n    function xmlToJSON(node, attributeRenamer) {\n        if (node.nodeType === node.TEXT_NODE) {\n            var v = node.nodeValue;\n            if (v.match(/^\\s+$/) === null) {\n                return v;\n            }\n        } else if (node.nodeType === node.ELEMENT_NODE ||\n            node.nodeType === node.DOCUMENT_NODE) {\n            var json = {type: node.nodeName, children: []};\n            if (node.nodeType === node.ELEMENT_NODE) {\n                for (var j = 0; j < node.attributes.length; j++) {\n                    var attribute = node.attributes[j];\n                    var nm = attributeRenamer[attribute.nodeName] || attribute.nodeName;\n                    json[nm] = attribute.nodeValue;\n                }\n            }\n            for (var i = 0; i < node.childNodes.length; i++) {\n                var item = node.childNodes[i];\n                var j = xmlToJSON(item, attributeRenamer);\n                if (j) json.children.push(j);\n            }\n            return json;\n        }\n    }\n\n    /**\n     Disposes of this ZIP\n     */\n    this.destroy = function () {\n        reader.close(function () {\n            // onclose callback\n        });\n    };\n};\n\nfunction\n\nloadZIP(src, ok, err) {\n    var zip = new ZIP();\n    zip.load(src, function () {\n        ok(zip);\n    }, function (errMsg) {\n        err(\"Error loading ZIP archive: \" + errMsg);\n    });\n}\n\nfunction\n\nstripURN(str) {\n    var subStr = \"urn:3DXML:\";\n    return (str.indexOf(subStr) === 0) ? str.substring(subStr.length) : str;\n}\n\n\nfunction\n\ngetIDFromURI(str) {\n    var hashIdx = str.lastIndexOf(\"#\");\n    return hashIdx !== -1 ? str.substring(hashIdx + 1) : str;\n}\n\n/**\n * {@link Viewer} plugin that loads models from [3DXML](https://en.wikipedia.org/wiki/3DXML) files.\n *\n * [<img src=\"https://xeokit.io/img/docs/XML3DLoaderPlugin/XML3DPluginTreeView.png\">](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_3DXML_TreeView)\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_3DXML_TreeView)]\n *\n * ## Overview\n *\n * * Currently supports 3DXML V4.2.\n * * Creates an {@link Entity} representing each model it loads, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.\n * * Creates an {@link Entity} for each object within the model, which will have {@link Entity#isObject} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.\n * * When loading, can set the World-space position, scale and rotation of each model within World space, along with initial properties for all the model's {@link Entity}s.\n * * Can optionally load a {@link MetaModel} to classify the objects within the model, from which you can create a tree view using the {@link TreeViewPlugin}.\n * <br>\n * Note that the name of this plugin is intentionally munged to \"XML3D\" because a JavaScript class name cannot begin with a numeral.\n *\n * An 3DXML model is a zip archive that bundles multiple XML files and assets. Internally, the XML3DLoaderPlugin uses the\n * [zip.js](https://gildas-lormeau.github.io/zip.js/) library to unzip them before loading. The zip.js library uses\n * [Web workers](https://www.w3.org/TR/workers/) for fast unzipping, so XML3DLoaderPlugin requires that we configure it\n * with a ````workerScriptsPath```` property specifying the directory where zip.js keeps its Web worker script. See\n * the example for how to do that.\n *\n * ## Usage\n *\n * In the example below, we'll use an XML3DLoaderPlugin to load a 3DXML model. When the model has loaded,\n * we'll use the {@link CameraFlightAnimation} to fly the {@link Camera} to look at boundary of the model. We'll\n * then get the model's {@link Entity} from the {@link Scene} and highlight the whole model.\n *\n * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_3DXML_Widget)]\n *\n * ````javascript\n * // Create a xeokit Viewer\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\"\n * });\n *\n * // Add an XML3DLoaderPlugin to the Viewer\n * var plugin = new XML3DLoaderPlugin(viewer, {\n *      id: \"XML3DLoader\",  // Default value\n *      workerScriptsPath : \"../../src/plugins/XML3DLoader/zipjs/\" // Path to zip.js workers dir\n * });\n *\n * // Load the 3DXML model\n * var model = plugin.load({ // Model is an Entity\n *     id: \"myModel\",\n *     src: \"./models/xml3d/3dpreview.3dxml\",\n *     scale: [0.1, 0.1, 0.1],\n *     rotate: [90, 0, 0],\n *     translate: [100,0,0],\n *     edges: true\n * });\n *\n * // When the model has loaded, fit it to view\n * model.on(\"loaded\", function() {\n *      viewer.cameraFlight.flyTo(model);\n * });\n *\n * // Update properties of the model via the entity\n * model.highlighted = true;\n *\n * // Find the model Entity by ID\n * model = viewer.scene.models[\"myModel\"];\n *\n * // Destroy the model\n * model.destroy();\n * ````\n * ## Loading MetaModels\n *\n * We have the option to load a {@link MetaModel} that contains a hierarchy of {@link MetaObject}s that classifes the objects within\n * our 3DXML model.\n *\n * This is useful for building a tree view to navigate the objects, using {@link TreeViewPlugin}.\n *\n * Let's load the model again, this time creating a MetaModel:\n *\n * ````javascript\n * var model = plugin.load({\n *     id: \"myModel\",\n *     src: \"./models/xml3d/3dpreview.3dxml\",\n *     scale: [0.1, 0.1, 0.1],\n *     rotate: [90, 0, 0],\n *     translate: [100,0,0],\n *     edges: true,\n *\n *     createMetaModel: true // <<-------- Create a MetaModel\n * });\n * ````\n *\n * The MetaModel can then be found on the {@link Viewer}'s {@link MetaScene}, using the model's ID:\n *\n * ````javascript\n * const metaModel = viewer.metaScene.metaModels[\"myModel\"];\n * ````\n *\n * Now we can use {@link TreeViewPlugin} to create a tree view to navigate our model's objects:\n *\n * ````javascript\n * import {TreeViewPlugin} from \"xeokit-sdk.es.js\"\"xeokit-sdk.es.js\";\n *\n * const treeView = new TreeViewPlugin(viewer, {\n *     containerElement: document.getElementById(\"myTreeViewContainer\")\n * });\n *\n * const treeView = new TreeViewPlugin(viewer, {\n *      containerElement: document.getElementById(\"treeViewContainer\"),\n *      autoExpandDepth: 3, // Initially expand tree three storeys deep\n *      hierarchy: \"containment\",\n *      autoAddModels: false\n * });\n *\n * model.on(\"loaded\", () => {\n *      treeView.addModel(model.id);\n * });\n * ````\n *\n * Note that only the TreeViewPlugin \"containment\" hierarchy makes sense for an XML3D model. A \"types\" hierarchy\n * does not make sense because XML3DLoaderPlugin will set each {@link MetaObject#type} to \"Default\", and \"storeys\"\n * does not make sense because that requires some of the MetaObject#type values to be \"IfcBuildingStorey\".\n *\n * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_3DXML_TreeView)]\n *\n * ## Material Type\n *\n * Although 3DXML only supports Phong materials, XML3DLoaderPlugin is able to convert them to physically-based materials.\n *\n * The plugin supports three material types:\n *\n * | Material Type | Material Components Loaded  | Description | Example |\n * |:--------:|:----:|:-----:|:-----:|\n * | \"PhongMaterial\" (default) | {@link PhongMaterial}  | Non-physically-correct Blinn-Phong shading model | [Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_3DXML_materialType_Phong) |\n * | \"MetallicMaterial\" | {@link MetallicMaterial} | Physically-accurate specular-glossiness shading model | [Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_3DXML_materialType_Metallic) |\n * | \"SpecularMaterial\" | {@link SpecularMaterial} | Physically-accurate metallic-roughness shading model | [Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_3DXML_materialType_Specular) |\n *\n * <br>\n * Let's load our model again, this time converting the 3DXML Blinn-Phong materials to {@link SpecularMaterial}s:\n *\n * ````javascript\n * var model = plugin.load({ // Model is an Entity\n *     id: \"myModel\",\n *     src: \"./models/xml3d/3dpreview.3dxml\",\n *     materialtype: \"SpecularMaterial\": true\"\n * });\n * ````\n *\n * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_3DXML_materialType_Specular)]\n *\n * @class XML3DLoaderPlugin\n */\n\nclass XML3DLoaderPlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"XML3DLoader\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {String} cfg.workerScriptsPath Path to the directory that contains the\n     * bundled [zip.js](https://gildas-lormeau.github.io/zip.js/) archive, which is a dependency of this plugin. This directory\n     * contains the script that is used by zip.js to instantiate Web workers, which assist with unzipping the 3DXML, which is a ZIP archive.\n     * @param {String} [cfg.materialType=\"PhongMaterial\"] What type of materials to create while loading: \"MetallicMaterial\" to create {@link MetallicMaterial}s, \"SpecularMaterial\" to create {@link SpecularMaterial}s or \"PhongMaterial\" to create {@link PhongMaterial}s. As it loads XML3D's Phong materials, the XMLLoaderPlugin will do its best approximate conversion of those to the specified workflow.\n     * @param {Boolean} [cfg.createMetaModel=false] When true, will create a {@link MetaModel} for the model in {@link MetaScene#metaModels}.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"XML3DLoader\", viewer, cfg);\n\n        if (!cfg.workerScriptsPath) {\n            this.error(\"Config expected: workerScriptsPath\");\n            return\n        }\n\n        this._workerScriptsPath = cfg.workerScriptsPath;\n\n        /**\n         * @private\n         */\n        this._loader = new XML3DSceneGraphLoader(this, cfg);\n\n        /**\n         * Supported 3DXML schema versions\n         * @property supportedSchemas\n         * @type {string[]}\n         */\n        this.supportedSchemas = this._loader.supportedSchemas;\n    }\n\n    /**\n     * Loads a 3DXML model from a file into this XML3DLoaderPlugin's {@link Viewer}.\n     *\n     * Creates a tree of {@link Entity}s within the Viewer's {@link Scene} that represents the model.\n     *\n     * @param {*} params  Loading parameters.\n     * @param {String} params.id ID to assign to the model's root {@link Entity}, unique among all components in the Viewer's {@link Scene}.\n     * @param {String} [params.src] Path to a 3DXML file.\n     * @param {Boolean} [params.edges=false] Whether or not xeokit renders the {@link Entity} with edges emphasized.\n     * @param {Number[]} [params.position=[0,0,0]] The model's World-space 3D position.\n     * @param {Number[]} [params.scale=[1,1,1]] The model's World-space scale.\n     * @param {Number[]} [params.rotation=[0,0,0]] The model's World-space rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [params.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] The model's world transform matrix. Overrides the position, scale and rotation parameters.\n     * @param {Boolean} [params.backfaces=false] When true, allows visible backfaces, wherever specified in the 3DXML. When false, ignores backfaces.\n     * @param {Number} [params.edgeThreshold=20] When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.\n     * @param {String} [params.materialType=\"PhongMaterial\"] What type of materials to create while loading: \"MetallicMaterial\" to create {@link MetallicMaterial}s, \"SpecularMaterial\" to create {@link SpecularMaterial}s or \"PhongMaterial\" to create {@link PhongMaterial}s. As it loads XML3D's Phong materials, the XMLLoaderPlugin will do its best approximate conversion of those to the specified workflow.\n     * @param {Boolean} [params.createMetaModel=false] When true, will create a {@link MetaModel} for the model in {@link MetaScene#metaModels}.\n     * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}\n     */\n    load(params = {}) {\n\n        params.workerScriptsPath = this._workerScriptsPath;\n\n        if (params.id && this.viewer.scene.components[params.id]) {\n            this.error(\"Component with this ID already exists in viewer: \" + params.id + \" - will autogenerate this ID\");\n            delete params.id;\n        }\n\n        const modelNode = new Node$1(this.viewer.scene, utils.apply(params, {\n            isModel: true\n        }));\n\n        const src = params.src;\n\n        if (!src) {\n            this.error(\"load() param expected: src\");\n            return modelNode; // Return new empty model\n        }\n\n        this._loader.load(this, modelNode, src, params);\n\n        return modelNode;\n    }\n}\n\n/**\n * Default data access strategy for {@link WebIFCLoaderPlugin}.\n */\nclass WebIFCDefaultDataSource {\n\n    constructor(cfg = {}) {\n        this.cacheBuster = (cfg.cacheBuster !== false);\n    }\n\n    _cacheBusterURL(url) {\n        if (!this.cacheBuster) {\n            return url;\n        }\n        const timestamp = new Date().getTime();\n        if (url.indexOf('?') > -1) {\n            return url + '&_=' + timestamp;\n        } else {\n            return url + '?_=' + timestamp;\n        }\n    }\n\n    /**\n     * Gets the contents of the given IFC file in an arraybuffer.\n     *\n     * @param {String|Number} src Path or ID of an IFC file.\n     * @param {Function} ok Callback fired on success, argument is the IFC file in an arraybuffer.\n     * @param {Function} error Callback fired on error.\n     */\n    getIFC(src, ok, error) {\n        src = this._cacheBusterURL(src);\n\n        var defaultCallback = () => {\n        };\n        ok = ok || defaultCallback;\n        error = error || defaultCallback;\n        const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n        const dataUriRegexResult = src.match(dataUriRegex);\n        if (dataUriRegexResult) { // Safari can't handle data URIs through XMLHttpRequest\n            const isBase64 = !!dataUriRegexResult[2];\n            var data = dataUriRegexResult[3];\n            data = window.decodeURIComponent(data);\n            if (isBase64) {\n                data = window.atob(data);\n            }\n            try {\n                const buffer = new ArrayBuffer(data.length);\n                const view = new Uint8Array(buffer);\n                for (var i = 0; i < data.length; i++) {\n                    view[i] = data.charCodeAt(i);\n                }\n                ok(buffer);\n            } catch (errMsg) {\n                error(errMsg);\n            }\n        } else {\n            const request = new XMLHttpRequest();\n            request.open('GET', src, true);\n            request.responseType = 'arraybuffer';\n            request.onreadystatechange = function () {\n                if (request.readyState === 4) {\n                    if (request.status === 200) {\n                        ok(request.response);\n                    } else {\n                        error('getXKT error : ' + request.response);\n                    }\n                }\n            };\n            request.send(null);\n        }\n    }\n}\n\n/**\n * {@link Viewer} plugin that uses [web-ifc](https://github.com/tomvandig/web-ifc) to load BIM models directly from IFC files.\n *\n * <a href=\"https://xeokit.github.io/xeokit-sdk/examples/index.html#BIMOffline_WebIFCLoaderPlugin_Duplex\"><img src=\"https://xeokit.io/img/docs/WebIFCLoaderPlugin/WebIFCLoaderPlugin.png\"></a>\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#BIMOffline_WebIFCLoaderPlugin_Duplex)]\n *\n * ## Overview\n *\n * * Loads small-to-medium sized BIM models directly from IFC files.\n * * Uses [web-ifc](https://github.com/tomvandig/web-ifc) to parse IFC files in the browser.\n * * Loads IFC geometry, element structure metadata, and property sets.\n * * Not for large models. For best performance with large models, we recommend using {@link XKTLoaderPlugin}.\n * * Loads double-precision coordinates, enabling models to be viewed at global coordinates without accuracy loss.\n * * Allows to set the position, scale and rotation of each model as you load it.\n * * Filter which IFC types get loaded.\n * * Configure initial appearances of specified IFC types.\n * * Set a custom data source for IFC files.\n * * Load multiple copies of the same model.\n *\n * ## Limitations\n *\n * Loading and parsing huge IFC STEP files can be slow, and can overwhelm the browser, however. To view your\n * largest IFC models, we recommend instead pre-converting those to xeokit's compressed native .XKT format, then\n * loading them with {@link XKTLoaderPlugin} instead.</p>\n *\n * ## Scene representation\n *\n * When loading a model, WebIFCLoaderPlugin creates an {@link Entity} that represents the model, which\n * will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id}\n * in {@link Scene#models}. The WebIFCLoaderPlugin also creates an {@link Entity} for each object within the\n * model. Those Entities will have {@link Entity#isObject} set ````true```` and will be registered\n * by {@link Entity#id} in {@link Scene#objects}.\n *\n * ## Metadata\n *\n * When loading a model, WebIFCLoaderPlugin also creates a {@link MetaModel} that represents the model, which contains\n * a {@link MetaObject} for each IFC element, plus a {@link PropertySet} for each IFC property set. Loading metadata can be very slow, so we can also optionally disable it if we\n * don't need it.\n *\n * ## Usage\n *\n * In the example below we'll load the Duplex BIM model from\n * an [IFC file](https://github.com/xeokit/xeokit-sdk/tree/master/assets/models/ifc). Within our {@link Viewer}, this will create a bunch of {@link Entity}s that represents the model and its objects, along with a {@link MetaModel}, {@link MetaObject}s and {@link PropertySet}s\n * that hold their metadata.\n *\n * Since this model contains IFC types, the WebIFCLoaderPlugin will set the initial appearance of each object\n * {@link Entity} according to its IFC type in {@link WebIFCLoaderPlugin#objectDefaults}.\n *\n * * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#BIMOffline_WebIFCLoaderPlugin_isolateStorey)]\n *\n * ````javascript\n * import {Viewer, WebIFCLoaderPlugin} from \"xeokit-sdk.es.js\";\n * import * as WebIFC from \"https://cdn.jsdelivr.net/npm/web-ifc@0.0.51/web-ifc-api.js\";\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // 1. Create a Viewer,\n * // 2. Arrange the camera\n * //------------------------------------------------------------------------------------------------------------------\n *\n * // 1\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * // 2\n * viewer.camera.eye = [-2.56, 8.38, 8.27];\n * viewer.camera.look = [13.44, 3.31, -14.83];\n * viewer.camera.up = [0.10, 0.98, -0.14];\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // 1. Create a web-ifc API, which will parse IFC for our WebIFCLoaderPlugin\n * // 2. Connect the API to the web-ifc WASM module, which powers the parsing\n * // 3. Initialize the web-ifc API\n * //------------------------------------------------------------------------------------------------------------------\n *\n * // 1\n *\n * const IfcAPI = new this._webIFC.IfcAPI();\n *\n * // 2\n *\n * IfcAPI.SetWasmPath(\"https://cdn.jsdelivr.net/npm/web-ifc@0.0.51/\");\n *\n * // 3\n *\n * IfcAPI.Init().then(() => {\n *\n *      //------------------------------------------------------------------------------------------------------------\n *      // 1. Create a WebIFCLoaderPlugin, configured with the web-ifc module and a web-ifc API instance\n *      // 2. Load a BIM model fom an IFC file, excluding its IfcSpace elements, and highlighting edges\n *      //------------------------------------------------------------------------------------------------------------\n *\n *     const ifcLoader = new WebIFCLoaderPlugin(viewer, {\n *         WebIFC,\n *         IfcAPI\n *     });\n *\n *     // 2\n *     const model = ifcLoader.load({          // Returns an Entity that represents the model\n *         id: \"myModel\",\n *         src: \"../assets/models/ifc/Duplex.ifc\",\n *         excludeTypes: [\"IfcSpace\"],\n *         edges: true\n *     });\n *\n *     model.on(\"loaded\", () => {\n *\n *         //----------------------------------------------------------------------------------------------------------\n *         // 1. Find metadata on the bottom storey\n *         // 2. X-ray all the objects except for the bottom storey\n *         // 3. Fit the bottom storey in view\n *         //----------------------------------------------------------------------------------------------------------\n *\n *         // 1\n *         const metaModel = viewer.metaScene.metaModels[\"myModel\"];       // MetaModel with ID \"myModel\"\n *         const metaObject\n *                 = viewer.metaScene.metaObjects[\"1xS3BCk291UvhgP2dvNsgp\"];  // MetaObject with ID \"1xS3BCk291UvhgP2dvNsgp\"\n *\n *         const name = metaObject.name;                                   // \"01 eerste verdieping\"\n *         const type = metaObject.type;                                   // \"IfcBuildingStorey\"\n *         const parent = metaObject.parent;                               // MetaObject with type \"IfcBuilding\"\n *         const children = metaObject.children;                           // Array of child MetaObjects\n *         const objectId = metaObject.id;                                 // \"1xS3BCk291UvhgP2dvNsgp\"\n *         const objectIds = viewer.metaScene.getObjectIDsInSubtree(objectId);   // IDs of leaf sub-objects\n *         const aabb = viewer.scene.getAABB(objectIds);                   // Axis-aligned boundary of the leaf sub-objects\n *\n *         // 2\n *         viewer.scene.setObjectsXRayed(viewer.scene.objectIds, true);\n *         viewer.scene.setObjectsXRayed(objectIds, false);\n *\n *         // 3\n *         viewer.cameraFlight.flyTo(aabb);\n *\n *         // Find the model Entity by ID\n *         model = viewer.scene.models[\"myModel\"];\n *\n *         // Destroy the model\n *         model.destroy();\n *     });\n * });\n * ````\n *\n * ## Transforming\n *\n * We have the option to rotate, scale and translate each  IFC model as we load it.\n *\n * This lets us load multiple models, or even multiple copies of the same model, and position them apart from each other.\n *\n * In the example below, we'll scale our model to half its size, rotate it 90 degrees about its local X-axis, then\n * translate it 100 units along its X axis.\n *\n * ````javascript\n * ifcLoader.load({\n *      src: \"../assets/models/ifc/Duplex.ifc\",\n *      rotation: [90,0,0],\n *      scale: [0.5, 0.5, 0.5],\n *      origin: [100, 0, 0]\n * });\n * ````\n *\n * ## Including and excluding IFC types\n *\n * We can also load only those objects that have the specified IFC types.\n *\n * In the example below, we'll load only the objects that represent walls.\n *\n * ````javascript\n * const model2 = ifcLoader.load({\n *     id: \"myModel2\",\n *     src: \"../assets/models/ifc/Duplex.ifc\",\n *     includeTypes: [\"IfcWallStandardCase\"]\n * });\n * ````\n *\n * We can also load only those objects that **don't** have the specified IFC types.\n *\n * In the example below, we'll load only the objects that do not represent empty space.\n *\n * ````javascript\n * const model3 = ifcLoader.load({\n *     id: \"myModel3\",\n *     src: \"../assets/models/ifc/Duplex.ifc\",\n *     excludeTypes: [\"IfcSpace\"]\n * });\n * ````\n *\n * ## Configuring initial IFC object appearances\n *\n * We can specify the custom initial appearance of loaded objects according to their IFC types.\n *\n * This is useful for things like:\n *\n * * setting the colors to our objects according to their IFC types,\n * * automatically hiding ````IfcSpace```` objects, and\n * * ensuring that ````IfcWindow```` objects are always transparent.\n * <br>\n * In the example below, we'll load a model, while configuring ````IfcSpace```` elements to be always initially invisible,\n * and ````IfcWindow```` types to be always translucent blue.\n *\n * ````javascript\n * const myObjectDefaults = {\n *\n *      IfcSpace: {\n *          visible: false\n *      },\n *      IfcWindow: {\n *          colorize: [0.337255, 0.303922, 0.870588], // Blue\n *          opacity: 0.3\n *      },\n *\n *      //...\n *\n *      DEFAULT: {\n *          colorize: [0.5, 0.5, 0.5]\n *      }\n * };\n *\n * const model4 = ifcLoader.load({\n *      id: \"myModel4\",\n *      src: \"../assets/models/ifc/Duplex.ifc\",\n *      objectDefaults: myObjectDefaults // Use our custom initial default states for object Entities\n * });\n * ````\n *\n * When we don't customize the appearance of IFC types, as just above, then IfcSpace elements tend to obscure other\n * elements, which can be confusing.\n *\n * It's often helpful to make IfcSpaces transparent and unpickable, like this:\n *\n * ````javascript\n * const ifcLoader = new WebIFCLoaderPlugin(viewer, {\n *    wasmPath: \"../dist/\",\n *    objectDefaults: {\n *        IfcSpace: {\n *            pickable: false,\n *            opacity: 0.2\n *        }\n *    }\n * });\n * ````\n *\n * Alternatively, we could just make IfcSpaces invisible, which also makes them unpickable:\n *\n * ````javascript\n * const ifcLoader = new WebIFCLoaderPlugin(viewer, {\n *    wasmPath: \"../dist/\",\n *    objectDefaults: {\n *        IfcSpace: {\n *            visible: false\n *        }\n *    }\n * });\n * ````\n *\n * ## Configuring a custom data source\n *\n * By default, WebIFCLoaderPlugin will load IFC files over HTTP.\n *\n * In the example below, we'll customize the way WebIFCLoaderPlugin loads the files by configuring it with our own data source\n * object. For simplicity, our custom data source example also uses HTTP, using a couple of xeokit utility functions.\n *\n * ````javascript\n * import {utils} from \"xeokit-sdk.es.js\";\n *\n * class MyDataSource {\n *\n *      constructor() {\n *      }\n *\n *      // Gets the contents of the given IFC file in an arraybuffer\n *      getIFC(src, ok, error) {\n *          console.log(\"MyDataSource#getIFC(\" + IFCSrc + \", ... )\");\n *          utils.loadArraybuffer(src,\n *              (arraybuffer) => {\n *                  ok(arraybuffer);\n *              },\n *              function (errMsg) {\n *                  error(errMsg);\n *              });\n *      }\n * }\n *\n * const ifcLoader2 = new WebIFCLoaderPlugin(viewer, {\n *       dataSource: new MyDataSource()\n * });\n *\n * const model5 = ifcLoader2.load({\n *      id: \"myModel5\",\n *      src: \"../assets/models/ifc/Duplex.ifc\"\n * });\n * ````\n *\n * ## Loading multiple copies of a model, without object ID clashes\n *\n * Sometimes we need to load two or more instances of the same model, without having clashes\n * between the IDs of the equivalent objects in the model instances.\n *\n * As shown in the example below, we do this by setting {@link WebIFCLoaderPlugin#globalizeObjectIds} ````true```` before we load our models.\n *\n * ````javascript\n * ifcLoader.globalizeObjectIds = true;\n *\n * const model = ifcLoader.load({\n *      id: \"model1\",\n *      src: \"../assets/models/ifc/Duplex.ifc\"\n * });\n *\n * const model2 = ifcLoader.load({\n *    id: \"model2\",\n *    src: \"../assets/models/ifc/Duplex.ifc\"\n * });\n * ````\n *\n * For each {@link Entity} loaded by these two calls, {@link Entity#id} and {@link MetaObject#id} will get prefixed by\n * the ID of their model, in order to avoid ID clashes between the two models.\n *\n * An Entity belonging to the first model will get an ID like this:\n *\n * ````\n * myModel1#0BTBFw6f90Nfh9rP1dlXrb\n * ````\n *\n * The equivalent Entity in the second model will get an ID like this:\n *\n * ````\n * myModel2#0BTBFw6f90Nfh9rP1dlXrb\n * ````\n *\n * Now, to update the visibility of both of those Entities collectively, using {@link Scene#setObjectsVisible}, we can\n * supply just the IFC product ID part to that method:\n *\n * ````javascript\n * myViewer.scene.setObjectVisibilities(\"0BTBFw6f90Nfh9rP1dlXrb\", true);\n * ````\n *\n * The method, along with {@link Scene#setObjectsXRayed}, {@link Scene#setObjectsHighlighted} etc, will internally expand\n * the given ID to refer to the instances of that Entity in both models.\n *\n * We can also, of course, reference each Entity directly, using its globalized ID:\n *\n * ````javascript\n * myViewer.scene.setObjectVisibilities(\"myModel1#0BTBFw6f90Nfh9rP1dlXrb\", true);\n *````\n *\n * @class WebIFCLoaderPlugin\n * @since 2.0.13\n */\nclass WebIFCLoaderPlugin extends Plugin {\n\n    /**\n     * @constructor\n     *\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"ifcLoader\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {Object} cfg.WebIFC The web-ifc module, required by WebIFCLoaderPlugin. WebIFCLoaderPlugin uses various IFC type constants defined on this module.\n     * @param {Object} cfg.IfcAPI A pre-initialized instance of the web-ifc API. WebIFCLoaderPlugin uses this to parse IFC.  * @param {Object} [cfg.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object.  Default value is {@link IFCObjectDefaults}.\n     * @param {Object} [cfg.dataSource] A custom data source through which the WebIFCLoaderPlugin can load model and metadata files. Defaults to an instance of {@link WebIFCDefaultDataSource}, which loads over HTTP.\n     * @param {String[]} [cfg.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.\n     * @param {String[]} [cfg.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.\n     * @param {Boolean} [cfg.excludeUnclassifiedObjects=false] When loading metadata and this is ````true````, will only load {@link Entity}s that have {@link MetaObject}s (that are not excluded). This is useful when we don't want Entitys in the Scene that are not represented within IFC navigation components, such as {@link TreeViewPlugin}.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"ifcLoader\", viewer, cfg);\n\n        this.dataSource = cfg.dataSource;\n        this.objectDefaults = cfg.objectDefaults;\n        this.includeTypes = cfg.includeTypes;\n        this.excludeTypes = cfg.excludeTypes;\n        this.excludeUnclassifiedObjects = cfg.excludeUnclassifiedObjects;\n\n        if (!cfg.WebIFC) {\n            throw \"Parameter expected: WebIFC\";\n        }\n        \n        if (!cfg.IfcAPI) {\n            throw \"Parameter expected: IfcAPI\";\n        }\n\n        this._webIFC = cfg.WebIFC;\n        \n        this._ifcAPI = cfg.IfcAPI;\n    }\n\n    /**\n     * Gets the ````IFC```` format versions supported by this WebIFCLoaderPlugin.\n     * @returns {string[]}\n     */\n    get supportedVersions() {\n        return [\"2x3\", \"4\"];\n    }\n\n    /**\n     * Gets the custom data source through which the WebIFCLoaderPlugin can load IFC files.\n     *\n     * Default value is {@link WebIFCDefaultDataSource}, which loads via HTTP.\n     *\n     * @type {Object}\n     */\n    get dataSource() {\n        return this._dataSource;\n    }\n\n    /**\n     * Sets a custom data source through which the WebIFCLoaderPlugin can load IFC files.\n     *\n     * Default value is {@link WebIFCDefaultDataSource}, which loads via HTTP.\n     *\n     * @type {Object}\n     */\n    set dataSource(value) {\n        this._dataSource = value || new WebIFCDefaultDataSource();\n    }\n\n    /**\n     * Gets map of initial default states for each loaded {@link Entity} that represents an object.\n     *\n     * Default value is {@link IFCObjectDefaults}.\n     *\n     * @type {{String: Object}}\n     */\n    get objectDefaults() {\n        return this._objectDefaults;\n    }\n\n    /**\n     * Sets map of initial default states for each loaded {@link Entity} that represents an object.\n     *\n     * Default value is {@link IFCObjectDefaults}.\n     *\n     * @type {{String: Object}}\n     */\n    set objectDefaults(value) {\n        this._objectDefaults = value || IFCObjectDefaults;\n    }\n\n    /**\n     * Gets the whitelist of the IFC types loaded by this WebIFCLoaderPlugin.\n     *\n     * When loading IFC models, causes this WebIFCLoaderPlugin to only load objects whose types are in this\n     * list. An object's type is indicated by its {@link MetaObject}'s {@link MetaObject#type}.\n     *\n     * Default value is ````undefined````.\n     *\n     * @type {String[]}\n     */\n    get includeTypes() {\n        return this._includeTypes;\n    }\n\n    /**\n     * Sets the whitelist of the IFC types loaded by this WebIFCLoaderPlugin.\n     *\n     * When loading IFC models, causes this WebIFCLoaderPlugin to only load objects whose types are in this\n     * list. An object's type is indicated by its {@link MetaObject}'s {@link MetaObject#type}.\n     *\n     * Default value is ````undefined````.\n     *\n     * @type {String[]}\n     */\n    set includeTypes(value) {\n        this._includeTypes = value;\n    }\n\n    /**\n     * Gets the blacklist of IFC types that are never loaded by this WebIFCLoaderPlugin.\n     *\n     * When loading IFC models, causes this WebIFCLoaderPlugin to **not** load objects whose types are in this\n     * list. An object's type is indicated by its {@link MetaObject}'s {@link MetaObject#type}.\n     *\n     * Default value is ````undefined````.\n     *\n     * @type {String[]}\n     */\n    get excludeTypes() {\n        return this._excludeTypes;\n    }\n\n    /**\n     * Sets the blacklist of IFC types that are never loaded by this WebIFCLoaderPlugin.\n     *\n     * When IFC models, causes this WebIFCLoaderPlugin to **not** load objects whose types are in this\n     * list. An object's type is indicated by its {@link MetaObject}'s {@link MetaObject#type}.\n     *\n     * Default value is ````undefined````.\n     *\n     * @type {String[]}\n     */\n    set excludeTypes(value) {\n        this._excludeTypes = value;\n    }\n\n    /**\n     * Gets whether we load objects that don't have IFC types.\n     *\n     * When loading IFC models and this is ````true````, WebIFCLoaderPlugin will not load objects\n     * that don't have IFC types.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get excludeUnclassifiedObjects() {\n        return this._excludeUnclassifiedObjects;\n    }\n\n    /**\n     * Sets whether we load objects that don't have IFC types.\n     *\n     * When loading IFC models and this is ````true````, WebIFCLoaderPlugin will not load objects\n     * that don't have IFC types.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    set excludeUnclassifiedObjects(value) {\n        this._excludeUnclassifiedObjects = !!value;\n    }\n\n    /**\n     * Gets whether WebIFCLoaderPlugin globalizes each {@link Entity#id} and {@link MetaObject#id} as it loads a model.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get globalizeObjectIds() {\n        return this._globalizeObjectIds;\n    }\n\n    /**\n     * Sets whether WebIFCLoaderPlugin globalizes each {@link Entity#id} and {@link MetaObject#id} as it loads a model.\n     *\n     * Set  this ````true```` when you need to load multiple instances of the same model, to avoid ID clashes\n     * between the objects in the different instances.\n     *\n     * When we load a model with this set ````true````, then each {@link Entity#id} and {@link MetaObject#id} will be\n     * prefixed by the ID of the model, ie. ````<modelId>#<objectId>````.\n     *\n     * {@link Entity#originalSystemId} and {@link MetaObject#originalSystemId} will always hold the original, un-prefixed, ID values.\n     *\n     * Default value is ````false````.\n     *\n     * See the main {@link WebIFCLoaderPlugin} class documentation for usage info.\n     *\n     * @type {Boolean}\n     */\n    set globalizeObjectIds(value) {\n        this._globalizeObjectIds = !!value;\n    }\n\n    /**\n     * Loads an ````IFC```` model into this WebIFCLoaderPlugin's {@link Viewer}.\n     *\n     * @param {*} params Loading parameters.\n     * @param {String} [params.id] ID to assign to the root {@link Entity#id}, unique among all components in the Viewer's {@link Scene}, generated automatically by default.\n     * @param {String} [params.src] Path to a IFC file, as an alternative to the ````ifc```` parameter.\n     * @param {ArrayBuffer} [params.ifc] The IFC file data, as an alternative to the ````src```` parameter.\n     * @param {Boolean} [params.loadMetadata=true] Whether to load IFC metadata (metaobjects and property sets).\n     * @param {{String:Object}} [params.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.\n     * @param {String[]} [params.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.\n     * @param {String[]} [params.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.\n     * @param {Boolean} [params.edges=false] Whether or not xeokit renders the model with edges emphasized.\n     * @param {Number[]} [params.origin=[0,0,0]] The model's World-space double-precision 3D origin. Use this to position the model within xeokit's World coordinate system, using double-precision coordinates.\n     * @param {Number[]} [params.position=[0,0,0]] The model single-precision 3D position, relative to the ````origin```` parameter.\n     * @param {Number[]} [params.scale=[1,1,1]] The model's scale.\n     * @param {Number[]} [params.rotation=[0,0,0]] The model's orientation, given as Euler angles in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [params.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] The model's world transform matrix. Overrides the position, scale and rotation parameters. Relative to ````origin````.\n     * @param {Boolean} [params.edges=false] Indicates if the model's edges are initially emphasized.\n     * @param {Boolean} [params.saoEnabled=true] Indicates if Scalable Ambient Obscurance (SAO) will apply to the model. SAO is configured by the Scene's {@link SAO} component. Only works when {@link SAO#enabled} is also ````true````\n     * @param {Boolean} [params.pbrEnabled=false] Indicates if physically-based rendering (PBR) will apply to the model. Only works when {@link Scene#pbrEnabled} is also ````true````.\n     * @param {Number} [params.backfaces=false] When we set this ````true````, then we force rendering of backfaces for the model. When we leave this ````false````, then we allow the Viewer to decide when to render backfaces. In that case, the Viewer will hide backfaces on watertight meshes, show backfaces on open meshes, and always show backfaces on meshes when we slice them open with {@link SectionPlane}s.\n     * @param {Boolean} [params.excludeUnclassifiedObjects=false] When loading metadata and this is ````true````, will only load {@link Entity}s that have {@link MetaObject}s (that are not excluded). This is useful when we don't want Entitys in the Scene that are not represented within IFC navigation components, such as {@link TreeViewPlugin}.\n     * @param {Boolean} [params.globalizeObjectIds=false] Indicates whether to globalize each {@link Entity#id} and {@link MetaObject#id}, in case you need to prevent ID clashes with other models. See {@link WebIFCLoaderPlugin#globalizeObjectIds} for more info.\n     * @param {Object} [params.stats] Collects model statistics.\n     * @param {Boolean} [params.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to\n     * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable\n     * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point\n     * primitives. Only works while {@link DTX#enabled} is also ````true````.\n     * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.\n     */\n    load(params = {}) {\n\n        if (params.id && this.viewer.scene.components[params.id]) {\n            this.error(\"Component with this ID already exists in viewer: \" + params.id + \" - will autogenerate this ID\");\n            delete params.id;\n        }\n\n        const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {\n            isModel: true\n        }));\n\n        if (!params.src && !params.ifc) {\n            this.error(\"load() param expected: src or IFC\");\n            return sceneModel; // Return new empty model\n        }\n\n        const options = {\n            autoNormals: true\n        };\n\n        if (params.loadMetadata !== false) {\n\n            const includeTypes = params.includeTypes || this._includeTypes;\n            const excludeTypes = params.excludeTypes || this._excludeTypes;\n            const objectDefaults = params.objectDefaults || this._objectDefaults;\n\n            if (includeTypes) {\n                options.includeTypesMap = {};\n                for (let i = 0, len = includeTypes.length; i < len; i++) {\n                    options.includeTypesMap[includeTypes[i]] = true;\n                }\n            }\n\n            if (excludeTypes) {\n                options.excludeTypesMap = {};\n                for (let i = 0, len = excludeTypes.length; i < len; i++) {\n                    options.excludeTypesMap[excludeTypes[i]] = true;\n                }\n            }\n\n            if (objectDefaults) {\n                options.objectDefaults = objectDefaults;\n            }\n\n            options.excludeUnclassifiedObjects = (params.excludeUnclassifiedObjects !== undefined) ? (!!params.excludeUnclassifiedObjects) : this._excludeUnclassifiedObjects;\n            options.globalizeObjectIds = (params.globalizeObjectIds !== undefined) ? (!!params.globalizeObjectIds) : this._globalizeObjectIds;\n        }\n\n        try {\n            if (params.src) {\n                this._loadModel(params.src, params, options, sceneModel);\n            } else {\n                this._parseModel(params.ifc, params, options, sceneModel);\n            }\n        } catch (e) {\n            this.error(e);\n            sceneModel.fire(\"error\", e);\n        }\n\n        return sceneModel;\n    }\n\n    _loadModel(src, params, options, sceneModel) {\n        const spinner = this.viewer.scene.canvas.spinner;\n        spinner.processes++;\n        this._dataSource.getIFC(params.src, (arrayBuffer) => {\n                this._parseModel(arrayBuffer, params, options, sceneModel);\n                spinner.processes--;\n            },\n            (errMsg) => {\n                spinner.processes--;\n                this.error(errMsg);\n                sceneModel.fire(\"error\", errMsg);\n            });\n    }\n\n    _parseModel(arrayBuffer, params, options, sceneModel) {\n        if (sceneModel.destroyed) {\n            return;\n        }\n        const stats = params.stats || {};\n        stats.sourceFormat = \"IFC\";\n        stats.schemaVersion = \"\";\n        stats.title = \"\";\n        stats.author = \"\";\n        stats.created = \"\";\n        stats.numMetaObjects = 0;\n        stats.numPropertySets = 0;\n        stats.numObjects = 0;\n        stats.numGeometries = 0;\n        stats.numTriangles = 0;\n        stats.numVertices = 0;\n\n        if (!this._ifcAPI) {\n            throw \"WebIFCLoaderPlugin has no WebIFC instance configured - please inject via WebIFCLoaderPlugin constructor\";\n        }\n\n        const dataArray = new Uint8Array(arrayBuffer);\n        const modelID = this._ifcAPI.OpenModel(dataArray);\n        const modelSchema = this._ifcAPI.GetModelSchema(modelID);\n\n        const lines = this._ifcAPI.GetLineIDsWithType(modelID, this._webIFC.IFCPROJECT);\n        const ifcProjectId = lines.get(0);\n\n        const loadMetadata = (params.loadMetadata !== false);\n\n        const metadata = loadMetadata ? {\n            id: \"\",\n            projectId: \"\" + ifcProjectId,\n            author: \"\",\n            createdAt: \"\",\n            schema: \"\",\n            creatingApplication: \"\",\n            metaObjects: [],\n            propertySets: []\n        } : null;\n\n        const ctx = {\n            modelID,\n            modelSchema,\n            sceneModel,\n            loadMetadata,\n            metadata,\n            metaObjects: {},\n            options,\n            log: function (msg) {\n            },\n            nextId: 0,\n            stats\n        };\n\n        if (loadMetadata) {\n\n            if (options.includeTypes) {\n                ctx.includeTypes = {};\n                for (let i = 0, len = options.includeTypes.length; i < len; i++) {\n                    ctx.includeTypes[options.includeTypes[i]] = true;\n                }\n            }\n\n            if (options.excludeTypes) {\n                ctx.excludeTypes = {};\n                for (let i = 0, len = options.excludeTypes.length; i < len; i++) {\n                    ctx.excludeTypes[options.excludeTypes[i]] = true;\n                }\n            }\n\n            this._parseMetaObjects(ctx);\n            this._parsePropertySets(ctx);\n        }\n\n        this._parseGeometry(ctx);\n\n        sceneModel.finalize();\n\n        if (loadMetadata) {\n            const metaModelId = sceneModel.id;\n            this.viewer.metaScene.createMetaModel(metaModelId, ctx.metadata, options);\n        }\n\n        sceneModel.scene.once(\"tick\", () => {\n            if (sceneModel.destroyed) {\n                return;\n            }\n            sceneModel.scene.fire(\"modelLoaded\", sceneModel.id); // FIXME: Assumes listeners know order of these two events\n            sceneModel.fire(\"loaded\", true, false); // Don't forget the event, for late subscribers\n        });\n    }\n\n    _parseMetaObjects(ctx) {\n        const lines = this._ifcAPI.GetLineIDsWithType(ctx.modelID, this._webIFC.IFCPROJECT);\n        const ifcProjectId = lines.get(0);\n        const ifcProject = this._ifcAPI.GetLine(ctx.modelID, ifcProjectId);\n        this._parseSpatialChildren(ctx, ifcProject);\n    }\n\n    _parseSpatialChildren(ctx, ifcElement, parentMetaObjectId) {\n        const metaObjectType = this._ifcAPI.GetNameFromTypeCode(ifcElement.type);\n        if (ctx.includeTypes && (!ctx.includeTypes[metaObjectType])) {\n            return;\n        }\n        if (ctx.excludeTypes && ctx.excludeTypes[metaObjectType]) {\n            return;\n        }\n        this._createMetaObject(ctx, ifcElement, parentMetaObjectId);\n        const metaObjectId = ifcElement.GlobalId.value;\n        this._parseRelatedItemsOfType(ctx, ifcElement.expressID, 'RelatingObject', 'RelatedObjects', this._webIFC.IFCRELAGGREGATES, metaObjectId);\n        this._parseRelatedItemsOfType(ctx, ifcElement.expressID, 'RelatingStructure', 'RelatedElements', this._webIFC.IFCRELCONTAINEDINSPATIALSTRUCTURE, metaObjectId);\n    }\n\n    _createMetaObject(ctx, ifcElement, parentMetaObjectId) {\n        const id = ifcElement.GlobalId.value;\n        const metaObjectType = this._ifcAPI.GetNameFromTypeCode(ifcElement.type);\n        const metaObjectName = (ifcElement.Name && ifcElement.Name.value !== \"\") ? ifcElement.Name.value : metaObjectType;\n        const metaObject = {\n            id: id,\n            name: metaObjectName,\n            type: metaObjectType,\n            parent: parentMetaObjectId\n        };\n        ctx.metadata.metaObjects.push(metaObject);\n        ctx.metaObjects[id] = metaObject;\n        ctx.stats.numMetaObjects++;\n    }\n\n    _parseRelatedItemsOfType(ctx, id, relation, related, type, parentMetaObjectId) {\n        const lines = this._ifcAPI.GetLineIDsWithType(ctx.modelID, type);\n        for (let i = 0; i < lines.size(); i++) {\n            const relID = lines.get(i);\n            const rel = this._ifcAPI.GetLine(ctx.modelID, relID);\n            const relatedItems = rel[relation];\n            let foundElement = false;\n            if (Array.isArray(relatedItems)) {\n                const values = relatedItems.map((item) => item.value);\n                foundElement = values.includes(id);\n            } else {\n                foundElement = (relatedItems.value === id);\n            }\n            if (foundElement) {\n                const element = rel[related];\n                if (!Array.isArray(element)) {\n                    const ifcElement = this._ifcAPI.GetLine(ctx.modelID, element.value);\n                    this._parseSpatialChildren(ctx, ifcElement, parentMetaObjectId);\n                } else {\n                    element.forEach((element2) => {\n                        const ifcElement = this._ifcAPI.GetLine(ctx.modelID, element2.value);\n                        this._parseSpatialChildren(ctx, ifcElement, parentMetaObjectId);\n                    });\n                }\n            }\n        }\n    }\n\n    _parsePropertySets(ctx) {\n        const lines = this._ifcAPI.GetLineIDsWithType(ctx.modelID, this._webIFC.IFCRELDEFINESBYPROPERTIES);\n        for (let i = 0; i < lines.size(); i++) {\n            let relID = lines.get(i);\n            let rel = this._ifcAPI.GetLine(ctx.modelID, relID, true);\n            if (rel) {\n                const relatingPropertyDefinition = rel.RelatingPropertyDefinition;\n                if (!relatingPropertyDefinition) {\n                    continue;\n                }\n                const propertySetId = relatingPropertyDefinition.GlobalId.value;\n                const props = relatingPropertyDefinition.HasProperties;\n                if (props && props.length > 0) {\n                    const propertySetType = \"Default\";\n                    const propertySetName = relatingPropertyDefinition.Name.value;\n                    const properties = [];\n                    for (let i = 0, len = props.length; i < len; i++) {\n                        const prop = props[i];\n                        const name = prop.Name;\n                        const nominalValue = prop.NominalValue;\n                        if (name && nominalValue) {\n                            const property = {\n                                name: name.value,\n                                type: nominalValue.type,\n                                value: nominalValue.value,\n                                valueType: nominalValue.valueType\n                            };\n                            if (prop.Description) {\n                                property.description = prop.Description.value;\n                            } else if (nominalValue.description) {\n                                property.description = nominalValue.description;\n                            }\n                            properties.push(property);\n                        }\n                    }\n                    const propertySet = {\n                        id: propertySetId,\n                        type: propertySetType,\n                        name: propertySetName,\n                        properties: properties\n                    };\n                    ctx.metadata.propertySets.push(propertySet);\n                    ctx.stats.numPropertySets++;\n                    const relatedObjects = rel.RelatedObjects;\n                    if (!relatedObjects || relatedObjects.length === 0) {\n                        return;\n                    }\n                    for (let i = 0, len = relatedObjects.length; i < len; i++) {\n                        const relatedObject = relatedObjects[i];\n                        const metaObjectId = relatedObject.GlobalId.value;\n                        const metaObject = ctx.metaObjects[metaObjectId];\n                        if (metaObject) {\n                            if (!metaObject.propertySetIds) {\n                                metaObject.propertySetIds = [];\n                            }\n                            metaObject.propertySetIds.push(propertySetId);\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    _parseGeometry(ctx) {\n        this._ifcAPI.StreamAllMeshes(ctx.modelID, (flatMesh) => {\n            // TODO: Can we do geometry reuse with web-ifc?\n            const flatMeshExpressID = flatMesh.expressID;\n            const placedGeometries = flatMesh.geometries;\n            const meshIds = [];\n            const properties = this._ifcAPI.GetLine(ctx.modelID, flatMeshExpressID);\n            const globalId = properties.GlobalId.value;\n            if (ctx.loadMetadata) {\n                const metaObjectId = globalId;\n                const metaObject = ctx.metaObjects[metaObjectId];\n                if (ctx.includeTypes && (!metaObject || (!ctx.includeTypes[metaObject.type]))) {\n                    return;\n                }\n                if (ctx.excludeTypes && (!metaObject || ctx.excludeTypes[metaObject.type])) {\n                    return;\n                }\n            }\n            const matrix = math.mat4();\n            const origin = math.vec3();\n            for (let j = 0, lenj = placedGeometries.size(); j < lenj; j++) {\n                const placedGeometry = placedGeometries.get(j);\n                const geometry = this._ifcAPI.GetGeometry(ctx.modelID, placedGeometry.geometryExpressID);\n                const vertexData = this._ifcAPI.GetVertexArray(geometry.GetVertexData(), geometry.GetVertexDataSize());\n                const indices = this._ifcAPI.GetIndexArray(geometry.GetIndexData(), geometry.GetIndexDataSize());\n                // De-interleave vertex arrays\n                const positions = new Float64Array(vertexData.length / 2);\n                const normals = new Float32Array(vertexData.length / 2);\n                for (let k = 0, l = 0, lenk = vertexData.length / 6; k < lenk; k++, l += 3) {\n                    positions[l + 0] = vertexData[k * 6 + 0];\n                    positions[l + 1] = vertexData[k * 6 + 1];\n                    positions[l + 2] = vertexData[k * 6 + 2];\n                }\n                matrix.set(placedGeometry.flatTransformation);\n                math.transformPositions3(matrix, positions);\n                const rtcNeeded = worldToRTCPositions(positions, positions, origin);\n                if (!ctx.options.autoNormals) {\n                    for (let k = 0, l = 0, lenk = vertexData.length / 6; k < lenk; k++, l += 3) {\n                        normals[l + 0] = vertexData[k * 6 + 3];\n                        normals[l + 1] = vertexData[k * 6 + 4];\n                        normals[l + 2] = vertexData[k * 6 + 5];\n                    }\n                }\n                ctx.stats.numGeometries++;\n                ctx.stats.numVertices += (positions.length / 3);\n                ctx.stats.numTriangles += (indices.length / 3);\n                const meshId = (\"mesh\" + ctx.nextId++);\n                ctx.sceneModel.createMesh({\n                    id: meshId,\n                    primitive: \"triangles\", // TODO\n                    origin: rtcNeeded ? origin : null,\n                    positions: positions,\n                    normals: ctx.options.autoNormals ? null : normals,\n                    indices: indices,\n                    color: [placedGeometry.color.x, placedGeometry.color.y, placedGeometry.color.z],\n                    opacity: placedGeometry.color.w\n                });\n                meshIds.push(meshId);\n            }\n            const entityId = ctx.options.globalizeObjectIds ? math.globalizeObjectId(ctx.sceneModel.id, globalId) : globalId;\n            ctx.sceneModel.createEntity({\n                id: entityId,\n                meshIds: meshIds,\n                isObject: true\n            });\n            ctx.stats.numObjects++;\n        });\n    }\n}\n\n/**\n * Fetches a file from the given URL and returns its contents as text.\n *\n * @param {string} url - The URL to fetch the file from.\n * @returns {Promise<string>} A promise that resolves to the file contents.\n * @private\n */\nasync function fetchFile(url) {\n    try {\n        const response = await fetch(url);\n        if (!response.ok) {\n            throw new Error(`HTTP error! Status: ${response.status}`);\n        }\n        return response.text();\n    } catch (error) {\n        console.error('Error fetching file:', error);\n    }\n}\n\n/**\n * {@link Viewer} plugin that uses [CxConverter](https://github.com/Creoox/cxconverter) to load BIM models directly from IFC files, using its WebAssembly buid from [npm package](https://www.npmjs.com/package/@creooxag/cxconverter).\n *\n * ## Overview\n * The WebAssembly build of CxConverter is still in alfa stage, so it may not work as expected. This documentation will be updated as the library and the plugin evolve. The example below shows how to use the plugin:\n * ````javascript\n * import { CxConverterIFCLoaderPlugin, Viewer } from \"../../dist/xeokit-sdk.es.js\";\n * const cxConverterIFCLoaderPlugin = new CxConverterIFCLoaderPlugin(viewer);\n * \n * const sceneModel = await cxConverterIFCLoaderPlugin.load({\n *        src: \"../../assets/models/ifc/Duplex.ifc\"\n * }); \n * ````\n    See the code in action [here](https://xeokit.github.io/xeokit-sdk/examples/buildings/#cxConverterIFC_vbo_Duplex).\n */\n\nclass CxConverterIFCLoaderPlugin extends Plugin {\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} [cfg={}] Plugin configuration.\n     */\n    constructor(viewer, cfg = {}) {\n        super(\"ifcLoader\", viewer, cfg);\n\n        /**\n         * The GLTFLoaderPlugin used internally to load the converted GLTF.\n         * @type {GLTFLoaderPlugin}\n         */\n        this.gltfLoader = new GLTFLoaderPlugin(this.viewer);\n        this.cxConverterModule = null;\n    }\n\n    /**\n     * Sets the CxConverter module to be used by this plugin.\n     * @param {Object} module The CxConverter module.\n     */\n    setCxConverterModule(module) {\n        this.cxConverterModule = module;\n    }\n\n    /**\n     * Loads an IFC model from the given source.\n     *\n     * @param {Object} [params={}] Loading parameters.\n     * @param {string} params.src Path to an IFC file.\n     * @param {Function} [params.progressCallback] Callback to track loading progress.\n     * @param {Function} [params.progressTextCallback] Callback to track loading progress with text updates.\n     * @returns {Promise<SceneModel>} A promise that resolves to the loaded SceneModel.\n     */\n    async load(params = {}) {\n        if (!this.cxConverterModule) {\n            throw new Error(\"CxConverter module is not set. Use setCxConverterModule() to set it.\");\n        }\n        if (!params.src) {\n            this.error(\"load() param expected: src\");\n        }\n        const data = await fetchFile(params.src);\n        const { gltf, metaData } = await this.cxConverterModule.ifc2gltf(\n            data,\n            {\n                remote: true,\n                progressCallback: params.progressCallback,\n                progressTextCallback: params.progressTextCallback\n            }\n        );\n        const sceneModel = this.gltfLoader.load({\n            id: \"myModel\",\n            gltf: gltf,\n            metaModelJSON: metaData\n        });\n        return sceneModel;\n    }\n}\n\n/**\n * Default data access strategy for {@link IFCOpenShellLoaderPlugin}.\n *\n * This just loads assets using XMLHttpRequest.\n */\nclass IFCOpenShellDefaultDataSource {\n\n    constructor(cfg = {}) {\n        this.cacheBuster = (cfg.cacheBuster !== false);\n    }\n\n    _cacheBusterURL(url) {\n        if (!this.cacheBuster) {\n            return url;\n        }\n        const timestamp = new Date().getTime();\n        if (url.indexOf('?') > -1) {\n            return url + '&_=' + timestamp;\n        } else {\n            return url + '?_=' + timestamp;\n        }\n    }\n\n    /**\n     * Gets the contents of the given IFC file in an arraybuffer.\n     *\n     * @param {String|Number} src Path or ID of an IFC file.\n     * @param {Function} ok Callback fired on success, argument is the IFC file in an arraybuffer.\n     * @param {Function} error Callback fired on error.\n     */\n    getIFC(src, ok, error) {\n        src = this._cacheBusterURL(src);\n\n        var defaultCallback = () => {\n        };\n        ok = ok || defaultCallback;\n        error = error || defaultCallback;\n        const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n        const dataUriRegexResult = src.match(dataUriRegex);\n        if (dataUriRegexResult) { // Safari can't handle data URIs through XMLHttpRequest\n            const isBase64 = !!dataUriRegexResult[2];\n            var data = dataUriRegexResult[3];\n            data = window.decodeURIComponent(data);\n            if (isBase64) {\n                data = window.atob(data);\n            }\n            try {\n                const buffer = new ArrayBuffer(data.length);\n                const view = new Uint8Array(buffer);\n                for (var i = 0; i < data.length; i++) {\n                    view[i] = data.charCodeAt(i);\n                }\n                ok(buffer);\n            } catch (errMsg) {\n                error(errMsg);\n            }\n        } else {\n            const request = new XMLHttpRequest();\n            request.open('GET', src, true);\n            request.responseType = 'text';\n            request.onreadystatechange = function () {\n                if (request.readyState === 4) {\n                    if (request.status === 200) {\n                        ok(request.response);\n                    } else {\n                        error('getIFC error : ' + request.response);\n                    }\n                }\n            };\n            request.send(null);\n        }\n    }\n}\n\n/**\n * {@link Viewer} plugin that uses [IfcOpenShell](https://ifcopenshell.org/) to load BIM models directly from IFC files.\n *\n * <a href=\"https://xeokit.github.io/xeokit-sdk/examples/index.html#BIMOffline_IFCOpenShellLoaderPlugin_Duplex\"><img src=\"https://xeokit.io/img/docs/IFCOpenShellLoaderPlugin/IFCOpenShellLoaderPlugin.png\"></a>\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#BIMOffline_IFCOpenShellLoaderPlugin_Duplex)]\n *\n * ## Overview\n *\n * * Loads small-to-medium sized BIM models directly from IFC files.\n * * Uses [IfcOpenShell API](https://ifcopenshell.org/) to parse IFC files in the browser.\n * * Loads IFC geometry, element structure metadata, and property sets.\n * * Not for large models. For best performance with large models, we recommend using {@link XKTLoaderPlugin}.\n * * Loads double-precision coordinates, enabling models to be viewed at global coordinates without accuracy loss.\n * * Filter which IFC types don't get loaded.\n * * Configure initial appearances of specified IFC types.\n * * Set a custom data source for IFC files.\n *\n * ## Limitations\n *\n * Loading and parsing huge IFC STEP files can be slow, and can overwhelm the browser, however. To view your\n * largest IFC models, we recommend instead pre-converting those to xeokit's compressed native .XKT format, then\n * loading them with {@link XKTLoaderPlugin} instead.</p>\n *\n * ## Scene representation\n *\n * When loading a model, IFCOpenShellLoaderPlugin creates an {@link Entity} that represents the model, which\n * will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id}\n * in {@link Scene#models}. The IFCOpenShellLoaderPlugin also creates an {@link Entity} for each object within the\n * model. Those Entities will have {@link Entity#isObject} set ````true```` and will be registered\n * by {@link Entity#id} in {@link Scene#objects}.\n *\n * ## Metadata\n *\n * When loading a model, IFCOpenShellLoaderPlugin also creates a {@link MetaModel} that represents the model, which contains\n * a {@link MetaObject} for each IFC element, plus a {@link PropertySet} for each IFC property set. Loading metadata\n * can be very slow, so we can also optionally disable it if we don't need it.\n *\n * ## Usage\n *\n * In the example below we'll load the Duplex BIM model from\n * an [IFC file](https://github.com/xeokit/xeokit-sdk/tree/master/assets/models/ifc). Within our {@link Viewer}, this\n * will create a bunch of {@link Entity}s that represents the model and its objects, along with a {@link MetaModel},\n * {@link MetaObject}s and {@link PropertySet}s that hold their metadata.\n *\n * ````javascript\n * import {Viewer, IFCOpenShellLoaderPlugin, NavCubePlugin, TreeViewPlugin} from \"../../dist/xeokit-sdk.es.js\";\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // 1. Create a Viewer,\n * // 2. Arrange the camera\n * //------------------------------------------------------------------------------------------------------------------\n *\n * // 1\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * // 2\n * viewer.camera.eye = [-3.933, 2.855, 27.018];\n * viewer.camera.look = [4.400, 3.724, 8.899];\n * viewer.camera.up = [-0.018, 0.999, 0.039];\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // 1. Create the IFCOpenShellLoaderPlugin,\n * // 2. Load an IFC model\n * //------------------------------------------------------------------------------------------------------------------\n *\n * // 1\n *\n * const ifcLoader = new IFCOpenShellLoaderPlugin(viewer, {\n *     workerSrc: \"./my/directory/IFCOpenShellWorker.js\",\n *     ifcOpenShellURL: \"./my/directory/ifcopenshell-0.8.3+34a1bc6-cp313-cp313-emscripten_4_0_9_wasm32.whl\"\n * });\n *\n * // 2\n * const model = ifcLoader.load({          // Returns an Entity that represents the model\n *    id: \"myModel\",\n *    src: \"../assets/models/ifc/Duplex.ifc\",\n *    excludeTypes: [\"IfcSpace\"],\n *    edges: true\n * });\n *\n * model.on(\"loaded\", () => {\n *\n *    //----------------------------------------------------------------------------------------------------------\n *    // 1. Find metadata on the bottom storey\n *    // 2. X-ray all the objects except for the bottom storey\n *    // 3. Fit the bottom storey in view\n *    //----------------------------------------------------------------------------------------------------------\n *\n *    // 1\n *    const metaModel = viewer.metaScene.metaModels[\"myModel\"];       // MetaModel with ID \"myModel\"\n *    const metaObject\n *            = viewer.metaScene.metaObjects[\"1xS3BCk291UvhgP2dvNsgp\"];  // MetaObject with ID \"1xS3BCk291UvhgP2dvNsgp\"\n *\n *    const name = metaObject.name;                                   // \"01 eerste verdieping\"\n *    const type = metaObject.type;                                   // \"IfcBuildingStorey\"\n *    const parent = metaObject.parent;                               // MetaObject with type \"IfcBuilding\"\n *    const children = metaObject.children;                           // Array of child MetaObjects\n *    const objectId = metaObject.id;                                 // \"1xS3BCk291UvhgP2dvNsgp\"\n *    const objectIds = viewer.metaScene.getObjectIDsInSubtree(objectId);   // IDs of leaf sub-objects\n *    const aabb = viewer.scene.getAABB(objectIds);                   // Axis-aligned boundary of the leaf sub-objects\n *\n *    // 2\n *    viewer.scene.setObjectsXRayed(viewer.scene.objectIds, true);\n *    viewer.scene.setObjectsXRayed(objectIds, false);\n *\n *    // 3\n *    viewer.cameraFlight.flyTo(aabb);\n *\n *    // Find the model Entity by ID\n *    model = viewer.scene.models[\"myModel\"];\n *\n *    // Destroy the model\n *    model.destroy();\n * });\n * ````\n *\n * ## Configuring a custom data source\n *\n * By default, IFCOpenShellLoaderPlugin will load IFC files over HTTP.\n *\n * In the example below, we'll customize the way IFCOpenShellLoaderPlugin loads the files by configuring it with our own data source\n * object. For simplicity, our custom data source example also uses HTTP, using a couple of xeokit utility functions.\n *\n * ````javascript\n * import {utils} from \"xeokit-sdk.es.js\";\n *\n * class MyDataSource {\n *\n *      constructor() {\n *      }\n *\n *      // Gets the contents of the given IFC file in an arraybuffer\n *      getIFC(src, ok, error) {\n *          console.log(\"MyDataSource#getIFC(\" + IFCSrc + \", ... )\");\n *          utils.loadArraybuffer(src,\n *              (arraybuffer) => {\n *                  ok(arraybuffer);\n *              },\n *              function (errMsg) {\n *                  error(errMsg);\n *              });\n *      }\n * }\n *\n * const ifcLoader2 = new IFCOpenShellLoaderPlugin(viewer, {\n *       dataSource: new MyDataSource()\n * });\n *\n * const model5 = ifcLoader2.load({\n *      id: \"myModel5\",\n *      src: \"../assets/models/ifc/Duplex.ifc\"\n * });\n * ````\n *\n * ## Loading multiple copies of a model, without object ID clashes\n *\n * Sometimes we need to load two or more instances of the same model, without having clashes\n * between the IDs of the equivalent objects in the model instances.\n *\n * As shown in the example below, we do this by setting {@link IFCOpenShellLoaderPlugin#globalizeObjectIds} ````true```` before we load our models.\n *\n * ````javascript\n * ifcLoader.globalizeObjectIds = true;\n *\n * const model = ifcLoader.load({\n *      id: \"model1\",\n *      src: \"../assets/models/ifc/Duplex.ifc\"\n * });\n *\n * const model2 = ifcLoader.load({\n *    id: \"model2\",\n *    src: \"../assets/models/ifc/Duplex.ifc\"\n * });\n * ````\n *\n * For each {@link Entity} loaded by these two calls, {@link Entity#id} and {@link MetaObject#id} will get prefixed by\n * the ID of their model, in order to avoid ID clashes between the two models.\n *\n * An Entity belonging to the first model will get an ID like this:\n *\n * ````\n * myModel1#0BTBFw6f90Nfh9rP1dlXrb\n * ````\n *\n * The equivalent Entity in the second model will get an ID like this:\n *\n * ````\n * myModel2#0BTBFw6f90Nfh9rP1dlXrb\n * ````\n *\n * Now, to update the visibility of both of those Entities collectively, using {@link Scene#setObjectsVisible}, we can\n * supply just the IFC product ID part to that method:\n *\n * ````javascript\n * myViewer.scene.setObjectVisibilities(\"0BTBFw6f90Nfh9rP1dlXrb\", true);\n * ````\n *\n * The method, along with {@link Scene#setObjectsXRayed}, {@link Scene#setObjectsHighlighted} etc, will internally expand\n * the given ID to refer to the instances of that Entity in both models.\n *\n * We can also, of course, reference each Entity directly, using its globalized ID:\n *\n * ````javascript\n * myViewer.scene.setObjectVisibilities(\"myModel1#0BTBFw6f90Nfh9rP1dlXrb\", true);\n *````\n *\n * @class IFCOpenShellLoaderPlugin\n * @since 2.6.90\n */\nclass IFCOpenShellLoaderPlugin extends Plugin {\n\n    /**\n     * @param {Viewer} viewer The {@link Viewer} that will own this plugin.\n     * @param {Object} cfg Plugin configuration.\n     * @param {String} [cfg.id=\"IFCOpenShellLoader\"] Optional ID for this plugin instance.\n     * @param {Object} [cfg.dataSource] Custom data source (defaults to {@link IFCOpenShellDefaultDataSource}).\n     * @param {Object} cfg.ifcopenshell IfcOpenShell API object.\n     * @param {Object} cfg.ifcopenshell_geom IfcOpenShell geometry API object.\n     */\n    constructor(viewer, cfg) {\n\n        super(\"IFCOpenShellLoader\", viewer, cfg);\n\n        if (!cfg) {\n            throw new Error(\"IFCOpenShellLoaderPlugin: No configuration given\");\n        }\n\n        if (!cfg.ifcopenshell) {\n            throw new Error(\"IFCOpenShellLoaderPlugin: No ifcopenshell given\");\n        }\n\n        if (!cfg.ifcopenshell_geom) {\n            throw new Error(\"IFCOpenShellLoaderPlugin: No ifcopenshell_geom given\");\n        }\n\n        this.ifcopenshell = cfg.ifcopenshell;\n        this.ifcopenshell_geom = cfg.ifcopenshell_geom;\n\n        this.dataSource = cfg.dataSource;\n    }\n\n    /**\n     * Sets a custom data source for IFC files.\n     * @param value\n     */\n    set dataSource(value) {\n        this._dataSource = value || new IFCOpenShellDefaultDataSource();\n    }\n\n    /**\n     * Gets the data source for IFC files.\n     * @returns {*|IFCOpenShellDefaultDataSource}\n     */\n    get dataSource() {\n        return this._dataSource;\n    }\n\n    /**\n     * Gets whether IFCOpenShellLoaderPlugin globalizes each {@link Entity#id} and {@link MetaObject#id} as it loads a model.\n     *\n     * Default value is ````false````.\n     *\n     * @type {Boolean}\n     */\n    get globalizeObjectIds() {\n        return this._globalizeObjectIds;\n    }\n\n    /**\n     * Sets whether IFCOpenShellLoaderPlugin globalizes each {@link Entity#id} and {@link MetaObject#id} as it loads a model.\n     *\n     * Set  this ````true```` when you need to load multiple instances of the same model, to avoid ID clashes\n     * between the objects in the different instances.\n     *\n     * When we load a model with this set ````true````, then each {@link Entity#id} and {@link MetaObject#id} will be\n     * prefixed by the ID of the model, ie. ````<modelId>#<objectId>````.\n     *\n     * {@link Entity#originalSystemId} and {@link MetaObject#originalSystemId} will always hold the original, un-prefixed, ID values.\n     *\n     * Default value is ````false````.\n     *\n     * See the main {@link IFCOpenShellLoaderPlugin} class documentation for usage info.\n     *\n     * @type {Boolean}\n     */\n    set globalizeObjectIds(value) {\n        this._globalizeObjectIds = !!value;\n    }\n\n    /**\n     * Loads an IFC model from a file or text into the {@link Viewer}.\n     *\n     * @param {Object} params\n     * @param {String} [params.id] Optional root Entity ID.\n     * @param {String} [params.src] IFC file path (alternative to `text`).\n     * @param {String} [params.text] IFC text (alternative to `src`).\n     * @param {{String:Object}} [params.objectDefaults]\n     * @param {String[]} [params.excludeTypes] Array of IFC types to exclude.\n     * @param {Number[]} [params.origin=[0,0,0]] Optional World-coordinate origin to apply to the model.\n     * @param {Number[]} [params.position=[0,0,0]] Optional position offset to apply to the model.\n     * @param {Number[]} [params.rotation=[0,0,0]] Optional XYZ Euler rotation (degrees) to apply to the model.\n     * @param {Boolean} [params.backfaces=true] Whether to render backfaces.\n     * @param {Boolean} [params.dtxEnabled=true] Whether to enable data texture storage for geometry buffers.\n     * @param {Boolean} [params.loadMetadata=true] Whether to load metadata.\n     * @param {Boolean} [params.loadMetadataPropertySets=true] Whether to load property sets within the metadata. Only works when `loadMetadata` is true.\n     * @param {Boolean} [params.edges=false] Whether to generate edge lines for the model.\n     * @param {Boolean} [params.saoEnabled=false] Whether to enable SAO for the model.\n     * @param {Boolean} [params.globalizeObjectIds=false] Whether to globalize each {@link Entity#id} and {@link MetaObject#id} as it loads the model.\n     * @returns {Entity}\n     */\n    async load(params = {}) {\n\n        let {\n            id,\n            backfaces = true,\n            dtxEnabled = true,\n            position,\n            rotation,\n            origin,\n            loadMetadata,\n            loadMetadataPropertySets,\n            edges,\n            saoEnabled,\n            globalizeObjectIds,\n            excludeTypes\n        } = params;\n\n        if (id && this.viewer.scene.components[id]) {\n            this.error(`Component with this ID already exists: ${id} - autogenerating SceneModel ID`);\n            id = null;\n        }\n\n        const sceneModel = new SceneModel(this.viewer.scene, {\n            id,\n            isModel: true,\n            globalizeObjectIds,\n            backfaces,\n            dtxEnabled,\n            position,\n            rotation,\n            origin,\n            edges,\n            saoEnabled\n        });\n\n        const modelId = sceneModel.id;\n\n        if (!params.src && !params.text) {\n            this.error(\"load() expected 'src' or 'text'\");\n            return sceneModel; // Return empty model\n        }\n\n        const spinner = this.viewer.scene.canvas.spinner;\n        spinner.processes++;\n\n        const loadIFC = (fileData) => {\n            const ifc = this.ifcopenshell.file.from_string(fileData);\n            const ctx = {\n                loadMetadataPropertySets: (loadMetadataPropertySets !== false),\n                globalizeObjectIds: globalizeObjectIds || this._globalizeObjectIds,\n                geometryCache: new Map(),\n                ifc,\n                sceneModel\n            };\n            if (excludeTypes) {\n                ctx.excludeTypes = excludeTypes;\n            }\n            this._loadIFCGeometry(ctx);\n            if (loadMetadata !== false) {\n                const metaModelData = this._loadIFCMetaModel(ctx, ifc);\n                this.viewer.metaScene.createMetaModel(modelId, metaModelData);\n            }\n            this.viewer.scene.canvas.spinner.processes--;\n        };\n\n        if (params.src) {\n            this.viewer.scene.canvas.spinner.processes++;\n            this._dataSource.getIFC(\n                params.src,\n                (fileData) => {\n                    loadIFC(fileData);\n                    this.viewer.scene.canvas.spinner.processes--;\n                },\n                (err) => {\n                    this.viewer.scene.canvas.spinner.processes--;\n                    this.error(err);\n                }\n            );\n        } else {\n            loadIFC(params.text);\n        }\n\n        sceneModel.once(\"destroyed\", () => {\n            this.viewer.metaScene.destroyMetaModel(modelId);\n        });\n\n        return sceneModel;\n    }\n\n    _loadIFCGeometry(ctx) {\n        const {ifc, sceneModel} = ctx;\n        const {ifcopenshell_geom} = this;\n\n        const settings = ifcopenshell_geom.settings();\n        settings.set(settings.WELD_VERTICES, false);\n\n        const iterator = ifcopenshell_geom.iterator.callKwargs({\n            settings,\n            file_or_filename: ifc,\n            exclude: ctx.excludeTypes,\n            geometry_library: \"hybrid-cgal-simple-opencascade\"\n        });\n\n        if (iterator.initialize()) {\n            do {\n                const obj = iterator.get();\n                if (obj) {\n                    const entity = ifc.by_id(obj.id);\n                    this._parseIFCEntity(ctx, obj, entity);\n                }\n            } while (iterator.next());\n        }\n\n        sceneModel.finalize();\n\n        sceneModel.scene.once(\"tick\", () => {\n            if (!sceneModel.destroyed) {\n                sceneModel.scene.fire(\"modelLoaded\", sceneModel.id);\n                sceneModel.fire(\"loaded\", true, false);\n            }\n        });\n    }\n\n    _parseIFCEntity(ctx, obj, ifcEntity) {\n        const {sceneModel, geometryCache} = ctx;\n        const geometry_id = obj.geometry.id;\n\n        const M = obj.transformation.data().components.toJs();\n        const {origin, matrix} = extractRTCTransform(M);\n\n        if (!geometryCache.get(geometry_id)) {\n\n            const srcMaterials = obj.geometry.materials.toJs();\n            const materials = srcMaterials.map((m) => ({\n                diffuse: m.diffuse.components.toJs(),\n                transparency: (m.transparency\n                    && !isNaN(m.transparency)) ? m.transparency : 0.0,\n            }));\n\n            const materialIds = new Int32Array(obj.geometry.material_ids.toJs());\n\n            // Build mapping: materialIndex -> [faceIdx...]\n            const mapping = buildMaterialMapping(materialIds);\n\n            // Create sub-geometry per materialIndex, once\n            const subGeoms = new Map();\n\n            for (const [matIndexStr, faceList] of Object.entries(mapping)) {\n\n                if (!faceList || faceList.length === 0) {\n                    continue;\n                }\n\n                // xeokit auto-generates normals on the GPU side\n\n                const positions = new Float32Array(obj.geometry.verts.toJs());\n                const edgeIndices = new Uint32Array(obj.geometry.edges.toJs());\n                const faces = new Uint32Array(obj.geometry.faces.toJs());\n                const matIndex = Number(matIndexStr);\n                const indices = buildIndicesForFaces(faceList, faces);\n                const sceneGeometryId = makeSubGeometryId(geometry_id, matIndex); // deterministic\n\n                sceneModel.createGeometry({\n                    id: sceneGeometryId,\n                    primitive: \"triangles\",\n                    positions,\n                    indices,\n                    edgeIndices\n                });\n\n                subGeoms.set(matIndex, sceneGeometryId);\n            }\n\n            geometryCache.set(geometry_id, {\n                subGeoms,\n                materials,\n                // store mapping as Map<number, Uint32Array> to avoid recomputing\n                mapping: new Map(Object.entries(mapping).map(\n                    ([k, v]) => [Number(k), new Uint32Array(v)]\n                ))\n            });\n        }\n\n        // Reuse cached sub-geometries to create per-object meshes\n\n        const cached = geometryCache.get(geometry_id);\n        const meshIds = [];\n\n        for (const [matIndex, sceneGeometryId] of cached.subGeoms.entries()) {\n            const material = cached.materials[matIndex] || {diffuse: [0.6, 0.6, 0.6], transparency: 0.0};\n            const meshId = generateUUID();\n            const diffuse = material.diffuse;\n            sceneModel.createMesh({\n                id: meshId,\n                geometryId: sceneGeometryId,\n                origin,\n                matrix,\n                color: [diffuse[0], diffuse[1], diffuse[2]],\n                opacity: 1.0 - material.transparency\n            });\n            meshIds.push(meshId);\n        }\n\n        sceneModel.createEntity({\n            id: ctx.globalizeObjectIds ? math.globalizeObjectId(ctx.sceneModel.id, ifcEntity.GlobalId) : ifcEntity.GlobalId,\n            isObject: true,\n            meshIds\n        });\n    }\n\n    _loadIFCMetaModel(ctx, ifc) {\n\n        const visited = new Set();\n        const metaObjects = [];\n        const propertySets = [];\n\n        // ---- helpers -----------------------------------------------------------\n        const toStr = (v) => (v === undefined || v === null) ? \"\" : String(v);\n\n        function getGlobalId(entity) {\n            try {\n                return String(entity.GlobalId);\n            } catch {\n                return null;\n            }\n        }\n\n        function addNode(entity, parent) {\n            const id = getGlobalId(entity);\n            if (!id || visited.has(id)) return false;\n            visited.add(id);\n            const globalizeObjectIds = ctx.globalizeObjectIds;\n            const modelId = ctx.sceneModel.id;\n            const propertySetIds = [];\n            if (ctx.loadMetadataPropertySets) {\n                // Try all possible association fields\n                const associationFields = [\"HasAssociations\", \"IsDefinedBy\", \"IsDecomposedBy\", \"ContainsElements\"];\n                for (const field of associationFields) {\n                    const associations = entity[field];\n                    if (associations && associations.length > 0) {\n                        for (let j = 0; j < associations.length; j++) {\n                            const rel = associations.get(j);\n                            if (rel.is_a && rel.is_a() === \"IfcRelDefinesByProperties\") {\n                                const propSet = rel.RelatingPropertyDefinition;\n                                if (propSet && propSet.is_a) {\n                                    // Accept both IfcPropertySet and IfcElementQuantity\n                                    if ([\"IfcPropertySet\", \"IfcElementQuantity\"].includes(propSet.is_a())) {\n                                        const propSetId = propSet.GlobalId ? String(propSet.GlobalId) : null;\n                                        const propSetName = propSet.Name ? String(propSet.Name) : \"\";\n                                        const propSetType = propSet.is_a ? String(propSet.is_a()) : \"\";\n                                        const properties = [];\n                                        const props = propSet.HasProperties || propSet.Quantities;\n                                        if (props && props.length > 0) {\n                                            for (let k = 0; k < props.length; k++) {\n                                                const p = props.get(k);\n                                                const propName = p.Name ? String(p.Name) : \"\";\n                                                let propValue = \"\";\n                                                let propType = p.is_a ? String(p.is_a()) : \"\";\n                                                if (p.is_a && p.is_a() === \"IfcPropertySingleValue\") {\n                                                    try {\n                                                        propValue = p.NominalValue ? String(p.NominalValue.wrappedValue) : \"\";\n                                                    } catch {\n                                                        propValue = \"\";\n                                                    }\n                                                } else if (p.is_a && p.is_a() === \"IfcPropertyEnumeratedValue\") {\n                                                    try {\n                                                        const values = p.EnumerationValues;\n                                                        if (values && values.length > 0) {\n                                                            const arr = [];\n                                                            for (let vi = 0; vi < values.length; vi++) {\n                                                                arr.push(String(values.get(vi).wrappedValue));\n                                                            }\n                                                            propValue = arr.join(\", \");\n                                                        }\n                                                    } catch {\n                                                        propValue = \"\";\n                                                    }\n                                                } else if (p.is_a && p.is_a() === \"IfcQuantityArea\") {\n                                                    propValue = p.AreaValue ? String(p.AreaValue) : \"\";\n                                                } else if (p.is_a && p.is_a() === \"IfcQuantityLength\") {\n                                                    propValue = p.LengthValue ? String(p.LengthValue) : \"\";\n                                                } else if (p.is_a && p.is_a() === \"IfcQuantityVolume\") {\n                                                    propValue = p.VolumeValue ? String(p.VolumeValue) : \"\";\n                                                } else {\n                                                    try {\n                                                        propValue = p.NominalValue ? String(p.NominalValue) : \"\";\n                                                    } catch {\n                                                        propValue = \"\";\n                                                    }\n                                                }\n                                                properties.push({\n                                                    name: propName,\n                                                    value: propValue,\n                                                    type: propType\n                                                });\n                                                p.destroy?.();\n                                            }\n                                            props.destroy?.();\n                                        }\n                                        propertySets.push({\n                                            id: propSetId,\n                                            //    objectId: ctx.globalizeObjectIds ? math.globalizeObjectId(ctx.sceneModel.id, objectId) : objectId,\n                                            name: propSetName,\n                                            type: propSetType,\n                                            properties\n                                        });\n                                        propertySetIds.push(propSetId);\n                                        propSet.destroy?.();\n                                    }\n                                }\n                                rel.destroy?.();\n                            }\n                        }\n                        associations.destroy?.();\n                    }\n                }\n            }\n            metaObjects.push({\n                id: globalizeObjectIds ? math.globalizeObjectId(modelId, id) : id,\n                type: String(entity.is_a()),\n                parent: parent\n                    ? (globalizeObjectIds\n                        ? math.globalizeObjectId(modelId, getGlobalId(parent))\n                        : getGlobalId(parent))\n                    : null,\n                propertySetIds\n            });\n            return true;\n        }\n\n        function walk(entity, parent = null) {\n            if (!entity) return;\n\n            // add current node (skip children if already visited)\n            if (!addNode(entity, parent)) {\n                entity.destroy?.();\n                return;\n            }\n\n            // 1) Decomposition (IfcRelAggregates / IfcRelNests)\n            const decos = entity.IsDecomposedBy;\n            if (decos) {\n                for (let i = 0; i < decos.length; i++) {\n                    const rel = decos.get(i);\n                    const children = rel.RelatedObjects;\n                    if (children) {\n                        for (let j = 0; j < children.length; j++) {\n                            const child = children.get(j);\n                            walk(child, entity);\n                            child.destroy?.();\n                        }\n                        children.destroy?.();\n                    }\n                    rel.destroy?.();\n                }\n            }\n\n            // 2) Spatial containment (IfcRelContainedInSpatialStructure)\n            const contains = entity.ContainsElements;\n            if (contains) {\n                for (let i = 0; i < contains.length; i++) {\n                    const rel = contains.get(i);\n                    const elems = rel.RelatedElements;\n                    if (elems) {\n                        for (let j = 0; j < elems.length; j++) {\n                            const elem = elems.get(j);\n                            walk(elem, entity);\n                            elem.destroy?.();\n                        }\n                        elems.destroy?.();\n                    }\n                    rel.destroy?.();\n                }\n            }\n\n            entity.destroy?.();\n        }\n\n        // ---- metadata extraction ----------------------------------------------\n        let projectId = \"\";\n        let author = \"\";\n        let createdAt = \"\"; // ISO string\n        let schema = \"\";\n        let creatingApplication = \"\";\n\n        // Schema (primary)\n        try {\n            // ifcopenshell.file usually exposes a `schema` string property\n            schema = toStr(ifc.schema);\n        } catch {\n        }\n        if (!schema) {\n            // Fallback to STEP header\n            try {\n                const ids = ifc.wrapped_data.header.file_schema.schema_identifiers;\n                if (ids && ids.length > 0) schema = toStr(ids.get(0));\n            } catch {\n            }\n        }\n\n        // Project (also gives us OwnerHistory on many files)\n        const projects = ifc.by_type(\"IfcProject\");\n        if (projects && projects.length > 0) {\n            const project = projects.get(0);\n            projectId = toStr(project.GlobalId);\n\n            // OwnerHistory path (preferred when present)\n            try {\n                const oh = project.OwnerHistory; // deprecated in newer IFC4.x, but present in many files\n                if (oh) {\n                    // Author: IfcPersonAndOrganization → ThePerson (GivenName/FamilyName) and TheOrganization.Name\n                    try {\n                        const user = oh.OwningUser;\n                        const person = user?.ThePerson;\n                        const org = user?.TheOrganization;\n                        const gn = person?.GivenName ? toStr(person.GivenName) : \"\";\n                        const fn = person?.FamilyName ? toStr(person.FamilyName) : \"\";\n                        const personName = (gn || fn) ? [gn, fn].filter(Boolean).join(\" \") : \"\";\n                        const orgName = org?.Name ? toStr(org.Name) : \"\";\n                        author = [personName, orgName].filter(Boolean).join(\" / \");\n                    } catch {\n                    }\n\n                    // Creation time (UNIX seconds)\n                    try {\n                        const ts = oh?.CreationDate;\n                        if (typeof ts === \"number\" && isFinite(ts) && ts > 0) {\n                            createdAt = new Date(ts * 1000).toISOString();\n                        }\n                    } catch {\n                    }\n\n                    // Creating application\n                    try {\n                        const app = oh?.OwningApplication;\n                        const appName =\n                            app?.ApplicationFullName ? toStr(app.ApplicationFullName) :\n                                app?.ApplicationIdentifier ? toStr(app.ApplicationIdentifier) : \"\";\n                        const appVer = app?.Version ? toStr(app.Version) : \"\";\n                        creatingApplication = [appName, appVer].filter(Boolean).join(\" \");\n                    } catch {\n                    }\n                }\n            } catch {\n            }\n\n            // Clean first project (we’ll traverse below with a fresh pointer anyway)\n            project.destroy?.();\n        }\n\n        // Fallbacks via STEP header if OwnerHistory wasn’t there / incomplete\n        try {\n            const fileName = ifc.wrapped_data.header.file_name;\n            if (!author) {\n                try {\n                    const authors = fileName.author;\n                    if (authors && authors.length > 0) {\n                        // `author` is a LIST in the STEP header; join if multiple\n                        const parts = [];\n                        for (let i = 0; i < authors.length; i++) parts.push(toStr(authors.get(i)));\n                        author = parts.filter(Boolean).join(\", \");\n                    }\n                } catch {\n                }\n            }\n            if (!createdAt) {\n                const ts = toStr(fileName.time_stamp); // already a string like \"2023-08-10T12:34:56\"\n                if (ts) {\n                    // normalize to ISO if possible\n                    const maybe = new Date(ts);\n                    if (!isNaN(maybe.getTime())) createdAt = maybe.toISOString();\n                }\n            }\n            if (!creatingApplication) {\n                // STEP header carries \"originating_system\" and \"preprocessor_version\"\n                const orig = toStr(fileName.originating_system);\n                const prep = toStr(fileName.preprocessor_version);\n                creatingApplication = [orig, prep].filter(Boolean).join(\" / \");\n            }\n        } catch {\n        }\n\n        // If createdAt still missing, sweep for earliest OwnerHistory timestamp across roots\n        if (!createdAt) {\n            try {\n                let minTs = Infinity;\n                const roots = ifc.by_type(\"IfcRoot\");\n                for (let i = 0; i < roots.length; i++) {\n                    const r = roots.get(i);\n                    const oh = r?.OwnerHistory;\n                    const ts = oh?.CreationDate;\n                    if (typeof ts === \"number\" && isFinite(ts) && ts > 0 && ts < minTs) {\n                        minTs = ts;\n                    }\n                    r.destroy?.();\n                }\n                roots.destroy?.();\n                if (isFinite(minTs)) createdAt = new Date(minTs * 1000).toISOString();\n            } catch {\n            }\n        }\n\n        // ---- hierarchy walk ----------------------------------------------------\n        // Re-query projects since we destroyed the first pointer above\n        const projects2 = ifc.by_type(\"IfcProject\");\n        for (let i = 0; i < projects2.length; i++) {\n            const project = projects2.get(i);\n            walk(project, null);\n            project.destroy?.();\n        }\n        projects2.destroy?.();\n\n        return {\n            id: \"\",\n            projectId,\n            author,\n            createdAt,\n            schema,\n            creatingApplication,\n            metaObjects,\n            propertySets\n        };\n    }\n\n    /**\n     * Destroys this IFCOpenShellLoaderPlugin instance.\n     */\n    destroy() {\n        super.destroy();\n    }\n}\n\nfunction makeSubGeometryId(geometry_id, matIndex) {\n    return `${geometry_id}:${matIndex}#geom`;\n}\n\nfunction buildMaterialMapping(materialIds) {\n    const mapping = {};\n    for (let faceIdx = 0; faceIdx < materialIds.length; faceIdx++) {\n        const materialId = materialIds[faceIdx];\n        if (materialId == null || materialId < 0) continue; // skip invalid / missing\n        (mapping[materialId] ||= []).push(faceIdx);\n    }\n    return mapping;\n}\n\nfunction buildIndicesForFaces(faceList, faceIndices) {\n    const indices = new Uint32Array(faceList.length * 3);\n    let k = 0;\n    for (const faceIdx of faceList) {\n        const base = faceIdx * 3;\n        indices[k++] = faceIndices[base + 0];\n        indices[k++] = faceIndices[base + 1];\n        indices[k++] = faceIndices[base + 2];\n    }\n    return indices;\n}\n\nfunction generateUUID() {\n    return Math.random().toString(36).substr(2, 9);\n}\n\nfunction extractRTCTransform(transform) {\n    const matrix = flattenMatrixArray(transform);\n    const origin = [];\n    const worldOrigin = matrix.slice(12, 15); // translation xyz\n    worldToRTCPositions(worldOrigin, worldOrigin, origin);\n    matrix.set(worldOrigin, 12);\n    return {origin, matrix};\n}\n\nfunction flattenMatrixArray(m) {\n    return new Float64Array([\n        m[0][0], m[2][0], -m[1][0], m[3][0],\n        m[0][1], m[2][1], -m[1][1], m[3][1],\n        m[0][2], m[2][2], -m[1][2], m[3][2],\n        m[0][3], m[2][3], -m[1][3], m[3][3]\n    ]);\n}\n\n/**\n * Default data access strategy for {@link LASLoaderPlugin}.\n */\nclass LASDefaultDataSource {\n\n    constructor(cfg = {}) {\n        this.cacheBuster = (cfg.cacheBuster !== false);\n    }\n\n    _cacheBusterURL(url) {\n        if (!this.cacheBuster) {\n            return url;\n        }\n        const timestamp = new Date().getTime();\n        if (url.indexOf('?') > -1) {\n            return url + '&_=' + timestamp;\n        } else {\n            return url + '?_=' + timestamp;\n        }\n    }\n\n    /**\n     * Gets the contents of the given LAS file in an arraybuffer.\n     *\n     * @param {String|Number} src Path or ID of an LAS file.\n     * @param {Function} ok Callback fired on success, argument is the LAS file in an arraybuffer.\n     * @param {Function} error Callback fired on error.\n     */\n    getLAS(src, ok, error) {\n        src = this._cacheBusterURL(src);\n        var defaultCallback = () => {\n        };\n        ok = ok || defaultCallback;\n        error = error || defaultCallback;\n        const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n        const dataUriRegexResult = src.match(dataUriRegex);\n        if (dataUriRegexResult) { // Safari can't handle data URIs through XMLHttpRequest\n            const isBase64 = !!dataUriRegexResult[2];\n            var data = dataUriRegexResult[3];\n            data = window.decodeURIComponent(data);\n            if (isBase64) {\n                data = window.atob(data);\n            }\n            try {\n                const buffer = new ArrayBuffer(data.length);\n                const view = new Uint8Array(buffer);\n                for (var i = 0; i < data.length; i++) {\n                    view[i] = data.charCodeAt(i);\n                }\n                ok(buffer);\n            } catch (errMsg) {\n                error(errMsg);\n            }\n        } else {\n            const request = new XMLHttpRequest();\n            request.open('GET', src, true);\n            request.responseType = 'arraybuffer';\n            request.onreadystatechange = function () {\n                if (request.readyState === 4) {\n                    if (request.status === 200) {\n                        ok(request.response);\n                    } else {\n                        error('getLAS error : ' + request.response);\n                    }\n                }\n            };\n            request.send(null);\n        }\n    }\n\n    getManifest(manifestSrc, ok, error) {\n        utils.loadJSON(this._cacheBusterURL(manifestSrc),\n            (json) => {\n                ok(json);\n            },\n            function (errMsg) {\n                error(errMsg);\n            });\n    }\n}\n\n//import * as epsgCheck from 'epsg-index/all.json';\n\nconst headerBlockItems = [\n    {item: 'FileSignature', format: 'char', size: 4},\n    {item: 'FileSoureceID', format: 'uShort', size: 2},\n    {item: 'GlobalEncoding', format: 'uShort', size: 2},\n    {item: 'ProjectID1', format: 'notUsed', size: 4},\n    {item: 'ProjectID2', format: 'notUsed', size: 2},\n    {item: 'ProjectID3', format: 'notUsed', size: 2},\n    {item: 'ProjectID4', format: 'notUsed', size: 8},\n    {item: 'VersionMajor', format: 'uChar', size: 1},\n    {item: 'VersionMinor', format: 'uChar', size: 1},\n    {item: 'SystemIdentifier', format: 'char', size: 32},\n    {item: 'GeneratingSoftware', format: 'char', size: 32},\n    {item: 'CreationDay', format: 'uShort', size: 2},\n    {item: 'CreationYear', format: 'uShort', size: 2},\n    {item: 'HeaderSize', format: 'uShort', size: 2},\n    {item: 'OffsetToPointData', format: 'uLong', size: 4},\n    {item: 'NumberOfVariableLengthRecords', format: 'uLong', size: 4},\n    {item: 'PointDataFormatID', format: 'uChar', size: 1},\n    {item: 'PointDataRecordLength', format: 'uShort', size: 2},\n    {item: 'NumberOfPoints', format: 'uLong', size: 4},\n    {item: 'NumberOfPointByReturn', format: 'uLong', size: 20},\n    {item: 'ScaleFactorX', format: 'double', size: 8},\n    {item: 'ScaleFactorY', format: 'double', size: 8},\n    {item: 'ScaleFactorZ', format: 'double', size: 8},\n    {item: 'OffsetX', format: 'double', size: 8},\n    {item: 'OffsetY', format: 'double', size: 8},\n    {item: 'OffsetZ', format: 'double', size: 8},\n    {item: 'MaxX', format: 'double', size: 8},\n    {item: 'MinX', format: 'double', size: 8},\n    {item: 'MaxY', format: 'double', size: 8},\n    {item: 'MinY', format: 'double', size: 8},\n    {item: 'MaxZ', format: 'double', size: 8},\n    {item: 'MinZ', format: 'double', size: 8},\n];\n\nconst variableLengthRecord = [\n    {item: 'Reserved', format: 'uShort', size: 2},\n    {item: 'UserId', format: 'char', size: 16},\n    {item: 'RecordId', format: 'uShort', size: 2},\n    {item: 'RecordLengthAfterHeader', format: 'uShort', size: 2},\n    {item: 'Description', format: 'char', size: 32},\n];\n\n/**\n * @private\n * @param arrayBuffer\n * @returns {{}}\n */\nconst loadLASHeader = (arrayBuffer) => {\n\n    let currentByte = 0;\n    let numOfVarLenRecords = 0;\n    let projectionStart = 0;\n\n    const dataView = new DataView(arrayBuffer);\n    const buffer = new Uint8Array(6000);\n\n    const getGeoKeys = (geoRecord) => {\n        if (geoRecord === undefined) {\n            return undefined;\n        }\n        const projectionEnd = projectionStart + geoRecord[\"RecordLengthAfterHeader\"];\n        const geoTag = buffer.slice(projectionStart, projectionEnd);\n        const arrayBuffer = bufferFlipper(geoTag);\n        const dataView = new DataView(arrayBuffer);\n        let byteCount = 6;\n        let numberOfKeys = Number(dataView.getUint16(byteCount, true));\n        const geoKeys = [];\n        while (numberOfKeys--) {\n            const keyTmp = {};\n            keyTmp.key = dataView.getUint16(byteCount += 2, true);\n            keyTmp.tiffTagLocation = dataView.getUint16(byteCount += 2, true);\n            keyTmp.count = dataView.getUint16(byteCount += 2, true);\n            keyTmp.valueOffset = dataView.getUint16(byteCount += 2, true);\n            geoKeys.push(keyTmp);\n        }\n        const projRecord = geoKeys.find(x => x.key === 3072);\n        if (projRecord && projRecord.hasOwnProperty('valueOffset')) {\n            const epsg = projRecord.valueOffset;\n            {\n                return epsg;\n            }\n        }\n        return undefined;\n    };\n\n    const getValue = ({item, format, size}) => {\n        let str, array;\n        switch (format) {\n            case 'char':\n                array = new Uint8Array(arrayBuffer, currentByte, size);\n                currentByte += size;\n                str = uint8arrayToString(array);\n                return [item, str];\n            case 'uShort':\n                str = dataView.getUint16(currentByte, true);\n                currentByte += size;\n                return [item, str];\n            case 'uLong':\n                str = dataView.getUint32(currentByte, true);\n                if (item === 'NumberOfVariableLengthRecords') {\n                    numOfVarLenRecords = str;\n                }\n                currentByte += size;\n                return [item, str];\n            case 'uChar':\n                str = dataView.getUint8(currentByte);\n                currentByte += size;\n                return [item, str];\n            case 'double':\n                str = dataView.getFloat64(currentByte, true);\n                currentByte += size;\n                return [item, str];\n            default:\n                currentByte += size;\n        }\n    };\n\n    const getValues = () => {\n        const publicHeaderBlock = {};\n        headerBlockItems.forEach((obj) => {\n            const myObj = getValue({...obj});\n            if (myObj !== undefined) {\n                if (myObj[0] === 'FileSignature' && myObj[1] !== 'LASF') {\n                    throw new Error('Ivalid FileSignature. Is this a LAS/LAZ file');\n                }\n                publicHeaderBlock[myObj[0]] = myObj[1];\n            }\n        });\n        const variableRecords = [];\n        let variableLengthRecords = numOfVarLenRecords;\n        while (variableLengthRecords--) {\n            const variableObj = {};\n            variableLengthRecord.forEach((obj) => {\n                const myObj = getValue({...obj});\n                variableObj[myObj[0]] = myObj[1];\n                if (myObj[0] === 'UserId' && myObj[1] === 'LASF_Projection') {\n                    projectionStart = currentByte - 18 + 54;\n                }\n            });\n            variableRecords.push(variableObj);\n        }\n        const geoRecord = variableRecords.find(x => x.UserId === 'LASF_Projection');\n        const epsg = getGeoKeys(geoRecord);\n        if (epsg) {\n            publicHeaderBlock['epsg'] = epsg;\n        }\n        return publicHeaderBlock;\n    };\n\n    return getValues();\n};\n\nconst bufferFlipper = (buf) => {\n    let ab = new ArrayBuffer(buf.length);\n    let view = new Uint8Array(ab);\n    for (let i = 0; i < buf.length; ++i) {\n        view[i] = buf[i];\n    }\n    return ab;\n};\n\nconst uint8arrayToString = (array) => {\n    let str = '';\n    array.forEach((item) => {\n        let c = String.fromCharCode(item);\n        if (c !== '\\u0000') {\n            str += c;\n        }\n    });\n    return str.trim();\n};\n\nconst MAX_VERTICES = 500000; // TODO: Rough estimate\n\n/**\n * {@link Viewer} plugin that loads lidar point cloud geometry from LAS files.\n *\n * <a href=\"https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_LASLoaderPlugin_Autzen\"><img src=\"https://xeokit.github.io/xeokit-sdk/assets/images/autzen.png\"></a>\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_LASLoaderPlugin_Autzen)]\n *\n * ## Summary\n *\n * * Loads [LAS Formats](https://www.asprs.org/divisions-committees/lidar-division/laser-las-file-format-exchange-activities) up to v1.3 from both *.las* and *.laz* files. It does not support LAS v1.4.\n * * Loads lidar point cloud positions, colors and intensities.\n * * Supports 32 and 64-bit positions.\n * * Supports 8 and 16-bit color depths.\n * * Option to load every *n* points.\n * * Does not (yet) load [point classifications](https://www.usna.edu/Users/oceano/pguth/md_help/html/las_format_classification_codes.htm).\n *\n * ## Performance\n *\n * If you need faster loading, consider pre-converting your LAS files to XKT format using [xeokit-convert](https://github.com/xeokit/xeokit-convert), then loading them\n * with {@link XKTLoaderPlugin}.\n *\n * ## Scene and metadata representation\n *\n * When LASLoaderPlugin loads a LAS file, it creates two {@link Entity}s, a {@link MetaModel} and a {@link MetaObject}.\n *\n * The first Entity represents the file as a model within the Viewer's {@link Scene}. To indicate that it represents a model,\n * this Entity will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.\n *\n * The second Entity represents the the point cloud itself, as an object within the Scene. To indicate that it\n * represents an object, this Entity will have {@link Entity#isObject} set ````true```` and will be registered\n * by {@link Entity#id} in {@link Scene#objects}.\n *\n * The MetaModel registers the LAS file as a model within the Viewer's {@link MetaScene}. The MetaModel will be registered\n * by {@link MetaModel#id} in {@link MetaScene#metaModels} .\n *\n * Finally, the MetaObject registers the point cloud as an object within the {@link MetaScene}. The MetaObject will be registered\n * by {@link MetaObject#id} in {@link MetaScene#metaObjects}.\n *\n * ## Usage\n *\n * In the example below we'll load the Autzen model from\n * a [LAS file](/assets/models/las/). Once the model has\n * loaded, we'll then find its {@link MetaModel}, and the {@link MetaObject} and {@link Entity} that represent its point cloud.\n *\n * * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_LASLoaderPlugin_Autzen)]\n *\n * ````javascript\n * import {Viewer, LASLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * viewer.camera.eye = [-2.56, 8.38, 8.27];\n * viewer.camera.look = [13.44, 3.31, -14.83];\n * viewer.camera.up = [0.10, 0.98, -0.14];\n *\n * const lasLoader = new LASLoaderPlugin(viewer, {\n *     colorDepth: 8, // Default\n *     fp64: false,   // Default\n *     skip: 1        // Default\n * });\n *\n * const modelEntity = lasLoader.load({\n *     id: \"myModel\",\n *     src: \"../assets/models/las/autzen.laz\"\n * });\n *\n * modelEntity.on(\"loaded\", () => {\n *\n *      const metaModel = viewer.metaScene.metaModels[modelEntity.id];\n *      const pointCloudMetaObject = metaModel.rootMetaObject;\n *\n *      const pointCloudEntity = viewer.scene.objects[pointCloudMetaObject.id];\n *\n *      //...\n * });\n * ````\n *\n * ## Transforming\n *\n * We have the option to rotate, scale and translate each LAS model as we load it.\n *\n * In the example below, we'll scale our model to half its size, rotate it 90 degrees about its local X-axis, then\n * position it at [1842022, 10, -5173301] within xeokit's world coordinate system.\n *\n * ````javascript\n * const modelEntity = lasLoader.load({\n *      id: \"myModel\",\n *      src: \"../assets/models/las/autzen.laz\"\n *      rotation: [90,0,0],\n *      scale: [0.5, 0.5, 0.5],\n *      origin: [1842022, 10, -5173301]\n * });\n * ````\n *\n * ## Configuring a custom data source\n *\n * By default, LASLoaderPlugin will load LAS files over HTTP.\n *\n * In the example below, we'll customize the way LASLoaderPlugin loads the files by configuring it with our own data source\n * object. For simplicity, our custom data source example also uses HTTP, using a couple of xeokit utility functions.\n *\n * ````javascript\n * import {utils} from \"xeokit-sdk.es.js\";\n *\n * class MyDataSource {\n *\n *      constructor() {\n *      }\n *\n *      // Gets the contents of the given LAS file in an arraybuffer\n *      getLAS(src, ok, error) {\n *          utils.loadArraybuffer(src,\n *              (arraybuffer) => {\n *                  ok(arraybuffer);\n *              },\n *              (errMsg) => {\n *                  error(errMsg);\n *              });\n *      }\n * }\n *\n * const lasLoader = new LASLoaderPlugin(viewer, {\n *       dataSource: new MyDataSource()\n * });\n *\n * const modelEntity = lasLoader.load({\n *      id: \"myModel\",\n *      src: \"../assets/models/las/autzen.laz\"\n * });\n * ````\n *\n * ## Showing a LAS/LAZ model in TreeViewPlugin\n *\n * We can use the `load()` method's `elementId` parameter\n * to make LASLoaderPlugin load the entire model into a single Entity that gets this ID.\n *\n * In conjunction with that parameter, we can then use the `load()` method's `metaModelJSON` parameter to create a MetaModel that\n * contains a MetaObject that corresponds to that Entity.\n *\n * When we've done that, then xeokit's {@link TreeViewPlugin} is able to have a node that represents the model and controls\n * the visibility of that Entity (ie. to control the visibility of the entire model).\n *\n * The snippet below shows how this is done.\n *\n * ````javascript\n * import {Viewer, LASLoaderPlugin, NavCubePlugin, TreeViewPlugin} from \"../../dist/xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n *     transparent: true\n * });\n *\n * new TreeViewPlugin(viewer, {\n *     containerElement: document.getElementById(\"treeViewContainer\"),\n *     hierarchy: \"containment\"\n * });\n *\n * const lasLoader = new LASLoaderPlugin(viewer);\n *\n * const sceneModel = lasLoader.load({  // Creates a SceneModel with ID \"myScanModel\"\n *     id: \"myScanModel\",\n *     src: \"../../assets/models/las/Nalls_Pumpkin_Hill.laz\",\n *     rotation: [-90, 0, 0],\n *\n *     entityId: \"3toKckUfH2jBmd$7uhJHa4\", // Creates an Entity with this ID\n *\n *     metaModelJSON: { // Creates a MetaModel with ID \"myScanModel\"\n *         \"metaObjects\": [\n *             {\n *                 \"id\": \"3toKckUfH2jBmd$7uhJHa6\", // Creates this MetaObject with this ID\n *                 \"name\": \"My Project\",\n *                 \"type\": \"Default\",\n *                 \"parent\": null\n *             },\n *             {\n *                 \"id\": \"3toKckUfH2jBmd$7uhJHa4\", // Creates this MetaObject with this ID\n *                 \"name\": \"My Scan\",\n *                 \"type\": \"Default\",\n *                 \"parent\": \"3toKckUfH2jBmd$7uhJHa6\"\n *             }\n *         ]\n *     }\n * });\n * ````\n *\n * @class LASLoaderPlugin\n * @since 2.0.17\n */\nclass LASLoaderPlugin extends Plugin {\n\n    /**\n     * @constructor\n     *\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"lasLoader\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {Object} [cfg.dataSource] A custom data source through which the LASLoaderPlugin can load model and metadata files. Defaults to an instance of {@link LASDefaultDataSource}, which loads over HTTP.\n     * @param {Number} [cfg.skip=1] Configures LASLoaderPlugin to load every **n** points.\n     * @param {Number} [cfg.fp64=false] Configures if LASLoaderPlugin assumes that LAS positions are stored in 64-bit floats instead of 32-bit.\n     * @param {Number} [cfg.colorDepth=8] Configures whether LASLoaderPlugin assumes that LAS colors are encoded using 8 or 16 bits. Accepted values are 8, 16 an \"auto\".\n     * @param {Boolean} [cfg.center=false] Whether to center the LAS points.  Applied before \"rotateX\", \"rotate\" and \"transform\".\n     * @param {Boolean} [cfg.rotateX=false] Whether to rotate the LAS point positions 90 degrees. Applied after \"center\".\n     * @param {Number[]} [cfg.rotate=[0,0,0]] Rotations to immediately apply to the LAS points, given as Euler angles in degrees, for each of the X, Y and Z axis. Rotation is applied after \"center\" and \"rotateX\".\n     * @param {Number[]} [cfg.transform] 4x4 transform matrix to immediately apply to the LAS points. This is applied after \"center\", \"rotateX\" and \"rotate\". Typically used instead of \"rotateX\" and \"rotate\".\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"lasLoader\", viewer, cfg);\n\n        this.dataSource = cfg.dataSource;\n        this.skip = cfg.skip;\n        this.fp64 = cfg.fp64;\n        this.colorDepth = cfg.colorDepth;\n        this.center = cfg.center;\n        this.rotate = cfg.rotate;\n        this.rotateX = cfg.rotateX;\n        this.transform = cfg.transform;\n    }\n\n    /**\n     * Gets the custom data source through which the LASLoaderPlugin can load LAS files.\n     *\n     * Default value is {@link LASDefaultDataSource}, which loads via HTTP.\n     *\n     * @type {Object}\n     */\n    get dataSource() {\n        return this._dataSource;\n    }\n\n    /**\n     * Sets a custom data source through which the LASLoaderPlugin can load LAS files.\n     *\n     * Default value is {@link LASDefaultDataSource}, which loads via HTTP.\n     *\n     * @type {Object}\n     */\n    set dataSource(value) {\n        this._dataSource = value || new LASDefaultDataSource();\n    }\n\n    /**\n     * When LASLoaderPlugin is configured to load every **n** points, returns the value of **n**.\n     *\n     * Default value is ````1````.\n     *\n     * @returns {Number} The **n**th point that LASLoaderPlugin will read.\n     */\n    get skip() {\n        return this._skip;\n    }\n\n    /**\n     * Configures LASLoaderPlugin to load every **n** points.\n     *\n     * Default value is ````1````.\n     *\n     * @param {Number} value The **n**th point that LASLoaderPlugin will read.\n     */\n    set skip(value) {\n        this._skip = value || 1;\n    }\n\n    /**\n     * Gets if LASLoaderPlugin assumes that LAS positions are stored in 64-bit floats instead of 32-bit.\n     *\n     * Default value is ````false````.\n     *\n     * @returns {Boolean} True if LASLoaderPlugin assumes that positions are stored in 64-bit floats instead of 32-bit.\n     */\n    get fp64() {\n        return this._fp64;\n    }\n\n    /**\n     * Configures if LASLoaderPlugin assumes that LAS positions are stored in 64-bit floats instead of 32-bit.\n     *\n     * Default value is ````false````.\n     *\n     * @param {Boolean} value True if LASLoaderPlugin assumes that positions are stored in 64-bit floats instead of 32-bit.\n     */\n    set fp64(value) {\n        this._fp64 = !!value;\n    }\n\n    /**\n     * Gets whether LASLoaderPlugin assumes that LAS colors are encoded using 8 or 16 bits.\n     *\n     * Default value is ````8````.\n     *\n     * Note: LAS specification recommends 16 bits.\n     *\n     * @returns {Number|String} Possible returned values are 8, 16 and \"auto\".\n     */\n    get colorDepth() {\n        return this._colorDepth;\n    }\n\n    /**\n     * Configures whether LASLoaderPlugin assumes that LAS colors are encoded using 8 or 16 bits.\n     *\n     * Default value is ````8````.\n     *\n     * Note: LAS specification recommends 16 bits.\n     *\n     * @param {Number|String} value Valid values are 8, 16 and \"auto\".\n     */\n    set colorDepth(value) {\n        this._colorDepth = value || \"auto\";\n    }\n\n    /**\n     * Gets if LASLoaderPlugin immediately centers LAS positions.\n     *\n     * If this is ````true```` then centering is the first thing that happens to LAS positions as they are loaded.\n     *\n     * Default value is ````false````.\n     *\n     * @returns {Boolean} True if LASLoaderPlugin immediately centers LAS positions.\n     */\n    get center() {\n        return this._center;\n    }\n\n    /**\n     * Configures if LASLoaderPlugin immediately centers LAS positions.\n     *\n     * If this is ````true```` then centering is the first thing that happens to LAS positions as they are loaded.\n     *\n     * Default value is ````false````.\n     *\n     * @param {Boolean} value True if LASLoaderPlugin immediately centers LAS positions.\n     */\n    set center(value) {\n        this._center = !!value;\n    }\n\n    /**\n     * Gets the current transformation to apply to LAS positions as they are loaded.\n     *\n     * If this is ````true````, then LAS positions will be transformed after they are centered and rotated.\n     *\n     * Default value is null.\n     *\n     * @returns {Number[]|null} A 16-element array containing a 4x4 transformation matrix.\n     */\n    get transform() {\n        return this._transform;\n    }\n\n    /**\n     * Sets the current transformation to apply to LAS positions as they are loaded.\n     *\n     * If this is ````true````, then LAS positions will be transformed after they are centered and rotated.\n     *\n     * Default value is null.\n     *\n     * @param {Number[]|null} transform A 16-element array containing a 4x4 transformation matrix.\n     */\n    set transform(transform) {\n        this._transform = transform;\n    }\n\n    /**\n     * Gets the current rotations to apply to LAS positions as they are loaded.\n     *\n     * Rotations are an array of three Euler angles in degrees, for each of the X, Y and Z axis, applied in that order.\n     *\n     * Default value is null.\n     *\n     * @returns {Number[]|null} If defined, an array of three Euler angles in degrees, for each of the X, Y and Z axis. Null if undefined.\n     */\n    get rotate() {\n        return this._rotate;\n    }\n\n    /**\n     * Sets the current rotations to apply to LAS positions as they are loaded.\n     *\n     * Rotations are an array of three Euler angles in degrees, for each of the X, Y and Z axis, applied in that order.\n     *\n     * Default value is null.\n     *\n     * @param {Number[]|null} rotate Array of three Euler angles in degrees, for each of the X, Y and Z axis.\n     */\n    set rotate(rotate) {\n        this._rotate = rotate;\n    }\n\n    /**\n     * Gets if LAS positions are rotated 90 degrees about X as they are loaded.\n     *\n     * Default value is ````false````.\n     *\n     * @returns {*}\n     */\n    get rotateX() {\n        return this._rotateX;\n    }\n\n    /**\n     * Sets if LAS positions are rotated 90 degrees about X as they are loaded.\n     *\n     * Default value is ````false````.\n     *\n     * @param rotateX\n     */\n    set rotateX(rotateX) {\n        this._rotateX = rotateX;\n    }\n\n    /**\n     * Loads an ````LAS```` model into this LASLoaderPlugin's {@link Viewer}.\n     *\n     * @param {*} params Loading parameters.\n     * @param {String} [params.id] ID to assign to the root {@link Entity#id}, unique among all components in the Viewer's {@link Scene}, generated automatically by default.\n     * @param {String} [params.src] Path to a LAS file, as an alternative to the ````las```` parameter.\n     * @param {ArrayBuffer} [params.las] The LAS file data, as an alternative to the ````src```` parameter.\n     *  @param {String} [params.manifestSrc] Path or URL to a JSON manifest file that provides paths to ````.laz```` || ````.las```` files to load as parts of the model. Use this option to load models that have been split into\n     * @param {Object} [params.manifest] A JSON manifest object (as an alternative to a path or URL) that provides paths to ````.laz```` || ````.las```` files to load as parts of the model. Use this option to load models that have been split into\n     * @param {Boolean} [params.loadMetadata=true] Whether to load metadata for the LAS model.\n     * @param {Number[]} [params.origin=[0,0,0]] The model's World-space double-precision 3D origin. Use this to position the model within xeokit's World coordinate system, using double-precision coordinates.\n     * @param {Number[]} [params.position=[0,0,0]] The model single-precision 3D position, relative to the ````origin```` parameter.\n     * @param {Number[]} [params.scale=[1,1,1]] The model's scale.\n     * @param {Number[]} [params.rotation=[0,0,0]] The model's orientation, given as Euler angles in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [params.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] The model's world transform matrix. Overrides the position, scale and rotation parameters. Relative to ````origin````.\n     * @param {Object} [params.stats] Collects model statistics.\n     * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.\n     */\n    load(params = {}) {\n\n        if (params.id && this.viewer.scene.components[params.id]) {\n            this.error(\"Component with this ID already exists in viewer: \" + params.id + \" - will autogenerate this ID\");\n            delete params.id;\n        }\n\n        const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {\n            maxGeometryBatchSize: MAX_VERTICES,\n            isModel: true\n        }));\n\n        if (!params.src && !params.las && !params.manifest && !params.manifestSrc) {\n            this.error(\"load() param expected: src or las\");\n            return sceneModel; // Return new empty model\n        }\n\n        const options = {\n            las: {\n                skip: this._skip,\n                fp64: this._fp64,\n                colorDepth: this._colorDepth\n            }\n        };\n\n        const spinner = this.viewer.scene.canvas.spinner;\n        const done = () => {\n            sceneModel.scene.once(\"tick\", () => {\n                if (sceneModel.destroyed) {\n                    return;\n                }\n                sceneModel.scene.fire(\"modelLoaded\", sceneModel.id); // FIXME: Assumes listeners know order of these two events\n                sceneModel.fire(\"loaded\", true, false); // Don't forget the event, for late subscribers\n            });\n            spinner.processes--;\n        };\n        const error = (errMsg) => {\n            spinner.processes--;\n            this.error(errMsg);\n            sceneModel.fire(\"error\", errMsg);\n        };\n\n        if (params.src) {\n            this._loadModel(params.src, params, options, sceneModel);\n        } else if(params.las) {\n            spinner.processes++;\n            this._parseModel(params.las, params, options, sceneModel).then(done, error);\n        } else if (params.manifest || params.manifestSrc) {\n            const baseDir = params.manifestSrc ? getBaseDirectory(params.manifestSrc) : \"\";\n            const loadAllFiles = (lasFiles) => { \n                let i = 0;\n                const modelsLoaded = new Array(lasFiles.length);\n                const loadNext = () => {\n                    if (sceneModel.destroyed) {\n                        done();\n                    } else if (i >= lasFiles.length) {\n                        return\n                    } else {\n                        modelsLoaded[i] = false;\n                        this._dataSource.getLAS(`${baseDir}${lasFiles[i]}`, (arrayBuffer) => {\n                            const modelParams = utils.apply(params, {isManifest: true, index: i});\n                            this._parseModel(arrayBuffer, modelParams, options, sceneModel).then(() => {\n                                modelsLoaded[modelParams.index] = true;\n                                let allLoaded = true;\n                                modelsLoaded.forEach((loaded) => {\n                                    if(!loaded) allLoaded = false;\n                                });\n                                if(allLoaded) done();\n                            });\n                            i++;\n                            this.scheduleTask(loadNext, 200);\n                        }, error);\n                    }\n                };\n                loadNext();\n            };\n            const loadManifestData = (manifestData) => {\n                if(sceneModel.destroyed) return;\n                const files = manifestData.lasFiles || manifestData.lazFiles;\n                if(!files || files.length <= 0) {\n                    this.error(`load(): Failed to load model manifest - manifest not valid`);\n                    return;\n                }\n                loadAllFiles(files);\n            };\n            if(params.manifestSrc) {\n                this._dataSource.getManifest(params.manifestSrc, (manifestData) => {\n                    loadManifestData(manifestData);\n                }, (errMsg) => {\n                    this.error(errMsg);\n                    sceneModel.fire(\"error\", errMsg);\n                });\n            } else {\n                const manifestData = params.manifest;\n                loadManifestData(manifestData);\n            }\n        }\n\n        return sceneModel;\n    }\n\n    _loadModel(src, params, options, sceneModel) {\n        const spinner = this.viewer.scene.canvas.spinner;\n        spinner.processes++;\n        this._dataSource.getLAS(params.src, (arrayBuffer) => {\n                this._parseModel(arrayBuffer, params, options, sceneModel).then(() => {\n                    sceneModel.scene.once(\"tick\", () => {\n                        if (sceneModel.destroyed) {\n                            return;\n                        }\n                        sceneModel.scene.fire(\"modelLoaded\", sceneModel.id); // FIXME: Assumes listeners know order of these two events\n                        sceneModel.fire(\"loaded\", true, false); // Don't forget the event, for late subscribers\n                    });\n                    spinner.processes--;\n                }, (errMsg) => {\n                    spinner.processes--;\n                    this.error(errMsg);\n                    sceneModel.fire(\"error\", errMsg);\n                });\n            },\n            (errMsg) => {\n                spinner.processes--;\n                this.error(errMsg);\n                sceneModel.fire(\"error\", errMsg);\n            });\n    }\n\n    _parseModel(arrayBuffer, params, options, sceneModel) {\n\n        const readPositions = (attributesPosition) => {\n            const positionsValue = attributesPosition.value;\n            if (this._center) {\n                const centerPos = math.vec3();\n                const numPoints = positionsValue.length;\n                for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n                    centerPos[0] += positionsValue[i + 0];\n                    centerPos[1] += positionsValue[i + 1];\n                    centerPos[2] += positionsValue[i + 2];\n                }\n                centerPos[0] /= numPoints;\n                centerPos[1] /= numPoints;\n                centerPos[2] /= numPoints;\n                for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n                    positionsValue[i + 0] -= centerPos[0];\n                    positionsValue[i + 1] -= centerPos[1];\n                    positionsValue[i + 2] -= centerPos[2];\n                }\n            }\n            if (this._rotateX) {\n                if (positionsValue) {\n                    for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n                        const temp = positionsValue[i + 1];\n                        positionsValue[i + 1] = positionsValue[i + 2];\n                        positionsValue[i + 2] = temp;\n                    }\n                }\n            }\n            if (this._rotate) {\n                const quaternion = math.identityQuaternion();\n                const mat = math.mat4();\n                math.eulerToQuaternion(this._rotate, \"XYZ\", quaternion);\n                math.quaternionToRotationMat4(quaternion, mat);\n                const pos = math.vec3();\n                for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n                    pos[0] = positionsValue[i + 0];\n                    pos[1] = positionsValue[i + 1];\n                    pos[2] = positionsValue[i + 2];\n                    math.transformPoint3(mat, pos, pos);\n                    positionsValue[i + 0] = pos[0];\n                    positionsValue[i + 1] = pos[1];\n                    positionsValue[i + 2] = pos[2];\n                }\n            }\n            if (this._transform) {\n                const mat = math.mat4(this._transform);\n                const pos = math.vec3();\n                for (let i = 0, len = positionsValue.length; i < len; i += 3) {\n                    pos[0] = positionsValue[i + 0];\n                    pos[1] = positionsValue[i + 1];\n                    pos[2] = positionsValue[i + 2];\n                    math.transformPoint3(mat, pos, pos);\n                    positionsValue[i + 0] = pos[0];\n                    positionsValue[i + 1] = pos[1];\n                    positionsValue[i + 2] = pos[2];\n                }\n            }\n            return positionsValue;\n        };\n\n        function readColorsAndIntensities(attributesColor, attributesIntensity) {\n            const colors = attributesColor.value;\n            const colorSize = attributesColor.size;\n            const intensities = attributesIntensity.value;\n            const colorsCompressedSize = intensities.length * 4;\n            const colorsCompressed = new Uint8Array(colorsCompressedSize);\n            for (let i = 0, j = 0, k = 0, len = intensities.length; i < len; i++, k += colorSize, j += 4) {\n                colorsCompressed[j + 0] = colors[k + 0];\n                colorsCompressed[j + 1] = colors[k + 1];\n                colorsCompressed[j + 2] = colors[k + 2];\n                colorsCompressed[j + 3] = Math.round((intensities[i] / 65536) * 255);\n            }\n            return colorsCompressed;\n        }\n\n        function readIntensities(attributesIntensity) {\n            const intensities = attributesIntensity.value;\n            const colorsCompressedSize = intensities.length * 4;\n            const colorsCompressed = new Uint8Array(colorsCompressedSize);\n            for (let i = 0, j = 0, len = intensities.length; i < len; i++, j += 4) {\n                colorsCompressed[j + 0] = 0;\n                colorsCompressed[j + 1] = 0;\n                colorsCompressed[j + 2] = 0;\n                colorsCompressed[j + 3] = Math.round((intensities[i] / 65536) * 255);\n            }\n            return colorsCompressed;\n        }\n\n        return new Promise((resolve, reject) => {\n\n            if (sceneModel.destroyed) {\n                reject();\n                return;\n            }\n\n            const stats = params.stats || {};\n            stats.sourceFormat = \"LAS\";\n            stats.schemaVersion = \"\";\n            stats.title = \"\";\n            stats.author = \"\";\n            stats.created = \"\";\n            stats.numMetaObjects = 0;\n            stats.numPropertySets = 0;\n            stats.numObjects = 0;\n            stats.numGeometries = 0;\n            stats.numTriangles = 0;\n            stats.numVertices = 0;\n\n            try {\n\n                const lasHeader = loadLASHeader(arrayBuffer);\n\n                parse$4(arrayBuffer, LASLoader, options).then((parsedData) => {\n\n                    const attributes = parsedData.attributes;\n                    const loaderData = parsedData.loaderData;\n                    const pointsFormatId = loaderData.pointsFormatId !== undefined ? loaderData.pointsFormatId : -1;\n\n                    if (!attributes.POSITION) {\n                        sceneModel.finalize();\n                        reject(\"No positions found in file\");\n                        return;\n                    }\n\n                    let positionsValue;\n                    let colorsCompressed;\n\n                    switch (pointsFormatId) {\n                        case 0:\n                            positionsValue = readPositions(attributes.POSITION);\n                            colorsCompressed = readIntensities(attributes.intensity);\n                            break;\n                        case 1:\n                            if (!attributes.intensity) {\n                                sceneModel.finalize();\n                                reject(\"No positions found in file\");\n                                return;\n                            }\n                            positionsValue = readPositions(attributes.POSITION);\n                            colorsCompressed = readIntensities(attributes.intensity);\n                            break;\n                        case 2:\n                            if (!attributes.intensity) {\n                                sceneModel.finalize();\n                                reject(\"No positions found in file\");\n                                return;\n                            }\n                            positionsValue = readPositions(attributes.POSITION);\n                            colorsCompressed = readColorsAndIntensities(attributes.COLOR_0, attributes.intensity);\n                            break;\n                        case 3:\n                            if (!attributes.intensity) {\n                                sceneModel.finalize();\n                                reject(\"No positions found in file\");\n                                return;\n                            }\n                            positionsValue = readPositions(attributes.POSITION);\n                            colorsCompressed = readColorsAndIntensities(attributes.COLOR_0, attributes.intensity);\n                            break;\n                    }\n\n                    const pointsChunks = chunkArray(positionsValue, MAX_VERTICES * 3);\n                    const colorsChunks = chunkArray(colorsCompressed, MAX_VERTICES * 4);\n                    const meshIds = [];\n\n                    for (let i = 0, len = pointsChunks.length; i < len; i++) {\n                        const meshId = `${params.isManifest ? 'model'+params.index : ''}pointsMesh${i}`;\n                        meshIds.push(meshId);\n                        sceneModel.createMesh({\n                            id: meshId,\n                            primitive: \"points\",\n                            positions: pointsChunks[i],\n                            colorsCompressed: (i < colorsChunks.length) ? colorsChunks[i] : null\n                        });\n                    }\n\n                    const pointsObjectId = params.entityId || math.createUUID();\n\n                    sceneModel.createEntity({\n                        id: pointsObjectId,\n                        meshIds,\n                        isObject: true\n                    });\n\n                    sceneModel.finalize();\n\n                    if (params.metaModelJSON) {\n                        const metaModelId = sceneModel.id;\n                        this.viewer.metaScene.createMetaModel(metaModelId, params.metaModelJSON, options);\n                    } else if (params.loadMetadata !== false) {\n                        const rootMetaObjectId = math.createUUID();\n                        const metadata = {\n                            projectId: \"\",\n                            author: \"\",\n                            createdAt: \"\",\n                            schema: \"\",\n                            creatingApplication: \"\",\n                            metaObjects: [\n                                {\n                                    id: rootMetaObjectId,\n                                    name: \"Model\",\n                                    type: \"Model\"\n                                },\n                                {\n                                    id: pointsObjectId,\n                                    name: \"PointCloud (LAS)\",\n                                    type: \"PointCloud\",\n                                    parent: rootMetaObjectId,\n                                    attributes: lasHeader || {}\n                                }\n                            ],\n                            propertySets: []\n                        };\n                        const metaModelId = sceneModel.id;\n                        this.viewer.metaScene.createMetaModel(metaModelId, metadata, options);\n                    }\n\n                    resolve();\n                });\n            } catch (e) {\n                sceneModel.finalize();\n                reject(e);\n            }\n        });\n    }\n}\n\nfunction chunkArray(array, chunkSize) {\n    if (chunkSize >= array.length) {\n        return [array];\n    }\n    let result = [];\n    for (let i = 0; i < array.length; i += chunkSize) {\n        result.push(array.slice(i, i + chunkSize));\n    }\n    return result;\n}\n\nfunction getBaseDirectory(filePath) {\n    if (filePath.indexOf('?') > -1) {\n        filePath = filePath.split('?')[0];\n    }\n\n    const pathArray = filePath.split('/');\n    pathArray.pop(); // Remove the file name or the last segment of the path\n    return pathArray.join('/') + '/';\n}\n\n/**\n * Default data access strategy for {@link CityJSONLoaderPlugin}.\n */\nclass CityJSONDefaultDataSource {\n\n    constructor(cfg = {}) {\n        this.cacheBuster = (cfg.cacheBuster !== false);\n    }\n\n    _cacheBusterURL(url) {\n        if (!this.cacheBuster) {\n            return url;\n        }\n        const timestamp = new Date().getTime();\n        if (url.indexOf('?') > -1) {\n            return url + '&_=' + timestamp;\n        } else {\n            return url + '?_=' + timestamp;\n        }\n    }\n\n    /**\n     * Gets the contents of the given CityJSON file.\n     *\n     * @param {String|Number} src Path or ID of an CityJSON file.\n     * @param {Function} ok Callback fired on success, argument is the CityJSON JSON.\n     * @param {Function} error Callback fired on error.\n     */\n    getCityJSON(src, ok, error) {\n        utils.loadJSON(this._cacheBusterURL(src),\n            (json) => {\n                ok(json);\n            },\n            function (errMsg) {\n                error(errMsg);\n            });\n    }\n}\n\nconst tempVec2a = math.vec2();\nconst tempVec3a = math.vec3();\nconst tempVec3b = math.vec3();\nconst tempVec3c = math.vec3();\n\n/**\n * {@link Viewer} plugin that loads models from CityJSON files.\n *\n * <a href=\"https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_CityJSONLoaderPlugin_Railway\"><img src=\"https://xeokit.io/img/docs/CityJSONLoaderPlugin/CityJSONLoaderPlugin.png\"></a>\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_CityJSONLoaderPlugin_Railway)]\n *\n * ## Overview\n *\n * * Loads small-to-medium sized models directly from [CityJSON 1.0.0](https://www.cityjson.org/specs/1.0.0/) files.\n * * Loads double-precision coordinates, enabling models to be viewed at global coordinates without accuracy loss.\n * * Allows to set the position, scale and rotation of each model as you load it.\n * * Not recommended for large models. For best performance with large CityJSON datasets, we recommend\n * converting them to ````.xkt```` format (eg. using [convert2xkt](https://github.com/xeokit/xeokit-convert)), then loading\n * the ````.xkt```` using {@link XKTLoaderPlugin}.\n *\n * ## Limitations\n *\n * Loading and parsing huge CityJSON files can be slow, and can overwhelm the browser, however. To view your\n * largest CityJSON models, we recommend instead pre-converting those to xeokit's compressed native .XKT format, then\n * loading them with {@link XKTLoaderPlugin} instead.</p>\n *\n * ## Scene representation\n *\n * When loading a model, CityJSONLoaderPlugin creates an {@link Entity} that represents the model, which\n * will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id}\n * in {@link Scene#models}. The CityJSONLoaderPlugin also creates an {@link Entity} for each object within the\n * model. Those Entities will have {@link Entity#isObject} set ````true```` and will be registered\n * by {@link Entity#id} in {@link Scene#objects}.\n *\n * ## Metadata\n *\n * When loading a model, CityJSONLoaderPlugin also creates a {@link MetaModel} that represents the model, which contains\n * a tree of {@link MetaObject}s that represent the CityJSON objects. .\n *\n * ## Usage\n *\n * In the example below we'll load the LOD 3 Railway model from\n * a [CityJSON file](https://github.com/xeokit/xeokit-sdk/tree/master/assets/models/cityjson/LoD3_Railway.json). Within\n * our {@link Viewer}, this will create a bunch of {@link Entity}s that represents the model and its objects, along with\n * a {@link MetaModel} and {@link MetaObject}s that hold their metadata.\n *\n * We'll also scale our model to half its size, rotate it 90 degrees about its local X-axis, then\n * translate it 100 units along its X axis.\n *\n * * [[Run example](https://xeokit.github.io/xeokit-sdk/examples/index.html#loading_CityJSONLoaderPlugin_Railway)]\n *\n * ````javascript\n * import {Viewer, CityJSONLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * viewer.scene.camera.eye = [14.915582703146043, 14.396781491179095, 5.431098754133695];\n * viewer.scene.camera.look = [6.599999999999998, 8.34099990051474, -4.159999575600315];\n * viewer.scene.camera.up = [-0.2820584034861215, 0.9025563895259413, -0.3253229483893775];\n *\n * const cityJSONLoader = new CityJSONLoaderPlugin(viewer);\n *\n * const model = cityJSONLoader.load({ // Returns an Entity that represents the model\n *     id: \"myModel1\",\n *     src: \"../assets/models/cityjson/LoD3_Railway.json\",\n *     saoEnabled: true,\n *     edges: false,\n *     rotation: [-90,0,0],\n *     scale: [0.5, 0.5, 0.5],\n *     origin: [100, 0, 0]\n * });\n * ````\n *\n * ## Configuring a custom data source\n *\n * By default, CityJSONLoaderPlugin will load CityJSON files over HTTP.\n *\n * In the example below, we'll customize the way CityJSONLoaderPlugin loads the files by configuring it with our own data source\n * object. For simplicity, our custom data source example also uses HTTP, using a couple of xeokit utility functions.\n *\n * ````javascript\n * import {utils} from \"xeokit-sdk.es.js\";\n *\n * class MyDataSource {\n *\n *      constructor() {\n *      }\n *\n *      getCityJSON(src, ok, error) {\n *          console.log(\"MyDataSource#getCityJSON(\" + CityJSONSrc + \", ... )\");\n *          utils.loadJSON(src,\n *              (cityJSON) => {\n *                  ok(cityJSON);\n *              },\n *              function (errMsg) {\n *                  error(errMsg);\n *              });\n *      }\n * }\n * ````\n *\n * @class CityJSONLoaderPlugin\n * @since 2.0.13\n */\nclass CityJSONLoaderPlugin extends Plugin {\n\n    /**\n     * @constructor\n     *\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"cityJSONLoader\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {Object} [cfg.dataSource] A custom data source through which the CityJSONLoaderPlugin can load model and\n     * metadata files. Defaults to an instance of {@link CityJSONDefaultDataSource}, which loads over HTTP.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"cityJSONLoader\", viewer, cfg);\n\n        this.dataSource = cfg.dataSource;\n    }\n\n    /**\n     * Gets the custom data source through which the CityJSONLoaderPlugin can load CityJSON files.\n     *\n     * Default value is {@link CityJSONDefaultDataSource}, which loads via HTTP.\n     *\n     * @type {Object}\n     */\n    get dataSource() {\n        return this._dataSource;\n    }\n\n    /**\n     * Sets a custom data source through which the CityJSONLoaderPlugin can load CityJSON files.\n     *\n     * Default value is {@link CityJSONDefaultDataSource}, which loads via HTTP.\n     *\n     * @type {Object}\n     */\n    set dataSource(value) {\n        this._dataSource = value || new CityJSONDefaultDataSource();\n    }\n\n    /**\n     * Loads an ````CityJSON```` model into this CityJSONLoaderPlugin's {@link Viewer}.\n     *\n     * @param {*} params Loading parameters.\n     * @param {String} [params.id] ID to assign to the root {@link Entity#id}, unique among all components in the Viewer's {@link Scene}, generated automatically by default.\n     * @param {String} [params.src] Path to a CityJSON file, as an alternative to the ````cityJSON```` parameter.\n     * @param {ArrayBuffer} [params.cityJSON] The CityJSON file data, as an alternative to the ````src```` parameter.\n     * @param {Boolean} [params.loadMetadata=true] Whether to load metadata on CityJSON objects.\n     * @param {Number[]} [params.origin=[0,0,0]] The model's World-space double-precision 3D origin. Use this to position the model within xeokit's World coordinate system, using double-precision coordinates.\n     * @param {Number[]} [params.position=[0,0,0]] The model single-precision 3D position, relative to the ````origin```` parameter.\n     * @param {Number[]} [params.scale=[1,1,1]] The model's scale.\n     * @param {Number[]} [params.rotation=[0,0,0]] The model's orientation, given as Euler angles in degrees, for each of the X, Y and Z axis.\n     * @param {Number[]} [params.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] The model's world transform matrix. Overrides the position, scale and rotation parameters. Relative to ````origin````.\n     * @param {Object} [params.stats] Collects model statistics.\n     * @param {Boolean} [params.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to\n     * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable\n     * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point\n     * primitives. Only works while {@link DTX#enabled} is also ````true````.\n     * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.\n     */\n    load(params = {}) {\n\n        if (params.id && this.viewer.scene.components[params.id]) {\n            this.error(\"Component with this ID already exists in viewer: \" + params.id + \" - will autogenerate this ID\");\n            delete params.id;\n        }\n\n        const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {\n            isModel: true,\n            edges: true\n        }));\n\n        if (!params.src && !params.cityJSON) {\n            this.error(\"load() param expected: src or cityJSON\");\n            return sceneModel; // Return new empty model\n        }\n\n        const options = {};\n\n        if (params.src) {\n            this._loadModel(params.src, params, options, sceneModel);\n        } else {\n            const spinner = this.viewer.scene.canvas.spinner;\n            spinner.processes++;\n            this._parseModel(params.cityJSON, params, options, sceneModel);\n            spinner.processes--;\n        }\n\n        return sceneModel;\n    }\n\n    _loadModel(src, params, options, sceneModel) {\n        const spinner = this.viewer.scene.canvas.spinner;\n        spinner.processes++;\n        this._dataSource.getCityJSON(params.src, (data) => {\n                this._parseModel(data, params, options, sceneModel);\n                spinner.processes--;\n            },\n            (errMsg) => {\n                spinner.processes--;\n                this.error(errMsg);\n                sceneModel.fire(\"error\", errMsg);\n            });\n    }\n\n    _parseModel(data, params, options, sceneModel) {\n\n        if (sceneModel.destroyed) {\n            return;\n        }\n\n        const vertices = data.transform ? this._transformVertices(data.vertices, data.transform, options.rotateX) : data.vertices;\n\n        const stats = params.stats || {};\n        stats.sourceFormat = data.type || \"CityJSON\";\n        stats.schemaVersion = data.version || \"\";\n        stats.title = \"\";\n        stats.author = \"\";\n        stats.created = \"\";\n        stats.numMetaObjects = 0;\n        stats.numPropertySets = 0;\n        stats.numObjects = 0;\n        stats.numGeometries = 0;\n        stats.numTriangles = 0;\n        stats.numVertices = 0;\n\n        const loadMetadata = (params.loadMetadata !== false);\n\n        const rootMetaObject = loadMetadata ? {\n            id: math.createUUID(),\n            name: \"Model\",\n            type: \"Model\"\n        } : null;\n\n        const metadata = loadMetadata ? {\n            id: \"\",\n            projectId: \"\",\n            author: \"\",\n            createdAt: \"\",\n            schema: data.version || \"\",\n            creatingApplication: \"\",\n            metaObjects: [rootMetaObject],\n            propertySets: []\n        } : null;\n\n        const ctx = {\n            data,\n            vertices,\n            sceneModel,\n            loadMetadata,\n            metadata,\n            rootMetaObject,\n            nextId: 0,\n            stats\n        };\n\n        this._parseCityJSON(ctx);\n\n        sceneModel.finalize();\n\n        if (loadMetadata) {\n            const metaModelId = sceneModel.id;\n            this.viewer.metaScene.createMetaModel(metaModelId, ctx.metadata, options);\n        }\n\n        sceneModel.scene.once(\"tick\", () => {\n            if (sceneModel.destroyed) {\n                return;\n            }\n            sceneModel.scene.fire(\"modelLoaded\", sceneModel.id); // FIXME: Assumes listeners know order of these two events\n            sceneModel.fire(\"loaded\", true, false); // Don't forget the event, for late subscribers\n        });\n    }\n\n    _transformVertices(vertices, transform, rotateX) {\n        const transformedVertices = [];\n        const scale = transform.scale || math.vec3([1, 1, 1]);\n        const translate = transform.translate || math.vec3([0, 0, 0]);\n        for (let i = 0, j = 0; i < vertices.length; i++, j += 3) {\n            const x = (vertices[i][0] * scale[0]) + translate[0];\n            const y = (vertices[i][1] * scale[1]) + translate[1];\n            const z = (vertices[i][2] * scale[2]) + translate[2];\n            if (rotateX) {\n                transformedVertices.push([x, z, y]);\n            } else {\n                transformedVertices.push([x, y, z]);\n            }\n        }\n        return transformedVertices;\n    }\n\n    _parseCityJSON(ctx) {\n        const data = ctx.data;\n        const cityObjects = data.CityObjects;\n        for (const objectId in cityObjects) {\n            if (cityObjects.hasOwnProperty(objectId)) {\n                const cityObject = cityObjects[objectId];\n                this._parseCityObject(ctx, cityObject, objectId);\n            }\n        }\n    }\n\n    _parseCityObject(ctx, cityObject, objectId) {\n\n        const sceneModel = ctx.sceneModel;\n        const data = ctx.data;\n\n        if (ctx.loadMetadata) {\n\n            const metaObjectId = objectId;\n            const metaObjectType = cityObject.type;\n            const metaObjectName = metaObjectType + \" : \" + objectId;\n            const parentMetaObjectId = cityObject.parents ? cityObject.parents[0] : ctx.rootMetaObject.id;\n\n            ctx.metadata.metaObjects.push({\n                id: metaObjectId,\n                name: metaObjectName,\n                type: metaObjectType,\n                parent: parentMetaObjectId\n            });\n        }\n\n        ctx.stats.numMetaObjects++;\n\n        if (!(cityObject.geometry && cityObject.geometry.length > 0)) {\n            return;\n        }\n\n        const meshIds = [];\n\n        for (let i = 0, len = cityObject.geometry.length; i < len; i++) {\n\n            const geometry = cityObject.geometry[i];\n\n            let objectMaterial;\n            let surfaceMaterials;\n\n            const appearance = data.appearance;\n            if (appearance) {\n                const materials = appearance.materials;\n                if (materials) {\n                    const geometryMaterial = geometry.material;\n                    if (geometryMaterial) {\n                        const themeIds = Object.keys(geometryMaterial);\n                        if (themeIds.length > 0) {\n                            const themeId = themeIds[0];\n                            const theme = geometryMaterial[themeId];\n                            if (theme.value !== undefined) {\n                                objectMaterial = materials[theme.value];\n                            } else {\n                                const values = theme.values;\n                                if (values) {\n                                    surfaceMaterials = [];\n                                    for (let j = 0, lenj = values.length; j < lenj; j++) {\n                                        const value = values[i];\n                                        const surfaceMaterial = materials[value];\n                                        surfaceMaterials.push(surfaceMaterial);\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (surfaceMaterials) {\n                this._parseGeometrySurfacesWithOwnMaterials(ctx, geometry, surfaceMaterials, meshIds);\n\n            } else {\n                this._parseGeometrySurfacesWithSharedMaterial(ctx, geometry, objectMaterial, meshIds);\n            }\n        }\n\n        if (meshIds.length > 0) {\n            sceneModel.createEntity({\n                id: objectId,\n                meshIds: meshIds,\n                isObject: true\n            });\n\n            ctx.stats.numObjects++;\n        }\n    }\n\n    _parseGeometrySurfacesWithOwnMaterials(ctx, geometry, surfaceMaterials, meshIds) {\n\n        const geomType = geometry.type;\n\n        switch (geomType) {\n\n            case \"MultiPoint\":\n                break;\n\n            case \"MultiLineString\":\n                break;\n\n            case \"MultiSurface\":\n\n            case \"CompositeSurface\":\n                const surfaces = geometry.boundaries;\n                this._parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n                break;\n\n            case \"Solid\":\n                const shells = geometry.boundaries;\n                for (let j = 0; j < shells.length; j++) {\n                    const surfaces = shells[j];\n                    this._parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n                }\n                break;\n\n            case \"MultiSolid\":\n\n            case \"CompositeSolid\":\n                const solids = geometry.boundaries;\n                for (let j = 0; j < solids.length; j++) {\n                    for (let k = 0; k < solids[j].length; k++) {\n                        const surfaces = solids[j][k];\n                        this._parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds);\n                    }\n                }\n                break;\n        }\n    }\n\n    _parseSurfacesWithOwnMaterials(ctx, surfaceMaterials, surfaces, meshIds) {\n\n        const vertices = ctx.vertices;\n        const sceneModel = ctx.sceneModel;\n\n        for (let i = 0; i < surfaces.length; i++) {\n\n            const surface = surfaces[i];\n            const surfaceMaterial = surfaceMaterials[i] || {diffuseColor: [0.8, 0.8, 0.8], transparency: 1.0};\n\n            const face = [];\n            const holes = [];\n\n            const sharedIndices = [];\n\n            const geometryCfg = {\n                positions: [],\n                indices: []\n            };\n\n            for (let j = 0; j < surface.length; j++) {\n\n                if (face.length > 0) {\n                    holes.push(face.length);\n                }\n\n                const newFace = this._extractLocalIndices(ctx, surface[j], sharedIndices, geometryCfg);\n\n                face.push(...newFace);\n            }\n\n            if (face.length === 3) { // Triangle\n\n                geometryCfg.indices.push(face[0]);\n                geometryCfg.indices.push(face[1]);\n                geometryCfg.indices.push(face[2]);\n\n            } else if (face.length > 3) { // Polygon\n\n                // Prepare to triangulate\n\n                const pList = [];\n\n                for (let k = 0; k < face.length; k++) {\n                    pList.push({\n                        x: vertices[sharedIndices[face[k]]][0],\n                        y: vertices[sharedIndices[face[k]]][1],\n                        z: vertices[sharedIndices[face[k]]][2]\n                    });\n                }\n\n                const normal = this._getNormalOfPositions(pList, math.vec3());\n\n                // Convert to 2D\n\n                let pv = [];\n\n                for (let k = 0; k < pList.length; k++) {\n\n                    this._to2D(pList[k], normal, tempVec2a);\n\n                    pv.unshift(tempVec2a[0]);\n                    pv.unshift(tempVec2a[1]);\n                }\n\n                // Triangulate\n\n                const tr = earcut(pv, holes, 2);\n\n                // Create triangles\n\n                for (let k = 0; k < tr.length; k += 3) {\n                    geometryCfg.indices.unshift(face[tr[k]]);\n                    geometryCfg.indices.unshift(face[tr[k + 1]]);\n                    geometryCfg.indices.unshift(face[tr[k + 2]]);\n                }\n            }\n\n            const meshId = \"\" + ctx.nextId++;\n\n            sceneModel.createMesh({\n                id: meshId,\n                primitive: \"triangles\",\n                positions: geometryCfg.positions,\n                indices: geometryCfg.indices,\n                color: (surfaceMaterial && surfaceMaterial.diffuseColor) ? surfaceMaterial.diffuseColor : [0.8, 0.8, 0.8],\n                opacity: (surfaceMaterial && surfaceMaterial.transparency !== undefined) ? (1.0 - surfaceMaterial.transparency) : 1.0\n            });\n\n            meshIds.push(meshId);\n\n            ctx.stats.numGeometries++;\n            ctx.stats.numVertices += geometryCfg.positions.length / 3;\n            ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n        }\n    }\n\n    _parseGeometrySurfacesWithSharedMaterial(ctx, geometry, objectMaterial, meshIds) {\n\n        const sceneModel = ctx.sceneModel;\n        const sharedIndices = [];\n        const geometryCfg = {\n            positions: [],\n            indices: []\n        };\n\n        const geomType = geometry.type;\n\n        switch (geomType) {\n            case \"MultiPoint\":\n                break;\n\n            case \"MultiLineString\":\n                break;\n\n            case \"MultiSurface\":\n            case \"CompositeSurface\":\n                const surfaces = geometry.boundaries;\n                this._parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n                break;\n\n            case \"Solid\":\n                const shells = geometry.boundaries;\n                for (let j = 0; j < shells.length; j++) {\n                    const surfaces = shells[j];\n                    this._parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n                }\n                break;\n\n            case \"MultiSolid\":\n            case \"CompositeSolid\":\n                const solids = geometry.boundaries;\n                for (let j = 0; j < solids.length; j++) {\n                    for (let k = 0; k < solids[j].length; k++) {\n                        const surfaces = solids[j][k];\n                        this._parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, geometryCfg);\n                    }\n                }\n                break;\n        }\n\n        if (geometryCfg.positions.length > 0 && geometryCfg.indices.length > 0) {\n\n            const meshId = \"\" + ctx.nextId++;\n\n            sceneModel.createMesh({\n                id: meshId,\n                primitive: \"triangles\",\n                positions: geometryCfg.positions,\n                indices: geometryCfg.indices,\n                color: (objectMaterial && objectMaterial.diffuseColor) ? objectMaterial.diffuseColor : [0.8, 0.8, 0.8],\n                opacity: 1.0\n                //opacity: (objectMaterial && objectMaterial.transparency !== undefined) ? (1.0 - objectMaterial.transparency) : 1.0\n            });\n\n            meshIds.push(meshId);\n\n            ctx.stats.numGeometries++;\n            ctx.stats.numVertices += geometryCfg.positions.length / 3;\n            ctx.stats.numTriangles += geometryCfg.indices.length / 3;\n        }\n    }\n\n    _parseSurfacesWithSharedMaterial(ctx, surfaces, sharedIndices, primitiveCfg) {\n\n        const vertices = ctx.vertices;\n\n        for (let i = 0; i < surfaces.length; i++) {\n\n            let boundary = [];\n            let holes = [];\n\n            for (let j = 0; j < surfaces[i].length; j++) {\n                if (boundary.length > 0) {\n                    holes.push(boundary.length);\n                }\n                const newBoundary = this._extractLocalIndices(ctx, surfaces[i][j], sharedIndices, primitiveCfg);\n                boundary.push(...newBoundary);\n            }\n\n            if (boundary.length === 3) { // Triangle\n\n                primitiveCfg.indices.push(boundary[0]);\n                primitiveCfg.indices.push(boundary[1]);\n                primitiveCfg.indices.push(boundary[2]);\n\n            } else if (boundary.length > 3) { // Polygon\n\n                let pList = [];\n\n                for (let k = 0; k < boundary.length; k++) {\n                    pList.push({\n                        x: vertices[sharedIndices[boundary[k]]][0],\n                        y: vertices[sharedIndices[boundary[k]]][1],\n                        z: vertices[sharedIndices[boundary[k]]][2]\n                    });\n                }\n\n                const normal = this._getNormalOfPositions(pList, math.vec3());\n                let pv = [];\n\n                for (let k = 0; k < pList.length; k++) {\n                    this._to2D(pList[k], normal, tempVec2a);\n                    pv.unshift(tempVec2a[0]);\n                    pv.unshift(tempVec2a[1]);\n                }\n\n                const tr = earcut(pv, holes, 2);\n\n                for (let k = 0; k < tr.length; k += 3) {\n                    primitiveCfg.indices.unshift(boundary[tr[k]]);\n                    primitiveCfg.indices.unshift(boundary[tr[k + 1]]);\n                    primitiveCfg.indices.unshift(boundary[tr[k + 2]]);\n                }\n            }\n        }\n    }\n\n    _extractLocalIndices(ctx, boundary, sharedIndices, geometryCfg) {\n\n        const vertices = ctx.vertices;\n        const newBoundary = [];\n\n        for (let i = 0, len = boundary.length; i < len; i++) {\n\n            const index = boundary[i];\n\n            if (sharedIndices.includes(index)) {\n                const vertexIndex = sharedIndices.indexOf(index);\n                newBoundary.push(vertexIndex);\n\n            } else {\n                geometryCfg.positions.push(vertices[index][0]);\n                geometryCfg.positions.push(vertices[index][1]);\n                geometryCfg.positions.push(vertices[index][2]);\n\n                newBoundary.push(sharedIndices.length);\n\n                sharedIndices.push(index);\n            }\n        }\n\n        return newBoundary\n    }\n\n    _getNormalOfPositions(positions, normal) {\n\n        for (let i = 0; i < positions.length; i++) {\n\n            let nexti = i + 1;\n            if (nexti === positions.length) {\n                nexti = 0;\n            }\n\n            normal[0] += ((positions[i].y - positions[nexti].y) * (positions[i].z + positions[nexti].z));\n            normal[1] += ((positions[i].z - positions[nexti].z) * (positions[i].x + positions[nexti].x));\n            normal[2] += ((positions[i].x - positions[nexti].x) * (positions[i].y + positions[nexti].y));\n        }\n\n        return math.normalizeVec3(normal);\n    }\n\n    _to2D(_p, _n, re) {\n\n        const p = tempVec3a;\n        const n = tempVec3b;\n        const x3 = tempVec3c;\n\n        p[0] = _p.x;\n        p[1] = _p.y;\n        p[2] = _p.z;\n\n        n[0] = _n.x;\n        n[1] = _n.y;\n        n[2] = _n.z;\n\n        x3[0] = 1.1;\n        x3[1] = 1.1;\n        x3[2] = 1.1;\n\n        const dist = math.lenVec3(math.subVec3(x3, n));\n\n        if (dist < 0.01) {\n            x3[0] += 1.0;\n            x3[1] += 2.0;\n            x3[2] += 3.0;\n        }\n\n        const dot = math.dotVec3(x3, n);\n        const tmp2 = math.mulVec3Scalar(n, dot, math.vec3());\n\n        x3[0] -= tmp2[0];\n        x3[1] -= tmp2[1];\n        x3[2] -= tmp2[2];\n\n        math.normalizeVec3(x3);\n\n        const y3 = math.cross3Vec3(n, x3, math.vec3());\n        const x = math.dotVec3(p, x3);\n        const y = math.dotVec3(p, y3);\n\n        re[0] = x;\n        re[1] = y;\n    }\n}\n\n/**\n * Default data access strategy for {@link DotBIMLoaderPlugin}.\n *\n * This just loads assets using XMLHttpRequest.\n */\nclass DotBIMDefaultDataSource {\n\n    constructor(cfg = {}) {\n        this.cacheBuster = (cfg.cacheBuster !== false);\n    }\n\n    _cacheBusterURL(url) {\n        if (!this.cacheBuster) {\n            return url;\n        }\n        const timestamp = new Date().getTime();\n        if (url.indexOf('?') > -1) {\n            return url + '&_=' + timestamp;\n        } else {\n            return url + '?_=' + timestamp;\n        }\n    }\n\n    /**\n     * Gets .BIM JSON.\n     *\n     * @param {String|Number} dotBIMSrc Identifies the .BIM JSON asset.\n     * @param {Function} ok Fired on successful loading of the .BIM JSON asset.\n     * @param {Function} error Fired on error while loading the .BIM JSON asset.\n     */\n    getDotBIM(dotBIMSrc, ok, error) {\n        utils.loadJSON(this._cacheBusterURL(dotBIMSrc),\n            (json) => {\n                ok(json);\n            },\n            function (errMsg) {\n                error(errMsg);\n            });\n    }\n}\n\n/**\n * {@link Viewer} plugin that loads models from [.bim](https://dotbim.net/) format.\n *\n * [<img src=\"https://xeokit.github.io/xeokit-sdk/assets/images/DotBIMLoaderPlugin-house.png\">](https://xeokit.github.io/xeokit-sdk/examples/buildings/#dotbim_House)\n *\n * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/buildings/#dotbim_House)]\n *\n * * Creates an {@link Entity} representing each .bim model it loads, which will have {@link Entity#isModel} set ````true````\n * and will be registered by {@link Entity#id} in {@link Scene#models}.\n * * Creates an {@link Entity} for each object within the .bim model. Those Entities will have {@link Entity#isObject}\n * set ````true```` and will be registered by {@link Entity#id} in {@link Scene#objects}.\n * * When loading, can set the World-space position, scale and rotation of each model within World space,\n * along with initial properties for all the model's {@link Entity}s.\n * * Allows to mask which types we want to load.\n * * Allows to configure initial viewer state for specified types (color, visibility, selection, highlighted, X-rayed, pickable, etc).\n *\n * ## Usage\n *\n * In the example below we'll load a house model from a [.bim file](/assets/models/dotbim/House.bim).\n *\n * This will create a bunch of {@link Entity}s that represents the model and its objects, along with\n * a {@link MetaModel} and {@link MetaObject}s that hold their metadata.\n *\n * ````javascript\n * import {Viewer, DotBIMLoaderPlugin} from \"xeokit-sdk.es.js\";\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // 1. Create a Viewer,\n * // 2. Arrange the camera,\n * // 3. Tweak the selection material (tone it down a bit)\n * //------------------------------------------------------------------------------------------------------------------\n *\n * // 1\n * const viewer = new Viewer({\n *      canvasId: \"myCanvas\",\n *      transparent: true\n * });\n *\n * // 2\n * viewer.camera.orbitPitch(20);\n * viewer.camera.orbitYaw(-45);\n *\n * // 3\n * viewer.scene.selectedMaterial.fillAlpha = 0.1;\n *\n * //------------------------------------------------------------------------------------------------------------------\n * // 1. Create a .bim loader plugin,\n * // 2. Load a .bim building model, emphasizing the edges to make it look nicer\n * //------------------------------------------------------------------------------------------------------------------\n *\n * // 1\n * const dotBIMLoader = new DotBIMLoaderPlugin(viewer);\n *\n * // 2\n * var model = dotBIMLoader.load({                                    // Returns an Entity that represents the model\n *      id: \"myModel\",\n *      src: \"House.bim\",\n *      edges: true\n * });\n *\n * // Find the model Entity by ID\n * model = viewer.scene.models[\"myModel\"];\n *\n * // Destroy the model\n * model.destroy();\n * ````\n *\n * ## Transforming\n *\n * We have the option to rotate, scale and translate each  *````.bim````* model as we load it.\n *\n * This lets us load multiple models, or even multiple copies of the same model, and position them apart from each other.\n *\n * In the example below, we'll rotate our model 90 degrees about its local X-axis, then\n * translate it 100 units along its X axis.\n *\n * ````javascript\n * const model = dotBIMLoader.load({\n *      src: \"House.bim\",\n *      rotation: [90,0,0],\n *      position: [100, 0, 0]\n * });\n * ````\n *\n * ## Including and excluding types\n *\n * We can also load only those objects that have the specified types. In the example below, we'll load only the\n * objects that represent walls.\n *\n * ````javascript\n * const model = dotBIMLoader.load({\n *     id: \"myModel\",\n *      src: \"House.bim\",\n *      includeTypes: [\"IfcWallStandardCase\"]\n * });\n * ````\n *\n * We can also load only those objects that **don't** have the specified types. In the example below, we'll load only the\n * objects that do not represent empty space.\n *\n * ````javascript\n * const model = dotBIMLoader.load({\n *     id: \"myModel\",\n *      src: \"House.bim\",\n *      excludeTypes: [\"IfcSpace\"]\n * });\n * ````\n *\n * # Configuring initial object appearances\n *\n * We can specify the custom initial appearance of loaded objects according to their types.\n *\n * This is useful for things like:\n *\n * * setting the colors to our objects according to their types,\n * * automatically hiding ````IfcSpace```` objects, and\n * * ensuring that ````IfcWindow```` objects are always transparent.\n * <br>\n * In the example below, we'll load a model, while configuring ````IfcSpace```` elements to be always initially invisible,\n * and ````IfcWindow```` types to be always translucent blue.\n *\n * ````javascript\n * const myObjectDefaults = {\n * \n *      IfcSpace: {\n *          visible: false\n *      },\n *      IfcWindow: {\n *          colorize: [0.337255, 0.303922, 0.870588], // Blue\n *          opacity: 0.3\n *      },\n * \n *      //...\n * \n *      DEFAULT: {\n *          colorize: [0.5, 0.5, 0.5]\n *      }\n * };\n *\n * const model4 = dotBIMLoader.load({\n *      id: \"myModel4\",\n *      src: \"House.bim\",\n *      objectDefaults: myObjectDefaults // Use our custom initial default states for object Entities\n * });\n * ````\n *\n * When we don't customize the appearance of types, as just above, then IfcSpace elements tend to obscure other\n * elements, which can be confusing.\n *\n * It's often helpful to make IfcSpaces transparent and unpickable, like this:\n *\n * ````javascript\n * const dotBIMLoader = new DotBIMLoaderPlugin(viewer, {\n *    objectDefaults: {\n *        IfcSpace: {\n *            pickable: false,\n *            opacity: 0.2\n *        }\n *    }\n * });\n * ````\n *\n * Alternatively, we could just make IfcSpaces invisible, which also makes them unpickable:\n *\n * ````javascript\n * const dotBIMLoader = new DotBIMLoaderPlugin(viewer, {\n *    objectDefaults: {\n *        IfcSpace: {\n *            visible: false\n *        }\n *    }\n * });\n * ````\n *\n * # Configuring a custom data source\n *\n * By default, DotBIMLoaderPlugin will load *````.bim````* files and metadata JSON over HTTP.\n *\n * In the example below, we'll customize the way DotBIMLoaderPlugin loads the files by configuring it with our own data source\n * object. For simplicity, our custom data source example also uses HTTP, using a couple of xeokit utility functions.\n *\n * ````javascript\n * import {utils} from \"xeokit-sdk.es.js\";\n *\n * class MyDataSource {\n * \n *      constructor() {\n *      }\n * \n *      // Gets the contents of the given .bim file in a JSON object\n *      getDotBIM(src, ok, error) {\n *          utils.loadJSON(dotBIMSrc,\n *             (json) => {\n *                 ok(json);\n *             },\n *             function (errMsg) {\n *                 error(errMsg);\n *             });\n *      }\n * }\n *\n * const dotBIMLoader2 = new DotBIMLoaderPlugin(viewer, {\n *       dataSource: new MyDataSource()\n * });\n *\n * const model5 = dotBIMLoader2.load({\n *      id: \"myModel5\",\n *      src: \"House.bim\"\n * });\n * ````\n * @class DotBIMLoaderPlugin\n */\nclass DotBIMLoaderPlugin extends Plugin {\n\n    /**\n     * @constructor\n     *\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} cfg  Plugin configuration.\n     * @param {String} [cfg.id=\"DotBIMLoader\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {Object} [cfg.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object.  Default value is {@link IFCObjectDefaults}.\n     * @param {Object} [cfg.dataSource] A custom data source through which the DotBIMLoaderPlugin can load metadata, glTF and binary attachments. Defaults to an instance of {@link DotBIMDefaultDataSource}, which loads over HTTP.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"DotBIMLoader\", viewer, cfg);\n\n        this.dataSource = cfg.dataSource;\n        this.objectDefaults = cfg.objectDefaults;\n    }\n\n    /**\n     * Sets a custom data source through which the DotBIMLoaderPlugin can .BIM files.\n     *\n     * Default value is {@link DotBIMDefaultDataSource}, which loads via an XMLHttpRequest.\n     *\n     * @type {Object}\n     */\n    set dataSource(value) {\n        this._dataSource = value || new DotBIMDefaultDataSource();\n    }\n\n    /**\n     * Gets the custom data source through which the DotBIMLoaderPlugin can load .BIM files.\n     *\n     * Default value is {@link DotBIMDefaultDataSource}, which loads via an XMLHttpRequest.\n     *\n     * @type {Object}\n     */\n    get dataSource() {\n        return this._dataSource;\n    }\n\n    /**\n     * Sets map of initial default states for each loaded {@link Entity} that represents an object.\n     *\n     * Default value is {@link IFCObjectDefaults}.\n     *\n     * @type {{String: Object}}\n     */\n    set objectDefaults(value) {\n        this._objectDefaults = value || IFCObjectDefaults;\n    }\n\n    /**\n     * Gets map of initial default states for each loaded {@link Entity} that represents an object.\n     *\n     * Default value is {@link IFCObjectDefaults}.\n     *\n     * @type {{String: Object}}\n     */\n    get objectDefaults() {\n        return this._objectDefaults;\n    }\n\n    /**\n     * Loads a .BIM model from a file into this DotBIMLoaderPlugin's {@link Viewer}.\n     *\n     * @param {*} params Loading parameters.\n     * @param {String} [params.id] ID to assign to the root {@link Entity#id}, unique among all components in the Viewer's {@link Scene}, generated automatically by default.\n     * @param {String} [params.src] Path to a .BIM file, as an alternative to the ````bim```` parameter.\n     * @param {*} [params.bim] .BIM JSON, as an alternative to the ````src```` parameter.\n     * @param {{String:Object}} [params.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.\n     * @param {String[]} [params.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.\n     * @param {String[]} [params.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.\n     * @param {Number[]} [params.origin=[0,0,0]] The double-precision World-space origin of the model's coordinates.\n     * @param {Number[]} [params.position=[0,0,0]] The single-precision position, relative to ````origin````.\n     * @param {Number[]} [params.scale=[1,1,1]] The model's scale.\n     * @param {Number[]} [params.rotation=[0,0,0]] The model's orientation, as Euler angles given in degrees, for each of the X, Y and Z axis.\n     * @param {Boolean} [params.backfaces=true] When true, always show backfaces, even on objects for which the .BIM material is single-sided. When false, only show backfaces on geometries whenever the .BIM material is double-sided.\n     * @param {Boolean} [params.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to\n     * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable\n     * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point\n     * primitives. Only works while {@link DTX#enabled} is also ````true````.\n     * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}\n     */\n    load(params = {}) {\n\n        if (params.id && this.viewer.scene.components[params.id]) {\n            this.error(\"Component with this ID already exists in viewer: \" + params.id + \" - will autogenerate this ID\");\n            delete params.id;\n        }\n\n        const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {\n            isModel: true,\n            backfaces: params.backfaces,\n            dtxEnabled: params.dtxEnabled,\n            rotation: params.rotation,\n            origin: params.origin\n        }));\n\n        const modelId = sceneModel.id;  // In case ID was auto-generated\n\n        if (!params.src && !params.dotBIM) {\n            this.error(\"load() param expected: src or dotBIM\");\n            return sceneModel; // Return new empty model\n        }\n\n        const objectDefaults = params.objectDefaults || this._objectDefaults || IFCObjectDefaults;\n\n        let includeTypes;\n        if (params.includeTypes) {\n            includeTypes = {};\n            for (let i = 0, len = params.includeTypes.length; i < len; i++) {\n                includeTypes[params.includeTypes[i]] = true;\n            }\n        }\n\n        let excludeTypes;\n        if (params.excludeTypes) {\n            excludeTypes = {};\n            if (!includeTypes) {\n                includeTypes = {};\n            }\n            for (let i = 0, len = params.excludeTypes.length; i < len; i++) {\n                includeTypes[params.excludeTypes[i]] = true;\n            }\n        }\n\n        const parseDotBIM = (ctx) => {\n\n            const fileData = ctx.fileData;\n            const sceneModel = ctx.sceneModel;\n\n            const dbMeshLoaded = {};\n\n            const projectId = math.createUUID();\n            const siteId = math.createUUID();\n            const buildingId = math.createUUID();\n            const buildingStoryId = math.createUUID();\n\n            const metaModelData = {\n                metaObjects: [\n                    {\n                        id: projectId,\n                        name: \"Project\",\n                        type: \"Project\",\n                        parent: null\n                    },\n                    {\n                        id: siteId,\n                        name: \"Site\",\n                        type: \"Site\",\n                        parent: projectId\n                    },\n                    {\n                        id: buildingId,\n                        name: \"Building\",\n                        type: \"Building\",\n                        parent: siteId\n                    },\n                    {\n                        id: buildingStoryId,\n                        name: \"BuildingStorey\",\n                        type: \"BuildingStorey\",\n                        parent: buildingId\n                    }\n                ],\n                propertySets: []\n            };\n\n            const parseDBMesh = (dbMeshId, element) => {\n                if (dbMeshLoaded[dbMeshId]) {\n                    return;\n                }\n\n                const dbMesh = fileData.meshes.find(obj => {\n                    return obj.mesh_id === element.mesh_id;\n                });\n                sceneModel.createGeometry({\n                    id: dbMeshId,\n                    primitive: \"triangles\",\n                    positions: dbMesh.coordinates,\n                    indices: dbMesh.indices\n                });\n                dbMeshLoaded[dbMeshId] = true;\n            };\n\n            const dbElements = fileData.elements;\n            for (let i = 0, len = dbElements.length; i < len; i++) {\n                const element = dbElements[i];\n                const elementType = element.type;\n                if (excludeTypes && excludeTypes[elementType]) {\n                    continue;\n\n                }\n                if (includeTypes && (!includeTypes[elementType])) {\n                    continue;\n                }\n                const info = element.info;\n                const objectId =\n                    element.guid !== undefined\n                        ? `${element.guid}`\n                        : (info !== undefined && info.id !== undefined\n                            ? info.id\n                            : i);\n\n                const dbMeshId = element.mesh_id;\n\n                const vector = element.vector;\n                const rotation = element.rotation;\n                const props = objectDefaults ? objectDefaults[elementType] || objectDefaults[\"DEFAULT\"] : null;\n                let visible = true;\n                let pickable = true;\n\n                if (element.face_colors === undefined) {\n\n                    parseDBMesh(dbMeshId, element);\n\n                    const meshId = `${objectId}-mesh-${dbMeshId}`;\n\n                    let color = element.color ? [element.color.r / 255.0, element.color.g / 255.0, element.color.b / 255.0] : [1, 1, 1];\n                    let opacity = element.color ? element.color.a / 255.0 : 1.0;\n\n                    if (props) {\n                        if (props.visible === false) {\n                            visible = false;\n                        }\n                        if (props.pickable === false) {\n                            pickable = false;\n                        }\n                        if (props.colorize) {\n                            color = props.colorize;\n                        }\n                        if (props.opacity !== undefined && props.opacity !== null) {\n                            opacity = props.opacity;\n                        }\n                    }\n\n                    sceneModel.createMesh({\n                        id: meshId,\n                        geometryId: dbMeshId,\n                        color: color,\n                        opacity: opacity,\n                        quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,\n                        position: vector ? [vector.x, vector.y, vector.z] : undefined\n                    });\n\n                    sceneModel.createEntity({\n                        id: objectId,\n                        meshIds: [meshId],\n                        visible: visible,\n                        pickable: pickable,\n                        isObject: true\n                    });\n                }\n                else {\n                    let faceColors = element.face_colors;\n                    let coloredTrianglesDictionary = {};\n                    let currentTriangleIndicesCount = 0;\n                    let dbMesh = fileData.meshes.find(obj => {\n                        return obj.mesh_id === element.mesh_id;\n                    });\n                    for (let i = 0, len = faceColors.length; i < len; i+=4) {\n                        let faceColor = [faceColors[i], faceColors[i+1], faceColors[i+2], faceColors[i+3]];\n                        if (coloredTrianglesDictionary[faceColor] === undefined) {\n                            coloredTrianglesDictionary[faceColor] = [];\n                        }\n                        let indexForPoint0 = dbMesh.indices[currentTriangleIndicesCount];\n                        let x0 = dbMesh.coordinates[indexForPoint0*3];\n                        let y0 = dbMesh.coordinates[indexForPoint0*3+1];\n                        let z0 = dbMesh.coordinates[indexForPoint0*3+2];\n                        let indexForPoint1 = dbMesh.indices[currentTriangleIndicesCount+1];\n                        let x1 = dbMesh.coordinates[indexForPoint1*3];\n                        let y1 = dbMesh.coordinates[indexForPoint1*3+1];\n                        let z1 = dbMesh.coordinates[indexForPoint1*3+2];\n                        let indexForPoint2 = dbMesh.indices[currentTriangleIndicesCount+2];\n                        let x2 = dbMesh.coordinates[indexForPoint2*3];\n                        let y2 = dbMesh.coordinates[indexForPoint2*3+1];\n                        let z2 = dbMesh.coordinates[indexForPoint2*3+2];\n                        coloredTrianglesDictionary[faceColor].push(x0, y0, z0, x1, y1, z1, x2, y2, z2);\n\n                        currentTriangleIndicesCount += 3;\n                    }\n                    let meshIds = [];\n                    for (const [faceColor, trianglesCoordinates] of Object.entries(coloredTrianglesDictionary)) {\n                        sceneModel.createGeometry({\n                            id: `${dbMeshId}-${faceColor}`,\n                            primitive: \"triangles\",\n                            positions: trianglesCoordinates,\n                            indices: [...Array(trianglesCoordinates.length / 3).keys()]\n                        });\n                        const meshId = `${objectId}-mesh-${dbMeshId}-${faceColor}`;\n                        const faceColorArray = faceColor.split(',').map(Number);\n\n                        let color = [faceColorArray[0] / 255.0, faceColorArray[1] / 255.0, faceColorArray[2] / 255.0];\n                        let opacity = faceColorArray[3] / 255.0;\n\n                        if (props) {\n                            if (props.visible === false) {\n                                visible = false;\n                            }\n                            if (props.pickable === false) {\n                                pickable = false;\n                            }\n                            if (props.colorize) {\n                                color = props.colorize;\n                            }\n                            if (props.opacity !== undefined && props.opacity !== null) {\n                                opacity = props.opacity;\n                            }\n                        }\n\n                        sceneModel.createMesh({\n                            id: meshId,\n                            geometryId: `${dbMeshId}-${faceColor}`,\n                            color: color,\n                            opacity: opacity,\n                            quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,\n                            position: vector ? [vector.x, vector.y, vector.z] : undefined\n                        });\n                        meshIds.push(meshId);\n                    }\n                    sceneModel.createEntity({\n                        id: objectId,\n                        meshIds: meshIds,\n                        visible: visible,\n                        pickable: pickable,\n                        isObject: true\n                    });\n                }\n\n                let properties = [];\n                for (let infoKey in info) {\n                    properties.push({\n                        name: infoKey,\n                        value: info[infoKey]\n                    });\n                }\n                metaModelData.propertySets.push({\n                    id: objectId,\n                    name: \"Properties\",\n                    properties: properties\n                });\n\n                metaModelData.metaObjects.push({\n                    id: objectId,\n                    name: info && info.Name && info.Name !== \"None\" ? info.Name : `${element.type} ${objectId}`,\n                    type: element.type,\n                    parent: buildingStoryId,\n                    propertySetIds: [objectId]\n                });\n            }\n\n            sceneModel.finalize();\n\n            this.viewer.metaScene.createMetaModel(modelId, metaModelData);\n\n            sceneModel.scene.once(\"tick\", () => {\n                if (sceneModel.destroyed) {\n                    return;\n                }\n                sceneModel.scene.fire(\"modelLoaded\", sceneModel.id); // FIXME: Assumes listeners know order of these two events\n                sceneModel.fire(\"loaded\", true, false); // Don't forget the event, for late subscribers\n            });\n        };\n\n        if (params.src) {\n            const src = params.src;\n            this.viewer.scene.canvas.spinner.processes++;\n            this._dataSource.getDotBIM(src, (fileData) => { // OK\n                    const ctx = {\n                        fileData,\n                        sceneModel,\n                        nextId: 0,\n                        error: function (errMsg) {\n                        }\n                    };\n                    parseDotBIM(ctx);\n                    this.viewer.scene.canvas.spinner.processes--;\n                },\n                (err) => {\n                    this.viewer.scene.canvas.spinner.processes--;\n                    this.error(err);\n                });\n        } else if (params.dotBIM) {\n            const ctx = {\n                fileData: params.dotBIM,\n                sceneModel,\n                nextId: 0,\n                error: function (errMsg) {\n                }\n            };\n            parseDotBIM(ctx);\n        }\n\n        sceneModel.once(\"destroyed\", () => {\n            this.viewer.metaScene.destroyMetaModel(modelId);\n        });\n\n        return sceneModel;\n    }\n\n    /**\n     * Destroys this DotBIMLoaderPlugin.\n     */\n    destroy() {\n        super.destroy();\n    }\n}\n\nconst hex2rgb = function(color) {\n    const rgb = idx => parseInt(color.substr(idx + 1, 2), 16) / 255;\n    return [ rgb(0), rgb(2), rgb(4) ];\n};\n\nconst basePolygon3D = function(scene, color, alpha) {\n    let mesh = null;\n\n    const updateBase = points => {\n        if (points)\n        {\n            if (mesh)\n            {\n                mesh.destroy();\n            }\n\n            try {\n                const [ baseVertices, baseTriangles ] = triangulateEarClipping(points.map(p => [ p[0], p[2] ]));\n\n                const positions = [ ].concat(...baseVertices.map(p => [p[0], points[0][1], p[1]])); // To convert from Float64Array into an Array\n                const ind = [ ].concat(...baseTriangles);\n                mesh = new Mesh(scene, {\n                    pickable: false, // otherwise there's a WebGL error inside PickMeshRenderer.prototype.drawMesh\n                    geometry: new ReadableGeometry(\n                        scene,\n                        {\n                            positions: positions,\n                            indices:   ind,\n                            normals:   math.buildNormals(positions, ind)\n                        }),\n                    material: new PhongMaterial(scene, {\n                        alpha: (alpha !== undefined) ? alpha : 0.5,\n                        backfaces: true,\n                        diffuse: hex2rgb(color)\n                    })\n                });\n            } catch (e) {\n                mesh = null;\n            }\n        }\n\n        if (mesh)\n        {\n            mesh.visible = !!points;\n        }\n    };\n    updateBase(null);\n\n    return {\n        updateBase: updateBase,\n        destroy: () => mesh && mesh.destroy()\n    };\n};\n\nconst startAARectCreateUI = function(scene, markersColor, pointerLens, select3dPoint, withPoints, onPointsSelected) {\n    const marker1 = marker3D(scene, markersColor);\n    const marker2 = marker3D(scene, markersColor);\n\n    const updatePointerLens = (pointerLens\n                               ? function(canvasPos) {\n                                   pointerLens.visible = !! canvasPos;\n                                   if (canvasPos)\n                                   {\n                                       pointerLens.canvasPos = canvasPos;\n                                   }\n                               }\n                               : () => { });\n\n    let deactivatePointSelection = select3dPoint(\n        () => {\n            updatePointerLens(null);\n            marker1.update(null);\n        },\n        (canvasPos, worldPos) => {\n            updatePointerLens(canvasPos);\n            marker1.update(worldPos);\n        },\n        function(point1CanvasPos, point1WorldPos) {\n            marker1.update(point1WorldPos);\n\n            deactivatePointSelection = select3dPoint(\n                function() {\n                    updatePointerLens(null);\n                    marker2.update(null);\n                    withPoints(null);\n                },\n                function(canvasPos, point2WorldPos) {\n                    updatePointerLens(canvasPos);\n                    marker2.update(point2WorldPos);\n                    withPoints((math.distVec3(point1WorldPos, point2WorldPos) > 0.01)\n                               &&\n                               [ point1WorldPos, point2WorldPos ]);\n                },\n                function(point2CanvasPos, point2WorldPos) {\n                    // `marker2.update' makes sure marker's position has been updated from its default [0,0,0]\n                    // This works around an unidentified bug somewhere around OcclusionLayer, that causes error\n                    // [.WebGL-0x13400c47e00] GL_INVALID_OPERATION: Vertex buffer is not big enough for the draw call\n                    marker2.update(point2WorldPos);\n\n                    marker1.destroy();\n                    marker2.destroy();\n                    updatePointerLens(null);\n\n                    onPointsSelected([ point1WorldPos, point2WorldPos ]);\n                });\n        });\n\n    return {\n        deactivate: function() {\n            deactivatePointSelection();\n            marker1.destroy();\n            marker2.destroy();\n            updatePointerLens(null);\n        }\n    };\n};\n\nconst mousePointSelector = function(viewer, ray2WorldPos) {\n    return function(onCancel, onChange, onCommit) {\n        const scene = viewer.scene;\n        const canvas = scene.canvas.canvas;\n        const moveTolerance = 20;\n\n        const copyCanvasPos = (event, vec2) => {\n            vec2[0] = event.clientX;\n            vec2[1] = event.clientY;\n            transformToNode(canvas.ownerDocument.documentElement, canvas, vec2);\n            return vec2;\n        };\n\n        const pickWorldPos = canvasPos => {\n            const origin = math.vec3();\n            const direction = math.vec3();\n            math.canvasPosToWorldRay(canvas, scene.camera.viewMatrix, scene.camera.projMatrix, scene.camera.projection, canvasPos, origin, direction);\n            return ray2WorldPos(origin, direction);\n        };\n\n        let buttonDown = false;\n        const resetAction = function() {\n            buttonDown = false;\n        };\n\n        const cleanup = function() {\n            resetAction();\n            canvas.removeEventListener(\"mousedown\", onMouseDown);\n            canvas.removeEventListener(\"mousemove\", onMouseMove);\n            viewer.cameraControl.off(onCameraControlRayMove);\n            canvas.removeEventListener(\"mouseup\", onMouseUp);\n        };\n\n        const startCanvasPos = math.vec2();\n        const onMouseDown = function(event) {\n            if (event.which === 1)\n            {\n                copyCanvasPos(event, startCanvasPos);\n                buttonDown = true;\n            }\n        };\n        canvas.addEventListener(\"mousedown\", onMouseDown);\n\n        const onMouseMove = function(event) {\n            const canvasPos = copyCanvasPos(event, math.vec2());\n            if (buttonDown && math.distVec2(startCanvasPos, canvasPos) > moveTolerance)\n            {\n                resetAction();\n                onCancel();\n            }\n        };\n        canvas.addEventListener(\"mousemove\", onMouseMove);\n\n        const onCameraControlRayMove = viewer.cameraControl.on(\n            \"rayMove\",\n            event => {\n                const canvasPos = event.canvasPos;\n                onChange(canvasPos, pickWorldPos(canvasPos));\n            });\n\n        const onMouseUp = function(event) {\n            if ((event.which === 1) && buttonDown)\n            {\n                cleanup();\n                const canvasPos = copyCanvasPos(event, math.vec2());\n                onCommit(canvasPos, pickWorldPos(canvasPos));\n            }\n        };\n        canvas.addEventListener(\"mouseup\", onMouseUp);\n\n        return cleanup;\n    };\n};\n\nconst planeIntersect = function(p0, n, origin, direction) {\n    const t = - (math.dotVec3(origin, n) - p0) / math.dotVec3(direction, n);\n    {\n        const worldPos = math.vec3();\n        math.mulVec3Scalar(direction, t, worldPos);\n        math.addVec3(origin, worldPos, worldPos);\n        return worldPos;\n    }\n};\n\n/**\n * @desc Renders a transparent box between two 3D points.\n *\n * See {@link ZonesPlugin} for more info.\n */\n\nclass Zone extends Component {\n\n    /**\n     * @private\n     */\n    constructor(plugin, cfg = {}) {\n\n        super(plugin.viewer.scene, cfg);\n\n        /**\n         * The {@link ZonesPlugin} that owns this Zone.\n         * @type {ZonesPlugin}\n         */\n        this.plugin = plugin;\n\n        this._container = cfg.container;\n        if (!this._container) {\n            throw \"config missing: container\";\n        }\n\n        this._eventSubs = {};\n\n        this.plugin.viewer.scene;\n\n        this._geometry = cfg.geometry;\n\n        cfg.onMouseOver ? (event) => {\n            cfg.onMouseOver(event, this);\n            this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mouseover', event));\n        } : null;\n\n        cfg.onMouseLeave ? (event) => {\n            cfg.onMouseLeave(event, this);\n            this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mouseleave', event));\n        } : null;\n\n        cfg.onContextMenu ? (event) => {\n            cfg.onContextMenu(event, this);\n        } : null;\n\n        this._alpha = ((\"alpha\" in cfg) && (cfg.alpha !== undefined)) ? cfg.alpha : 0.5;\n        this.color = cfg.color;\n\n        this._visible = true;\n\n        this._rebuildMesh();\n    }\n\n    _rebuildMesh() {\n        const scene       = this.plugin.viewer.scene;\n        const planeCoords = this._geometry.planeCoordinates.slice();\n        const downward    = this._geometry.height < 0;\n        const altitude    = this._geometry.altitude + (downward ? this._geometry.height : 0);\n        const height      = this._geometry.height * (downward ? -1 : 1);\n\n        const [ baseVertices, baseTriangles, isCCW ] = triangulateEarClipping(planeCoords); // TODO: prevent crossing edges\n\n        const pos = [ ];\n        const ind = [ ];\n\n\n        const addPlane = (isCeiling) => {\n            const baseIdx = pos.length;\n\n            for (let c of baseVertices) {\n                pos.push([ c[0], altitude + (isCeiling ? height : 0), c[1] ]);\n            }\n\n            for (let t of baseTriangles) {\n                ind.push(...(isCeiling ? t : t.slice(0).reverse()).map(i => i + baseIdx));\n            }\n        };\n        addPlane(false);        // floor\n        addPlane(true);         // ceiling\n\n\n        // sides\n        for (let i = 0; i < baseVertices.length; ++i) {\n            const a = baseVertices[i];\n            const b = baseVertices[(baseVertices.length + i + (isCCW ? 1 : -1)) % baseVertices.length];\n            const f = altitude;\n            const c = altitude + height;\n\n            const baseIdx = pos.length;\n\n            pos.push(\n                [ a[0], f, a[1] ],\n                [ b[0], f, b[1] ],\n                [ b[0], c, b[1] ],\n                [ a[0], c, a[1] ]\n            );\n\n            ind.push(...[ 0, 1, 2, 0, 2, 3 ].map(i => i + baseIdx));\n        }\n\n\n        if (this._zoneMesh) {\n            this._zoneMesh.destroy();\n        }\n\n\n        const min = idx => Math.min(...pos.map(p => p[idx]));\n        const max = idx => Math.max(...pos.map(p => p[idx]));\n\n        const xmin = min(0);\n        const ymin = min(1);\n        const zmin = min(2);\n        const xmax = max(0);\n        const ymax = max(1);\n        const zmax = max(2);\n\n        this._center = math.vec3([ (xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2 ]);\n\n        const positions = [].concat(...pos.map(p => math.subVec3(p, this._center, p)));\n        this._zoneMesh = new Mesh(scene, {\n            origin: this._center,\n            edges: this._edges,\n            geometry: new ReadableGeometry(\n                scene,\n                {\n                    positions: positions,\n                    indices:   ind,\n                    normals:   math.buildNormals(positions, ind)\n                }),\n            material: new PhongMaterial(scene, {\n                alpha: this._alpha,\n                backfaces: true,\n                diffuse: hex2rgb(this._color)\n            }),\n            visible: this._visible\n        });\n        this._zoneMesh.highlighted = this._highlighted;\n\n        this._zoneMesh.zone = this;\n\n        {\n            const u = math.vec2();\n            const v = math.vec2();\n\n            let baseArea = 0;\n\n            for (let t of baseTriangles) {\n                const p0 = baseVertices[t[0]];\n                const p1 = baseVertices[t[1]];\n                const p2 = baseVertices[t[2]];\n\n                math.subVec2(p1, p0, u);\n                math.subVec2(p2, p0, v);\n\n                baseArea += Math.abs(u[0] * v[1] - u[1] * v[0]);\n            }\n\n            this._baseArea = baseArea / 2;\n        }\n\n        this._metrics = null;\n    }\n\n    get baseArea() {\n        return this._baseArea;\n    }\n\n    get area() {\n        return this._getMetrics().area;\n    }\n\n    get volume() {\n        return this._getMetrics().volume;\n    }\n\n    _getMetrics() {\n        if (this._metrics === null) {\n            // Sum the volume of tetrahedrons formed by the origin and face triangles\n            let volume = 0;\n            let area = 0;\n            const geo = this._zoneMesh.geometry;\n            const pts = [ math.vec3(), math.vec3(), math.vec3() ];\n            const tmpVec3 = math.vec3();\n            for (let i = 0; i < geo.indices.length; i += 3) {\n                for (let off = 0; off < 3; ++off) {\n                    const p = pts[off];\n                    const pIdx = 3 * geo.indices[i + off];\n                    for (let c = 0; c < 3; ++c) {\n                        p[c] = geo.positions[pIdx + c];\n                    }\n                }\n                volume += math.dotVec3(pts[0], math.cross3Vec3(pts[1], pts[2], tmpVec3));\n                math.subVec3(pts[1], pts[0], pts[1]);\n                math.subVec3(pts[2], pts[0], pts[2]);\n                area += math.lenVec3(math.cross3Vec3(pts[1], pts[2], tmpVec3));\n            }\n\n            this._metrics = {\n                area: area / 2,\n                volume: volume / 6\n            };\n        }\n        return this._metrics;\n    }\n\n    sectionedAverage(sectionPlanes) {\n        const planeCoords = this._geometry.planeCoordinates.slice();\n\n        let faces = [ ];\n        {\n            const h = this._geometry.height;\n            const a = this._geometry.altitude;\n            const c = a + Math.max(0, h);\n            const f = a + Math.min(0, h);\n\n            const addPlane = (isCeiling) => {\n                const face = planeCoords.map(p => [ p[0], isCeiling ? c : f, p[1] ]);\n                faces.push(isCeiling ? face : face.slice(0).reverse());\n            };\n            addPlane(true);     // ceiling\n            addPlane(false);    // floor\n\n            // sides\n            const p = (idx, y) => [ planeCoords[idx][0], y, planeCoords[idx][1] ];\n            for (let i = 0; i < planeCoords.length; ++i)\n            {\n                const j = (i + 1) % planeCoords.length;\n                faces.push([ p(i, f), p(j, f), p(j, c), p(i, c) ]);\n            }\n        }\n\n        for (const s of sectionPlanes)\n        {\n            const dir = s.dir;\n            const dist = s.dist;\n            const newFaces = [ ];\n\n            for (const face of faces)\n            {\n                const EPSILON = 1e-5;\n                const COPLANAR = 0;\n                const FRONT = 1;\n                const BACK = 2;\n                const SPANNING = 3;\n\n                // Classify each point as well as the entire polygon into one of the above four classes.\n                let polygonType = 0;\n                const types = [ ];\n                for (let i = 0; i < face.length; i++) {\n                    const t = math.dotVec3(dir, face[i]) + dist;\n                    const type = (t < -EPSILON) ? BACK : (t > EPSILON) ? FRONT : COPLANAR;\n                    polygonType |= type;\n                    types.push(type);\n                }\n\n                // Put the polygon in the correct list, splitting it when necessary.\n                switch (polygonType) {\n                case COPLANAR:\n                    newFaces.push(face);\n                    break;\n                case FRONT:\n                    newFaces.push(face);\n                    break;\n                case BACK:\n                    break;\n                case SPANNING:\n                    const f = [ ];\n                    for (let i = 0; i < face.length; i++)\n                    {\n                        var j = (i + 1) % face.length;\n                        const ti = types[i];\n                        const tj = types[j];\n                        const vi = face[i];\n                        const vj = face[j];\n                        if (ti !== BACK)\n                        {\n                            f.push(vi);\n                        }\n\n                        if ((ti | tj) === SPANNING)\n                        {\n                            const diff = math.vec3();\n                            math.subVec3(vj, vi, diff);\n                            const t = - (dist + math.dotVec3(dir, vi)) / math.dotVec3(dir, diff);\n                            const v = [0,0,0];\n                            math.lerpVec3(t, 0, 1, vi, vj, v);\n                            f.push(v);\n                        }\n                    }\n                    if (f.length >= 3)\n                    {\n                        newFaces.push(f);\n                    }\n                    break;\n                }\n            }\n\n            faces = newFaces;\n        }\n\n        if (faces.length === 0)\n        {\n            return null;\n        }\n        else\n        {\n            const avg = math.vec3([ 0, 0, 0 ]);\n            const unique = new Set();\n\n            for (const f of faces)\n            {\n                for (const p of f)\n                {\n                    const id = p.map(x => x.toFixed(3)).join(\":\");\n                    if (! (unique.has(id)))\n                    {\n                        unique.add(id);\n                        math.addVec3(avg, p, avg);\n                    }\n                }\n            }\n\n            math.mulVec3Scalar(avg, 1 / unique.size, avg);\n\n            return avg;\n        }\n    }\n\n    get center() {\n        return this._center;\n    }\n\n    get altitude() {\n        return this._geometry.altitude;\n    }\n\n    set altitude(value) {\n        this._geometry.altitude = value;\n        this._rebuildMesh();\n    }\n\n    get height() {\n        return this._geometry.height;\n    }\n\n    set height(value) {\n        this._geometry.height = value;\n        this._rebuildMesh();\n    }\n\n    get highlighted() {\n        return this._highlighted;\n    }\n\n    set highlighted(value)\n    {\n        this._highlighted = value;\n        if (this._zoneMesh) {\n            this._zoneMesh.highlighted = value;\n        }\n    }\n\n    set color(value) {\n        this._color = value;\n        if (this._zoneMesh) {\n            this._zoneMesh.material.diffuse = hex2rgb(this._color);\n        }\n    }\n\n    get color() {\n        return this._color;\n    }\n\n    set alpha(value) {\n        this._alpha = value;\n        if (this._zoneMesh) {\n            this._zoneMesh.material.alpha = this._alpha;\n        }\n    }\n\n    get alpha() {\n        return this._alpha;\n    }\n\n    get edges() {\n        return this._edges;\n    }\n\n    set edges(edges) {\n        this._edges = edges;\n        if (this._zoneMesh) {\n            this._zoneMesh.edges = this._edges;\n        }\n    }\n\n    /**\n     * Sets whether this Zone is visible or not.\n     *\n     * @type {Boolean}\n     */\n    set visible(value) {\n        this._visible = !!value;\n        this._zoneMesh.visible = this._visible;\n        this._needUpdate();\n    }\n\n    /**\n     * Gets whether this Zone is visible or not.\n     *\n     * @type {Boolean}\n     */\n    get visible() {\n        return this._visible;\n    }\n\n    /**\n     * Gets this Zone as JSON.\n     *\n     * @returns {JSON}\n     */\n\n    getJSON() {\n        return {\n            id: this.id,\n            geometry: this._geometry,\n            alpha: this._alpha,\n            color: this._color\n        };\n    }\n\n    duplicate() {\n        return this.plugin.createZone(\n            {\n                id: math.createUUID(),\n                geometry: {\n                    planeCoordinates: this._geometry.planeCoordinates.map(c => c.slice()),\n                    altitude: this._geometry.altitude,\n                    height: this._geometry.height\n                },\n                alpha: this._alpha,\n                color: this._color\n            });\n    }\n\n    /**\n     * @private\n     */\n    destroy() {\n        this._zoneMesh.destroy();\n        super.destroy();\n    }\n}\n\nconst createAAZoneFromPoints = function(pos1, pos2, zoneAltitude, zoneHeight, zoneColor, zoneAlpha, zonesPlugin) {\n\n    const min = (idx) => Math.min(pos1[idx], pos2[idx]);\n    const max = (idx) => Math.max(pos1[idx], pos2[idx]);\n\n    const xmin = min(0);\n    const zmin = min(2);\n    const xmax = max(0);\n    const zmax = max(2);\n\n    return zonesPlugin.createZone(\n        {\n            id: math.createUUID(),\n            geometry: {\n                planeCoordinates: [\n                    [ xmin, zmax ],\n                    [ xmax, zmax ],\n                    [ xmax, zmin ],\n                    [ xmin, zmin ]\n                ],\n                altitude: zoneAltitude,\n                height: zoneHeight\n            },\n            alpha: zoneAlpha,\n            color: zoneColor\n        });\n};\n\n/**\n * Creates {@link Zone}s in a {@link ZonesPlugin} from mouse input.\n *\n * ## Usage\n *\n * [[Run example](/examples/measurement/#distance_createWithMouse_snapping)]\n *\n * ````javascript\n * import {Viewer, XKTLoaderPlugin, ZonesPlugin, ZonesMouseControl} from \"xeokit-sdk.es.js\";\n *\n * const viewer = new Viewer({\n *     canvasId: \"myCanvas\",\n * });\n *\n * viewer.camera.eye = [-3.93, 2.85, 27.01];\n * viewer.camera.look = [4.40, 3.72, 8.89];\n * viewer.camera.up = [-0.01, 0.99, 0.039];\n *\n * const xktLoader = new XKTLoaderPlugin(viewer);\n *\n * const sceneModel = xktLoader.load({\n *     id: \"myModel\",\n *     src: \"Duplex.xkt\"\n * });\n *\n * const zones = new ZonesPlugin(viewer);\n *\n * const zonesControl  = new ZonesMouseControl(Zones)\n * ````\n */\nclass ZonesAAZoneControl extends Component {\n\n    /**\n     * Creates a ZonesMouseControl bound to the given ZonesPlugin.\n     *\n     * @param {ZonesPlugin} zonesPlugin The ZonesPlugin to control.\n     * @param [cfg] Configuration\n     * @param {PointerLens} [cfg.pointerLens] A PointerLens to use to provide a magnified view of the cursor when snapping is enabled.\n     */\n    constructor(zonesPlugin, cfg, createSelect3dPoint) {\n        super(zonesPlugin.viewer.scene);\n\n        this.zonesPlugin = zonesPlugin;\n        this.pointerLens = cfg.pointerLens;\n        this.createSelect3dPoint = createSelect3dPoint;\n        this._deactivate = null;\n    }\n\n    get active() {\n        return !! this._deactivate;\n    }\n\n    activate(zoneAltitude, zoneHeight, zoneColor, zoneAlpha) {\n\n        if (this._deactivate) {\n            return;\n        }\n\n        if (typeof(zoneAltitude) === \"object\" && (zoneAltitude !== null)) {\n            const params = zoneAltitude;\n            const param = (name, defaultValue) => {\n                if (name in params) {\n                    return params[name];\n                } else if (defaultValue !== undefined) {\n                    return defaultValue;\n                } else {\n                    throw \"config missing: \" + name;\n                }\n            };\n\n            zoneAltitude = param(\"altitude\");\n            zoneHeight   = param(\"height\");\n            zoneColor    = param(\"color\", \"#008000\");\n            zoneAlpha    = param(\"alpha\", 0.5);\n        }\n\n        const zonesPlugin = this.zonesPlugin;\n        const viewer = zonesPlugin.viewer;\n        const scene = viewer.scene;\n        const self = this;\n\n        const select3dPoint = this.createSelect3dPoint(viewer, (origin, direction) => planeIntersect(zoneAltitude, math.vec3([ 0, 1, 0 ]), origin, direction));\n\n        (function rec() {\n            const basePolygon = basePolygon3D(scene, zoneColor, zoneAlpha);\n            const deactivate = startAARectCreateUI(\n                scene, zoneColor, self.pointerLens, select3dPoint,\n                points => {\n                    if (points) {\n                        const p0 = points[0];\n                        const p1 = points[1];\n                        const min = (idx) => Math.min(p0[idx], p1[idx]);\n                        const max = (idx) => Math.max(p0[idx], p1[idx]);\n\n                        const xmin = min(0);\n                        const ymin = min(1);\n                        const zmin = min(2);\n                        const xmax = max(0);\n                        max(1);\n                        const zmax = max(2);\n\n                        basePolygon.updateBase([ [ xmin, ymin, zmax ], [ xmax, ymin, zmax ],\n                                                 [ xmax, ymin, zmin ], [ xmin, ymin, zmin ] ]);\n                    } else {\n                        basePolygon.updateBase(null);\n                    }\n                },\n                points => {\n                    basePolygon.destroy();\n                    const zone = createAAZoneFromPoints(points[0], points[1], zoneAltitude, zoneHeight, zoneColor, zoneAlpha, zonesPlugin);\n                    let reactivate = true;\n                    self._deactivate = () => { reactivate = false; };\n                    self.fire(\"zoneEnd\", zone);\n                    if (reactivate)\n                    {\n                        rec();\n                    }\n                }).deactivate;\n            self._deactivate = () => {\n                deactivate();\n                basePolygon.destroy();\n            };\n        })();\n    }\n\n    deactivate() {\n        if (this._deactivate)\n        {\n            this._deactivate();\n            this._deactivate = null;\n        }\n    }\n\n    /**\n     * Destroys this ZonesMouseControl.\n     *\n     * Destroys any {@link Zone} under construction by this ZonesMouseControl.\n     */\n    destroy() {\n        this.deactivate();\n        super.destroy();\n    }\n}\n\nclass ZonesMouseControl extends ZonesAAZoneControl {\n    constructor(zonesPlugin, cfg = {}) {\n        super(\n            zonesPlugin,\n            cfg,\n            (viewer, ray2WorldPos) => mousePointSelector(viewer, ray2WorldPos));\n    }\n}\nclass ZonesTouchControl extends ZonesAAZoneControl {\n    constructor(zonesPlugin, cfg = {}) {\n        const pointerCircle = new PointerCircle(zonesPlugin.viewer);\n        super(\n            zonesPlugin,\n            cfg,\n            (viewer, ray2WorldPos) => touchPointSelector(viewer, pointerCircle, ray2WorldPos));\n        this.pointerCircle = pointerCircle;\n    }\n\n    destroy() {\n        this.pointerCircle.destroy();\n        super.destroy();\n    }\n}\n\n/**\n * ZonesPlugin documentation to be added, mostly compatible with DistanceMeasurementsPlugin.\n */\nclass ZonesPlugin extends Plugin {\n\n    /**\n     * @constructor\n     * @param {Viewer} viewer The Viewer.\n     * @param {Object} [cfg]  Plugin configuration.\n     * @param {String} [cfg.id=\"Zones\"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.\n     * @param {HTMLElement} [cfg.container] Container DOM element for markers and labels. Defaults to ````document.body````.\n     * @param {string} [cfg.defaultColor=#00BBFF] The default color of the length dots, wire and label.\n     * @param {number} [cfg.zIndex] If set, the wires, dots and labels will have this zIndex (+1 for dots and +2 for labels).\n     * @param {PointerCircle} [cfg.pointerLens] A PointerLens to help the user position the pointer. This can be shared with other plugins.\n     */\n    constructor(viewer, cfg = {}) {\n\n        super(\"Zones\", viewer);\n\n        this._pointerLens = cfg.pointerLens;\n\n        this._container = cfg.container || document.body;\n\n        this._zones = [ ];\n\n        this.defaultColor = cfg.defaultColor !== undefined ? cfg.defaultColor : \"#00BBFF\";\n        this.zIndex = cfg.zIndex || 10000;\n\n        this._onMouseOver = (event, zone) => {\n            this.fire(\"mouseOver\", {\n                plugin: this,\n                zone,\n                event\n            });\n        };\n\n        this._onMouseLeave = (event, zone) => {\n            this.fire(\"mouseLeave\", {\n                plugin: this,\n                zone,\n                event\n            });\n        };\n\n        this._onContextMenu = (event, zone) => {\n            this.fire(\"contextMenu\", {\n                plugin: this,\n                zone,\n                event\n            });\n        };\n    }\n\n    /**\n     * Creates a {@link Zone}.\n     *\n     * The Zone is then registered by {@link Zone#id} in {@link ZonesPlugin#zones}.\n     *\n     * @param {Object} params {@link Zone} configuration.\n     * @param {String} params.id Unique ID to assign to {@link Zone#id}. The Zone will be registered by this in {@link ZonesPlugin#zones} and {@link Scene.components}. Must be unique among all components in the {@link Viewer}.\n     * @param {Number[]} params.origin.worldPos Origin World-space 3D position.\n     * @param {Entity} params.origin.entity Origin Entity.\n     * @param {Number[]} params.target.worldPos Target World-space 3D position.\n     * @param {Entity} params.target.entity Target Entity.\n     * @param {string} [params.color] The color of the length dot, wire and label.\n     * @returns {Zone} The new {@link Zone}.\n     */\n    createZone(params = {}) {\n        if (this.viewer.scene.components[params.id]) {\n            this.error(\"Viewer scene component with this ID already exists: \" + params.id);\n            delete params.id;\n        }\n\n        const zone = new Zone(this, {\n            id: params.id,\n            plugin: this,\n            container: this._container,\n            geometry: params.geometry,\n            alpha: params.alpha,\n            color: params.color,\n            onMouseOver: this._onMouseOver,\n            onMouseLeave: this._onMouseLeave,\n            onContextMenu: this._onContextMenu\n        });\n        this._zones.push(zone);\n        zone.on(\"destroyed\", () => {\n            const idx = this._zones.indexOf(zone);\n            if (idx >= 0) {\n                this._zones.splice(idx, 1);\n            }\n        });\n        this.fire(\"zoneCreated\", zone);\n        return zone;\n    }\n\n    /**\n     * Gets the existing {@link Zone}s, each mapped to its {@link Zone#id}.\n     *\n     * @type {{String:Zone}}\n     */\n    get zones() {\n        return this._zones;\n    }\n\n    /**\n     * Destroys this ZonesPlugin.\n     *\n     * Destroys all {@link Zone}s first.\n     */\n    destroy() {\n        super.destroy();\n    }\n}\n\nconst startPolysurfaceZoneCreateUI = function(scene, zoneAltitude, zoneHeight, zoneColor, zoneAlpha, pointerLens, zonesPlugin, select3dPoint, onZoneCreated) {\n    const updatePointerLens = (pointerLens\n                               ? function(canvasPos) {\n                                   pointerLens.visible = !! canvasPos;\n                                   if (canvasPos)\n                                   {\n                                       pointerLens.canvasPos = canvasPos;\n                                   }\n                               }\n                               : () => { });\n\n    let deactivatePointSelection;\n    const cleanups = [ () => updatePointerLens(null) ];\n\n    const basePolygon = basePolygon3D(scene, zoneColor, zoneAlpha);\n    cleanups.push(() => basePolygon.destroy());\n\n    (function selectNextPoint(markers) {\n        const marker = marker3D(scene, zoneColor);\n        const wire = (markers.length > 0) && wire3D(scene, zoneColor);\n        const wireStart = wire && markers[markers.length - 1].getWorldPos();\n\n        cleanups.push(() => {\n            marker.destroy();\n            wire && wire.destroy();\n        });\n\n        const firstMarker = (markers.length > 0) && markers[0];\n        const getSnappedFirst = function(canvasPos) {\n            const firstCanvasPos = firstMarker && firstMarker.getCanvasPos();\n            const snapToFirst = firstCanvasPos && (math.distVec2(firstCanvasPos, canvasPos) < 10);\n            return snapToFirst && { canvasPos: firstCanvasPos, worldPos: firstMarker.getWorldPos() };\n        };\n\n        const lastSegmentIntersects = (function() {\n            const onSegment = (p, q, r) => ((q[0] <= Math.max(p[0], r[0])) &&\n                                            (q[0] >= Math.min(p[0], r[0])) &&\n                                            (q[1] <= Math.max(p[1], r[1])) &&\n                                            (q[1] >= Math.min(p[1], r[1])));\n\n            const orient = (p, q, r) => {\n                const val = (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]);\n                // collinear\n                // clockwise\n                // counterclockwise\n                return ((val === 0) ? 0 : ((val > 0) ? 1 : 2));\n            };\n\n            return function(pos2D, excludeFirstSegment) {\n                const a = pos2D[pos2D.length - 2];\n                const b = pos2D[pos2D.length - 1];\n\n                for (let i = excludeFirstSegment ? 1 : 0; i < pos2D.length - 2 - 1; ++i)\n                {\n                    const c = pos2D[i];\n                    const d = pos2D[i + 1];\n\n                    const o1 = orient(a, b, c);\n                    const o2 = orient(a, b, d);\n                    const o3 = orient(c, d, a);\n                    const o4 = orient(c, d, b);\n\n                    if (((o1 !== o2) && (o3 !== o4))       || // General case\n                        ((o1 === 0) && onSegment(a, c, b)) || // a, b and c are collinear and c lies on segment ab\n                        ((o2 === 0) && onSegment(a, d, b)) || // a, b and d are collinear and d lies on segment ab\n                        ((o3 === 0) && onSegment(c, a, d)) || // c, d and a are collinear and a lies on segment cd\n                        ((o4 === 0) && onSegment(c, b, d)))   // c, d and b are collinear and b lies on segment cd\n                    {\n                        return true;\n                    }\n                }\n\n                return false;\n            };\n        })();\n\n        deactivatePointSelection = select3dPoint(\n            () => {\n                updatePointerLens(null);\n                marker.update(null);\n                wire && wire.update(wireStart, null);\n                basePolygon.updateBase((markers.length > 2) ? markers.map(m => m.getWorldPos()) : null);\n            },\n            (canvasPos, worldPos) => {\n                const snappedFirst = (markers.length > 2) && getSnappedFirst(canvasPos);\n                firstMarker && firstMarker.setHighlighted(!! snappedFirst);\n                updatePointerLens(snappedFirst ? snappedFirst.canvasPos : canvasPos);\n                marker.update((! snappedFirst) && worldPos);\n                wire && wire.update(wireStart, snappedFirst ? snappedFirst.worldPos : worldPos);\n                if ((markers.length >= 2))\n                {\n                    const pos = markers.map(m => m.getWorldPos()).concat(snappedFirst ? [] : [worldPos]);\n                    const inter = lastSegmentIntersects(pos.map(p => [ p[0], p[2] ]), snappedFirst);\n                    basePolygon.updateBase(inter ? null : pos);\n                }\n                else\n                    basePolygon.updateBase(null);\n            },\n            function(canvasPos, worldPos) {\n                const snappedFirst = (markers.length > 2) && getSnappedFirst(canvasPos);\n                const pos = markers.map(m => m.getWorldPos()).concat(snappedFirst ? [] : [worldPos]);\n                basePolygon.updateBase(pos);\n                const pos2D = pos.map(p => [ p[0], p[2] ]);\n                if ((markers.length > 2) && lastSegmentIntersects(pos2D, snappedFirst))\n                {\n                    cleanups.pop()();\n                    selectNextPoint(markers);\n                }\n                else if (snappedFirst)\n                {\n                    // `marker2.update' makes sure marker's position has been updated from its default [0,0,0]\n                    // This works around an unidentified bug somewhere around OcclusionLayer, that causes error\n                    // [.WebGL-0x13400c47e00] GL_INVALID_OPERATION: Vertex buffer is not big enough for the draw call\n                    marker.update(worldPos);\n\n                    cleanups.forEach(c => c());\n                    onZoneCreated(\n                        zonesPlugin.createZone(\n                            {\n                                id: math.createUUID(),\n                                geometry: {\n                                    planeCoordinates: pos2D,\n                                    altitude: zoneAltitude,\n                                    height: zoneHeight\n                                },\n                                alpha: zoneAlpha,\n                                color: zoneColor\n                            }));\n                }\n                else\n                {\n                    marker.update(worldPos);\n                    wire && wire.update(wireStart, worldPos);\n                    selectNextPoint(markers.concat(marker));\n                }\n            });\n    })([ ]);\n\n    return {\n        closeSurface: function() {\n            throw \"TODO\";\n        },\n        deactivate: function() {\n            deactivatePointSelection();\n            cleanups.forEach(c => c());\n        }\n    };\n};\n\nclass ZonesPolysurfaceMouseControl extends Component {\n\n    constructor(zonesPlugin, cfg = {}) {\n        super(zonesPlugin.viewer.scene);\n\n        this.zonesPlugin = zonesPlugin;\n        this.pointerLens = cfg.pointerLens;\n        this._action = null;\n    }\n\n    get active() {\n        return !! this._action;\n    }\n\n    activate(zoneAltitude, zoneHeight, zoneColor, zoneAlpha) {\n\n        if (typeof(zoneAltitude) === \"object\" && (zoneAltitude !== null)) {\n            const params = zoneAltitude;\n            const param = (name, defaultValue) => {\n                if (name in params) {\n                    return params[name];\n                } else if (defaultValue !== undefined) {\n                    return defaultValue;\n                } else {\n                    throw \"config missing: \" + name;\n                }\n            };\n\n            zoneAltitude = param(\"altitude\");\n            zoneHeight   = param(\"height\");\n            zoneColor    = param(\"color\", \"#008000\");\n            zoneAlpha    = param(\"alpha\", 0.5);\n        }\n\n        if (this._action) {\n            return;\n        }\n\n        const zonesPlugin = this.zonesPlugin;\n        const viewer = zonesPlugin.viewer;\n        const scene = viewer.scene;\n        const self = this;\n\n        const select3dPoint = mousePointSelector(\n            viewer,\n            function(origin, direction) {\n                return planeIntersect(zoneAltitude, math.vec3([ 0, 1, 0 ]), origin, direction);\n            });\n\n        (function rec() {\n            self._action = startPolysurfaceZoneCreateUI(\n                scene, zoneAltitude, zoneHeight, zoneColor, zoneAlpha, self.pointerLens, zonesPlugin, select3dPoint,\n                zone => {\n                    let reactivate = true;\n                    self._action = { deactivate: () => { reactivate = false; } };\n                    self.fire(\"zoneEnd\", zone);\n                    if (reactivate)\n                    {\n                        rec();\n                    }\n                });\n        })();\n    }\n\n    deactivate() {\n        if (this._action)\n        {\n            this._action.deactivate();\n            this._action = null;\n        }\n    }\n\n    destroy() {\n        this.deactivate();\n        super.destroy();\n    }\n}\n\nclass ZonesPolysurfaceTouchControl extends Component {\n\n    constructor(zonesPlugin, cfg = {}) {\n        super(zonesPlugin.viewer.scene);\n\n        this.zonesPlugin = zonesPlugin;\n        this.pointerLens = cfg.pointerLens;\n        this.pointerCircle = new PointerCircle(zonesPlugin.viewer);\n        this._action = null;\n    }\n\n    get active() {\n        return !! this._action;\n    }\n\n    activate(zoneAltitude, zoneHeight, zoneColor, zoneAlpha) {\n\n        if (typeof(zoneAltitude) === \"object\" && (zoneAltitude !== null)) {\n            const params = zoneAltitude;\n            const param = (name, defaultValue) => {\n                if (name in params) {\n                    return params[name];\n                } else if (defaultValue !== undefined) {\n                    return defaultValue;\n                } else {\n                    throw \"config missing: \" + name;\n                }\n            };\n\n            zoneAltitude = param(\"altitude\");\n            zoneHeight   = param(\"height\");\n            zoneColor    = param(\"color\", \"#008000\");\n            zoneAlpha    = param(\"alpha\", 0.5);\n        }\n\n        if (this._action) {\n            return;\n        }\n\n        const zonesPlugin = this.zonesPlugin;\n        const viewer = zonesPlugin.viewer;\n        const scene = viewer.scene;\n        const self = this;\n\n        const select3dPoint = touchPointSelector(\n            viewer,\n            this.pointerCircle,\n            function(origin, direction) {\n                return planeIntersect(zoneAltitude, math.vec3([ 0, 1, 0 ]), origin, direction);\n            });\n\n        (function rec() {\n            self._action = startPolysurfaceZoneCreateUI(\n                scene, zoneAltitude, zoneHeight, zoneColor, zoneAlpha, self.pointerLens, zonesPlugin, select3dPoint,\n                zone => {\n                    let reactivate = true;\n                    self._action = { deactivate: () => { reactivate = false; } };\n                    self.fire(\"zoneEnd\", zone);\n                    if (reactivate)\n                    {\n                        rec();\n                    }\n                });\n        })();\n    }\n\n    deactivate() {\n        if (this._action)\n        {\n            this._action.deactivate();\n            this._action = null;\n        }\n    }\n\n    destroy() {\n        this.deactivate();\n        super.destroy();\n    }\n}\n\nclass ZoneEditControl extends Component {\n    constructor(zone, cfg, handleMouseEvents, handleTouchEvents) {\n        const viewer = zone.plugin.viewer;\n        const scene = viewer.scene;\n        super(scene);\n\n        const altitude = zone._geometry.altitude;\n\n        const dots = zone._geometry.planeCoordinates.map(planeCoord => {\n            const dotParent = scene.canvas.canvas.ownerDocument.body;\n            const dot = new Dot3D(scene, {}, dotParent, { fillColor: zone._color });\n            dot.worldPos = math.vec3([ planeCoord[0], altitude, planeCoord[1] ]);\n            dot.on(\"worldPos\", function() {\n                planeCoord[0] = dot.worldPos[0];\n                planeCoord[1] = dot.worldPos[2];\n                try {\n                    zone._rebuildMesh();\n                } catch (e) {\n                    if (zone._zoneMesh) {\n                        zone._zoneMesh.destroy();\n                        zone._zoneMesh = null;\n                    }\n                }\n            });\n            return dot;\n        });\n\n        const cleanupDrag = activateDraggableDots({\n            viewer: viewer,\n            handleMouseEvents: handleMouseEvents,\n            handleTouchEvents: handleTouchEvents,\n            pointerLens: cfg && cfg.pointerLens,\n            dots: dots,\n            ray2WorldPos: (orig, dir) => planeIntersect(altitude, math.vec3([ 0, 1, 0 ]), orig, dir),\n            onEnd: (initPos, dot) => {\n                if (zone._zoneMesh)\n                {\n                    this.fire(\"edited\");\n                }\n                return !! zone._zoneMesh;\n            }\n        });\n\n        const cleanup = function() {\n            cleanupDrag();\n            dots.forEach(d => d.destroy());\n        };\n\n        const destroyCb = zone.on(\"destroyed\", cleanup);\n\n        this._deactivate = function() {\n            zone.off(\"destroyed\", destroyCb);\n            cleanup();\n        };\n    }\n\n    deactivate() {\n        this._deactivate();\n        super.destroy();\n    }\n}\n\nclass ZoneEditMouseControl extends ZoneEditControl {\n    constructor(zone, cfg) {\n        super(zone, cfg, true, false);\n    }\n}\n\nclass ZoneEditTouchControl extends ZoneEditControl {\n    constructor(zone, cfg) {\n        super(zone, cfg, false, true);\n    }\n}\n\n\nclass ZoneTranslateControl extends Component {\n    constructor(zone, cfg, handleMouseEvents, handleTouchEvents) {\n        const viewer = zone.plugin.viewer;\n        const scene = viewer.scene;\n        const canvas = scene.canvas.canvas;\n\n        super(scene);\n        const self = this;\n\n        const altitude = zone._geometry.altitude;\n        const pointerLens = cfg && cfg.pointerLens;\n        const updatePointerLens = (pointerLens\n                                   ? function(canvasPos) {\n                                       pointerLens.visible = !! canvasPos;\n                                       if (canvasPos)\n                                       {\n                                           pointerLens.canvasPos = canvasPos;\n                                       }\n                                   }\n                                   : () => { });\n\n        const ray2WorldPos = (orig, dir) => planeIntersect(altitude, math.vec3([ 0, 1, 0 ]), orig, dir);\n\n        const pickWorldPos = canvasPos => {\n            const origin = math.vec3();\n            const direction = math.vec3();\n            math.canvasPosToWorldRay(canvas, scene.camera.viewMatrix, scene.camera.projMatrix, scene.camera.projection, canvasPos, origin, direction);\n            return ray2WorldPos(origin, direction);\n        };\n\n        const copyCanvasPos = (event, vec2) => {\n            vec2[0] = event.clientX;\n            vec2[1] = event.clientY;\n            transformToNode(canvas.ownerDocument.documentElement, canvas, vec2);\n            return vec2;\n        };\n\n        const canvasHandle = function(type, cb) {\n            const callback = event => {\n                event.preventDefault();\n                cb(event);\n            };\n            canvas.addEventListener(type, callback);\n            return () => canvas.removeEventListener(type, callback);\n        };\n\n        let cleanupCurrentDrag = () => { };\n\n        const startDrag = function(event, onMoveType, onEndType, matchesEvent) {\n            const e = matchesEvent(event);\n            const canvasPos = copyCanvasPos(e, math.vec2());\n            const pickRecord = viewer.scene.pick({ canvasPos: canvasPos, includeEntities: [ zone._zoneMesh.id ] });\n            const pickZone = pickRecord && pickRecord.entity && pickRecord.entity.zone;\n\n            if (pickZone === zone)\n            {\n                cleanupCurrentDrag();\n\n                canvas.style.cursor = \"move\";\n                viewer.cameraControl.active = false;\n\n                const onChange = (function() {\n                    const initCoords = zone._geometry.planeCoordinates.map(c => c.slice());\n                    const initWorldPos = pickWorldPos(canvasPos);\n                    const initDragCoord = math.vec2([ initWorldPos[0], initWorldPos[2] ]);\n                    const dPos = math.vec2();\n\n                    return function(canvasPos) {\n                        const worldPos = pickWorldPos(canvasPos);\n                        dPos[0] = worldPos[0];\n                        dPos[1] = worldPos[2];\n                        math.subVec2(initDragCoord, dPos, dPos);\n\n                        zone._geometry.planeCoordinates.forEach((planeCoord, idx) => {\n                            math.subVec2(initCoords[idx], dPos, planeCoord);\n                        });\n\n                        try {\n                            zone._rebuildMesh();\n                        } catch (e) {\n                            if (zone._zoneMesh) {\n                                zone._zoneMesh.destroy();\n                                zone._zoneMesh = null;\n                            }\n                        }\n                    };\n                })();\n\n                const cleanupMove = canvasHandle(\n                    onMoveType,\n                    function(event) {\n                        const e = matchesEvent(event);\n                        if (e)\n                        {\n                            const canvasPos = copyCanvasPos(e, math.vec2());\n                            onChange(canvasPos);\n                            updatePointerLens(canvasPos);\n                        }\n                    });\n\n                const cleanupEnd  = canvasHandle(\n                    onEndType,\n                    function(event) {\n                        const e = matchesEvent(event);\n                        if (e)\n                        {\n                            const canvasPos = copyCanvasPos(e, math.vec2());\n                            onChange(canvasPos);\n                            updatePointerLens(null);\n                            cleanupCurrentDrag();\n                            self.fire(\"translated\");\n                        }\n                    });\n\n                cleanupCurrentDrag = function() {\n                    cleanupCurrentDrag = () => { };\n                    canvas.style.cursor = \"default\";\n                    viewer.cameraControl.active = true;\n                    cleanupMove();\n                    cleanupEnd();\n                };\n            }\n        };\n\n        const startDragCbs = [ ];\n\n        if (handleMouseEvents) {\n            startDragCbs.push(\n                canvasHandle(\"mousedown\", event => {\n                    if (event.which === 1) {\n                        startDrag(\n                            event,\n                            \"mousemove\",\n                            \"mouseup\",\n                            event => (event.which === 1) && event);\n                    }\n                }));\n        }\n\n        if (handleTouchEvents) {\n            startDragCbs.push(\n                canvasHandle(\"touchstart\", event => {\n                    if (event.touches.length === 1) {\n                        const touchStartId = event.touches[0].identifier;\n                        startDrag(\n                            event,\n                            \"touchmove\",\n                            \"touchend\",\n                            event => [...event.changedTouches].find(e => e.identifier === touchStartId));\n                    }\n                }));\n        }\n\n        const cleanup = function() {\n            cleanupCurrentDrag();\n            startDragCbs.forEach(cb => cb());\n            updatePointerLens(null);\n        };\n\n        const destroyCb = zone.on(\"destroyed\", cleanup);\n\n        this._deactivate = function() {\n            zone.off(\"destroyed\", destroyCb);\n            cleanup();\n        };\n    }\n\n    deactivate() {\n        this._deactivate();\n        super.destroy();\n    }\n}\n\nclass ZoneTranslateMouseControl extends ZoneTranslateControl {\n    constructor(zone, cfg) {\n        super(zone, cfg, true, false);\n    }\n}\n\nclass ZoneTranslateTouchControl extends ZoneTranslateControl {\n    constructor(zone, cfg) {\n        super(zone, cfg, false, true);\n    }\n}\n\nexports.AlphaFormat = AlphaFormat;\nexports.AmbientLight = AmbientLight;\nexports.AngleMeasurementEditMouseControl = AngleMeasurementEditMouseControl;\nexports.AngleMeasurementEditTouchControl = AngleMeasurementEditTouchControl;\nexports.AngleMeasurementsControl = AngleMeasurementsControl;\nexports.AngleMeasurementsMouseControl = AngleMeasurementsMouseControl;\nexports.AngleMeasurementsPlugin = AngleMeasurementsPlugin;\nexports.AngleMeasurementsTouchControl = AngleMeasurementsTouchControl;\nexports.AnnotationsPlugin = AnnotationsPlugin;\nexports.AxisGizmoPlugin = AxisGizmoPlugin;\nexports.BCFViewpointsPlugin = BCFViewpointsPlugin;\nexports.Bitmap = Bitmap;\nexports.ByteType = ByteType;\nexports.CameraMemento = CameraMemento;\nexports.CameraPath = CameraPath;\nexports.CameraPathAnimation = CameraPathAnimation;\nexports.CityJSONLoaderPlugin = CityJSONLoaderPlugin;\nexports.ClampToEdgeWrapping = ClampToEdgeWrapping;\nexports.Component = Component;\nexports.CompressedMediaType = CompressedMediaType;\nexports.Configs = Configs;\nexports.ContextMenu = ContextMenu;\nexports.CubicBezierCurve = CubicBezierCurve;\nexports.Curve = Curve;\nexports.CxConverterIFCLoaderPlugin = CxConverterIFCLoaderPlugin;\nexports.DefaultLoadingManager = DefaultLoadingManager;\nexports.DepthFormat = DepthFormat;\nexports.DepthStencilFormat = DepthStencilFormat;\nexports.DirLight = DirLight;\nexports.DistanceMeasurementEditControl = DistanceMeasurementEditControl;\nexports.DistanceMeasurementEditMouseControl = DistanceMeasurementEditMouseControl;\nexports.DistanceMeasurementEditTouchControl = DistanceMeasurementEditTouchControl;\nexports.DistanceMeasurementsControl = DistanceMeasurementsControl;\nexports.DistanceMeasurementsMouseControl = DistanceMeasurementsMouseControl;\nexports.DistanceMeasurementsPlugin = DistanceMeasurementsPlugin;\nexports.DistanceMeasurementsTouchControl = DistanceMeasurementsTouchControl;\nexports.Dot3D = Dot3D;\nexports.DotBIMDefaultDataSource = DotBIMDefaultDataSource;\nexports.DotBIMLoaderPlugin = DotBIMLoaderPlugin;\nexports.EdgeMaterial = EdgeMaterial;\nexports.EmphasisMaterial = EmphasisMaterial;\nexports.FaceAlignedSectionPlanesPlugin = FaceAlignedSectionPlanesPlugin;\nexports.FastNavPlugin = FastNavPlugin;\nexports.FloatType = FloatType;\nexports.Fresnel = Fresnel;\nexports.Frustum = Frustum$1;\nexports.FrustumPlane = FrustumPlane;\nexports.GIFMediaType = GIFMediaType;\nexports.GLTFDefaultDataSource = GLTFDefaultDataSource;\nexports.GLTFLoaderPlugin = GLTFLoaderPlugin;\nexports.HalfFloatType = HalfFloatType;\nexports.IFCOpenShellDefaultDataSource = IFCOpenShellDefaultDataSource;\nexports.IFCOpenShellLoaderPlugin = IFCOpenShellLoaderPlugin;\nexports.ImagePlane = ImagePlane;\nexports.IntType = IntType;\nexports.JPEGMediaType = JPEGMediaType;\nexports.KTX2TextureTranscoder = KTX2TextureTranscoder;\nexports.LASLoaderPlugin = LASLoaderPlugin;\nexports.Label3D = Label3D;\nexports.LambertMaterial = LambertMaterial;\nexports.LightMap = LightMap;\nexports.LineSet = LineSet;\nexports.LinearEncoding = LinearEncoding;\nexports.LinearFilter = LinearFilter;\nexports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\nexports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\nexports.LinearMipmapLinearFilter = LinearMipmapLinearFilter;\nexports.LinearMipmapNearestFilter = LinearMipmapNearestFilter;\nexports.Loader = Loader;\nexports.LoadingManager = LoadingManager;\nexports.LocaleService = LocaleService;\nexports.LuminanceAlphaFormat = LuminanceAlphaFormat;\nexports.LuminanceFormat = LuminanceFormat;\nexports.Map = Map$1;\nexports.Marker = Marker;\nexports.MarqueePicker = MarqueePicker;\nexports.MarqueePickerMouseControl = MarqueePickerMouseControl;\nexports.Mesh = Mesh;\nexports.MeshSurfaceArea = MeshSurfaceArea;\nexports.MeshVolume = MeshVolume;\nexports.MetallicMaterial = MetallicMaterial;\nexports.MirroredRepeatWrapping = MirroredRepeatWrapping;\nexports.ModelMemento = ModelMemento;\nexports.NavCubePlugin = NavCubePlugin;\nexports.NearestFilter = NearestFilter;\nexports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\nexports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\nexports.NearestMipmapLinearFilter = NearestMipmapLinearFilter;\nexports.NearestMipmapNearestFilter = NearestMipmapNearestFilter;\nexports.Node = Node$1;\nexports.OBJLoaderPlugin = OBJLoaderPlugin;\nexports.ObjectsKdTree3 = ObjectsKdTree3;\nexports.ObjectsMemento = ObjectsMemento;\nexports.PNGMediaType = PNGMediaType;\nexports.Path = Path;\nexports.PerformanceModel = PerformanceModel;\nexports.PhongMaterial = PhongMaterial;\nexports.PickResult = PickResult;\nexports.Plugin = Plugin;\nexports.PointLight = PointLight;\nexports.PointerCircle = PointerCircle;\nexports.PointerLens = PointerLens;\nexports.QuadraticBezierCurve = QuadraticBezierCurve;\nexports.Queue = Queue;\nexports.RGBAFormat = RGBAFormat;\nexports.RGBAIntegerFormat = RGBAIntegerFormat;\nexports.RGBA_ASTC_10x10_Format = RGBA_ASTC_10x10_Format;\nexports.RGBA_ASTC_10x5_Format = RGBA_ASTC_10x5_Format;\nexports.RGBA_ASTC_10x6_Format = RGBA_ASTC_10x6_Format;\nexports.RGBA_ASTC_10x8_Format = RGBA_ASTC_10x8_Format;\nexports.RGBA_ASTC_12x10_Format = RGBA_ASTC_12x10_Format;\nexports.RGBA_ASTC_12x12_Format = RGBA_ASTC_12x12_Format;\nexports.RGBA_ASTC_4x4_Format = RGBA_ASTC_4x4_Format;\nexports.RGBA_ASTC_5x4_Format = RGBA_ASTC_5x4_Format;\nexports.RGBA_ASTC_5x5_Format = RGBA_ASTC_5x5_Format;\nexports.RGBA_ASTC_6x5_Format = RGBA_ASTC_6x5_Format;\nexports.RGBA_ASTC_6x6_Format = RGBA_ASTC_6x6_Format;\nexports.RGBA_ASTC_8x5_Format = RGBA_ASTC_8x5_Format;\nexports.RGBA_ASTC_8x6_Format = RGBA_ASTC_8x6_Format;\nexports.RGBA_ASTC_8x8_Format = RGBA_ASTC_8x8_Format;\nexports.RGBA_BPTC_Format = RGBA_BPTC_Format;\nexports.RGBA_ETC2_EAC_Format = RGBA_ETC2_EAC_Format;\nexports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\nexports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\nexports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\nexports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\nexports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\nexports.RGBFormat = RGBFormat;\nexports.RGB_ETC1_Format = RGB_ETC1_Format;\nexports.RGB_ETC2_Format = RGB_ETC2_Format;\nexports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\nexports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\nexports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\nexports.RGFormat = RGFormat;\nexports.RGIntegerFormat = RGIntegerFormat;\nexports.ReadableGeometry = ReadableGeometry;\nexports.RedFormat = RedFormat;\nexports.RedIntegerFormat = RedIntegerFormat;\nexports.ReflectionMap = ReflectionMap;\nexports.RepeatWrapping = RepeatWrapping;\nexports.STLDefaultDataSource = STLDefaultDataSource;\nexports.STLLoaderPlugin = STLLoaderPlugin;\nexports.SceneModel = SceneModel;\nexports.SceneModelMesh = SceneModelMesh;\nexports.SceneModelTransform = SceneModelTransform;\nexports.SectionPlane = SectionPlane;\nexports.SectionPlanesPlugin = SectionPlanesPlugin;\nexports.ShortType = ShortType;\nexports.SpecularMaterial = SpecularMaterial;\nexports.SplineCurve = SplineCurve;\nexports.SpriteMarker = SpriteMarker;\nexports.StoreyViewsPlugin = StoreyViewsPlugin;\nexports.Texture = Texture;\nexports.TextureTranscoder = TextureTranscoder;\nexports.TransformControl = TransformControl;\nexports.TreeViewPlugin = TreeViewPlugin;\nexports.UnsignedByteType = UnsignedByteType;\nexports.UnsignedInt248Type = UnsignedInt248Type;\nexports.UnsignedIntType = UnsignedIntType;\nexports.UnsignedShort4444Type = UnsignedShort4444Type;\nexports.UnsignedShort5551Type = UnsignedShort5551Type;\nexports.UnsignedShortType = UnsignedShortType;\nexports.VBOGeometry = VBOGeometry;\nexports.ViewCullPlugin = ViewCullPlugin;\nexports.Viewer = Viewer;\nexports.WebIFCLoaderPlugin = WebIFCLoaderPlugin;\nexports.Wire3D = Wire3D;\nexports.WorkerPool = WorkerPool$1;\nexports.XKTDefaultDataSource = XKTDefaultDataSource;\nexports.XKTLoaderPlugin = XKTLoaderPlugin;\nexports.XML3DLoaderPlugin = XML3DLoaderPlugin;\nexports.ZoneEditControl = ZoneEditControl;\nexports.ZoneEditMouseControl = ZoneEditMouseControl;\nexports.ZoneEditTouchControl = ZoneEditTouchControl;\nexports.ZoneTranslateControl = ZoneTranslateControl;\nexports.ZoneTranslateMouseControl = ZoneTranslateMouseControl;\nexports.ZoneTranslateTouchControl = ZoneTranslateTouchControl;\nexports.ZonesMouseControl = ZonesMouseControl;\nexports.ZonesPlugin = ZonesPlugin;\nexports.ZonesPolysurfaceMouseControl = ZonesPolysurfaceMouseControl;\nexports.ZonesPolysurfaceTouchControl = ZonesPolysurfaceTouchControl;\nexports.ZonesTouchControl = ZonesTouchControl;\nexports.activateDraggableDot = activateDraggableDot;\nexports.activateDraggableDots = activateDraggableDots;\nexports.addMousePressListener = addMousePressListener;\nexports.addTouchPressListener = addTouchPressListener;\nexports.buildBoxGeometry = buildBoxGeometry;\nexports.buildBoxLinesGeometry = buildBoxLinesGeometry;\nexports.buildBoxLinesGeometryFromAABB = buildBoxLinesGeometryFromAABB;\nexports.buildCylinderGeometry = buildCylinderGeometry;\nexports.buildGridGeometry = buildGridGeometry;\nexports.buildLineGeometry = buildLineGeometry;\nexports.buildPlaneGeometry = buildPlaneGeometry;\nexports.buildPolylineGeometry = buildPolylineGeometry;\nexports.buildPolylineGeometryFromCurve = buildPolylineGeometryFromCurve;\nexports.buildSphereGeometry = buildSphereGeometry;\nexports.buildTorusGeometry = buildTorusGeometry;\nexports.buildVectorTextGeometry = buildVectorTextGeometry;\nexports.createCombinedTexture = createCombinedTexture;\nexports.createRTCViewMat = createRTCViewMat;\nexports.createSkyboxMesh = createSkyboxMesh;\nexports.createSphereMapMesh = createSphereMapMesh;\nexports.frustumIntersectsAABB3 = frustumIntersectsAABB3;\nexports.getKTX2TextureTranscoder = getKTX2TextureTranscoder;\nexports.isTriangleMeshSolid = isTriangleMeshSolid;\nexports.load3DSGeometry = load3DSGeometry;\nexports.loadOBJGeometry = loadOBJGeometry;\nexports.marker3D = marker3D;\nexports.math = math;\nexports.meshSurfaceArea = meshSurfaceArea;\nexports.meshVolume = meshVolume;\nexports.os = os;\nexports.sRGBEncoding = sRGBEncoding;\nexports.setFrustum = setFrustum;\nexports.startPolygonCreate = startPolygonCreate;\nexports.stats = stats;\nexports.touchPointSelector = touchPointSelector;\nexports.transformToNode = transformToNode;\nexports.triangulateEarClipping = triangulateEarClipping;\nexports.utils = utils;\nexports.wire3D = wire3D;\nexports.worldToRTCPos = worldToRTCPos;\nexports.worldToRTCPositions = worldToRTCPositions;\n"]}